2010-08-02 11 views
0

Je reçois un comportement très étrange dans ma bibliothèque Objective C (pour iPhone). Ce que j'essaie de faire est de prendre les paquets qui arrivent (hors du port accessoire), de les ajouter dans une variable d'instance NSMutableData, puis de vérifier cela pour voir si j'ai des paquets complets. Si c'est le cas, la méthode [containsPacket] retournera la longueur du paquet, sinon elle retournera -1. S'il contient un paquet, je crée un nouvel objet RASPPacket avec ces données, et je mets à jour mon objet receivedData avec le reste des données (en soustrayant les données avec lesquelles je viens de créer le RASPPacket). Je boucle à travers cela jusqu'à la longueur < 0 (ce qui signifie qu'il n'y a plus de paquets complets dans receivedData). Lorsque je lui donne un paquet complet, il fonctionne comme il se doit (containsPacket renvoie la bonne longueur et receivedData devient un NSMutableData vide). La chose étrange est que la seconde fois que j'appelle containsPacket, elle renvoie toujours le même nombre (13), même si receivedData est vide. J'ai mis quelques NSLogs dedans pour voir ce qui se passait (puisque je suis déconnecté de l'ordinateur que je ne peux pas passer en utilisant le débogueur), dont la sortie est ci-dessous.Objective C se comporter étrangement (en utilisant des anciennes références)

- (void)receive:(NSData *)packet { 

    [receivedData appendData:packet]; 

    NSMutableString *dataString = [[NSMutableString alloc] init]; 
    unsigned char *ptr = (unsigned char *)[receivedData bytes]; 

    for(int i = 0; i < [receivedData length]; i++) { 

     [dataString appendFormat:@"%02X ", ptr[i]]; 
    } 

    NSLog(@"Received data: %@", dataString); 

    int length = [RASPPacket containsPacket:receivedData]; 
    NSLog(@"length is %i", length); 

    while(length > 0) { 

     RASPPacket *receivedPacket = [[RASPPacket alloc] initWithIncomingPacket:[NSData dataWithBytes:[receivedData bytes] length:length]]; 

     [receivedData setData:[NSMutableData dataWithBytes:([receivedData bytes]+length) length:([receivedData length] - length)]]; 

     dataString = [[NSMutableString alloc] init]; 
     ptr = (unsigned char *)[receivedData bytes]; 

     for(int i = 0; i < [receivedData length]; i++) { 

      [dataString appendFormat:@"%02X ", ptr[i]]; 
     } 

     NSLog(@"new received data: %@", dataString); 

     if([receivedPacket isValidPacket]) { 

      [raspObject receive:receivedPacket]; 
      NSLog(@"Complete packet is valid"); 
     } 

     [receivedPacket release]; 

     length = [RASPPacket containsPacket:receivedData]; 
     NSLog(@"length is %i", length); 
    } 
} 

Et la méthode containsPacket:

+ (int)containsPacket:(NSData *)thePacket { 

    //Return -1 by default (if it doesn't contain a complete packet) 
    int returnValue = -1; 

    unsigned char *data = (unsigned char *)[thePacket bytes]; 

    NSMutableString *dataString = [[NSMutableString alloc] init]; 
    unsigned char *ptr = (unsigned char *)[thePacket bytes]; 

    for(int i = 0; i < [thePacket length]; i++) { 

     [dataString appendFormat:@"%02X ", ptr[i]]; 
    } 

    NSLog(@"containsPacket data: %@, len %i", dataString, [thePacket length]); 

    NSLog(@"beginning return value %i", returnValue); 

    //DLE counts the number of consecutive DLE bytes (0x10). An odd number means 
    //we found the DLE we want, an even means it's just in a sequence in the message data 
    int dleCount = 0; 
    NSLog(@"a return value %i", returnValue); 

    //Start i at 2 to skip 0x10 0x01 
    for(int i = 2; (i < ([thePacket length] - 1)) && returnValue < 0; i++) { 

     NSLog(@"b return value %i, i: %i, len: %i", returnValue, i, [thePacket length] - 1); 
     //Check if we found 0x10 and 0x03 and there are at least three bytes extra (0x03 and checksum) 
     if(data[i] == 0x10 && data[i+1] == 0x03 && [thePacket length] - 3 > i) { 

      int j = i - 1; 
      dleCount = 1; 

      while(data[j] == 0x10 && j >= 0) { 
       dleCount++; 
       j--; 
      } 

      if(dleCount % 2) { 

       //Add 1 to convert to indices to length, 1 to go from 0x10 to 0x03, and 2 for checksum 
       returnValue = i + 2 + 1 + 1; 
       NSLog(@"c return value %i", returnValue); 
      } 
     } 
    } 

    NSLog(@"ending return value %i", returnValue); 
    return returnValue; 
} 

Et enfin, la sortie NSLog:

TestRaspLayer[922:6c03] Received data: 10 01 00 01 01 10 02 00 00 10 03 A1 07 

TestRaspLayer[922:6c03] containsPacket data: 10 01 00 01 01 10 02 00 00 10 03 A1 07 , len 13 

TestRaspLayer[922:6c03] beginning return value -1 

TestRaspLayer[922:6c03] a return value -1 

TestRaspLayer[922:6c03] b return value -1, i: 2, len: 12 

TestRaspLayer[922:6c03] b return value -1, i: 3, len: 12 

TestRaspLayer[922:6c03] b return value -1, i: 4, len: 12 

TestRaspLayer[922:6c03] b return value -1, i: 5, len: 12 

TestRaspLayer[922:6c03] b return value -1, i: 6, len: 12 

TestRaspLayer[922:6c03] b return value -1, i: 7, len: 12 

TestRaspLayer[922:6c03] b return value -1, i: 8, len: 12 

TestRaspLayer[922:6c03] b return value -1, i: 9, len: 12 

TestRaspLayer[922:6c03] c return value 13 

TestRaspLayer[922:6c03] ending return value 13 

TestRaspLayer[922:6c03] length is 13 

TestRaspLayer[922:6c03] new received data: 

TestRaspLayer[922:6c03] RASP receive, interface: 1, command 1, looking for interface: 9, command 1 

TestRaspLayer[922:6c03] Complete packet is valid 

TestRaspLayer[922:6c03] containsPacket data: , len 0 

TestRaspLayer[922:6c03] beginning return value -1 

TestRaspLayer[922:6c03] a return value -1 

TestRaspLayer[922:6c03] b return value -1, i: 2, len: -1 

TestRaspLayer[922:6c03] b return value -1, i: 3, len: -1 

TestRaspLayer[922:6c03] b return value -1, i: 4, len: -1 

TestRaspLayer[922:6c03] b return value -1, i: 5, len: -1 

TestRaspLayer[922:6c03] b return value -1, i: 6, len: -1 

TestRaspLayer[922:6c03] b return value -1, i: 7, len: -1 

TestRaspLayer[922:6c03] b return value -1, i: 8, len: -1 

TestRaspLayer[922:6c03] b return value -1, i: 9, len: -1 

TestRaspLayer[922:6c03] c return value 13 

TestRaspLayer[922:6c03] ending return value 13 

TestRaspLayer[922:6c03] length is 13 

La première fois qu'il traverse les données valides, la deuxième fois, il n » est pas t, et ne devrait pas continuer à travers la boucle for (puisque i> [la longueur du paquet] -1).

Répondre

0
for(int i=2; (i<([thePacket length]-1)) && returnValue<0; i++) 

[thePacket length]-1 aura un très grand (pour le paquet vide) depuis la longueur est unsigned int.