2012-12-03 1 views
2

StackOverflowers Chers collègues,Microchip TCP/IP pile PIC18F paquets invalides numéros suivants/ack

Im travaillant sur un projet pour mettre en œuvre quelque chose sur la carte PIC18F87J60 sur mon habitude (et testé) en utilisant la pile TCP/IP de Microchip . Comme test, j'ai écrit du code pour configurer une connexion, la maintenir pendant x secondes et la fermer ensuite avec élégance. Je l'ai implémenté comme une machine d'état finie. Je n'ai pas encore ajouté d'envoi et de réception de données.

Cependant, mon programme ne parvient pas à établir une connexion. En utilisant Wireshark, j'ai remarqué que mon appareil recevait avec succès une adresse IP via DHCP et que la résolution ARP était correctement effectuée. J'ai laissé DNS pour le moment car cela ne va pas, mais je vais résoudre cela plus tard. J'ai également vu que le premier paquet SYN est envoyé par mon appareil et que le serveur me répond comme il se doit, mais le troisième pas dans la prise de contact à trois voies se passe mal. Le numéro d'accusé de réception est juste un nombre aléatoire, donc le serveur devient confus et réinitialise la connexion avec un paquet RST. Ensuite, mon appareil confirme la réinitialisation avec un paquet ACK avec un autre numéro de séquence aléatoire et le serveur accepte en quelque sorte ce paquet. Ensuite, le serveur essaie de reconfigurer la connexion avec un paquet SYN mais mon code n'écoute pas les connexions entrantes, donc c'est la fin de la connexion.

Voici mon code:

#define THIS_IS_STACK_APPLICATION 
#include "TCPIP.h" 

APP_CONFIG AppConfig; 

ROM char serverAddress[] = "data.zienu.eu"; //unused in this codefile: DNS doesn't work yet 
ROM char serverIP[] = "80.69.92.56"; 
short authenticationPort = 5588; 

typedef enum _SOCKET_STATE { 
    SOCKET_DONE = 0, 
    SETUP_CONNECTION, 
    CONNECTING, 
    CONNECTED, 
    AWAITING_ANSWER, 
    SENDING_DATA, 
    CLOSE_CONNECTION, 
    DISCONNECTING, 
    DISCONNECTED 
} SOCKET_STATE; 

typedef struct _CONNECTION { 
    TCP_SOCKET socketID; 
    SOCKET_INFO* remoteInfo; 
    const char* remoteHostName; 
    WORD remotePort; 
    SOCKET_STATE state, previousState; 
    DWORD timeOut; 
    BYTE purpose; 
} CONNECTION; 

void InitHardware(); 
void AuthenticateTask(); 
void FTPDownloadTask(); 
void HandleTCPConnection(CONNECTION* connection); 

ROM BYTE SerializedMACAddress[6] = {MY_DEFAULT_MAC_BYTE1, MY_DEFAULT_MAC_BYTE2, MY_DEFAULT_MAC_BYTE3, MY_DEFAULT_MAC_BYTE4, MY_DEFAULT_MAC_BYTE5, MY_DEFAULT_MAC_BYTE6}; 
void InitAppConfig(void) { 
    AppConfig.Flags.bIsDHCPEnabled = TRUE; 
    AppConfig.Flags.bInConfigMode = TRUE; 
    memcpypgm2ram((void*)&AppConfig.MyMACAddr, (ROM void*)SerializedMACAddress, sizeof(AppConfig.MyMACAddr)); 
    AppConfig.MyIPAddr.Val = MY_DEFAULT_IP_ADDR_BYTE1 | MY_DEFAULT_IP_ADDR_BYTE2<<8ul | MY_DEFAULT_IP_ADDR_BYTE3<<16ul | MY_DEFAULT_IP_ADDR_BYTE4<<24ul; 
    AppConfig.DefaultIPAddr.Val = AppConfig.MyIPAddr.Val; 
    AppConfig.MyMask.Val = MY_DEFAULT_MASK_BYTE1 | MY_DEFAULT_MASK_BYTE2<<8ul | MY_DEFAULT_MASK_BYTE3<<16ul | MY_DEFAULT_MASK_BYTE4<<24ul; 
    AppConfig.DefaultMask.Val = AppConfig.MyMask.Val; 
    AppConfig.MyGateway.Val = MY_DEFAULT_GATE_BYTE1 | MY_DEFAULT_GATE_BYTE2<<8ul | MY_DEFAULT_GATE_BYTE3<<16ul | MY_DEFAULT_GATE_BYTE4<<24ul; 
    AppConfig.PrimaryDNSServer.Val = MY_DEFAULT_PRIMARY_DNS_BYTE1 | MY_DEFAULT_PRIMARY_DNS_BYTE2<<8ul | MY_DEFAULT_PRIMARY_DNS_BYTE3<<16ul | MY_DEFAULT_PRIMARY_DNS_BYTE4<<24ul; 
    AppConfig.SecondaryDNSServer.Val = MY_DEFAULT_SECONDARY_DNS_BYTE1 | MY_DEFAULT_SECONDARY_DNS_BYTE2<<8ul | MY_DEFAULT_SECONDARY_DNS_BYTE3<<16ul | MY_DEFAULT_SECONDARY_DNS_BYTE4<<24ul; 

    // Load the default NetBIOS Host Name 
    memcpypgm2ram(AppConfig.NetBIOSName, (ROM void*)MY_DEFAULT_HOST_NAME, 10); 
    FormatNetBIOSName(AppConfig.NetBIOSName); 
} 

void InitHardware() { 
    /** \var isBoot (LATH0_bit) tells the boot-interrupt handler that boot is busy */ 
    LATHbits.LATH0 = 1; 

    ADCON1 |= 0x0f;   // adc pins as I/0 
    CMCON |= 7;   // Disable comperator 

    OSCCON = 0x04; 
    OSCTUNE = 0x40; //41 MHz 

    /******************************************************************/ 
    // init======== 
// Het TRISA en TRISF register moeten goed zijn ingesteld voor de analoge input: 
    PORTA = 0x00; 
    TRISA = 0x20; /* Bit 1 and 2 are used by ethernet LEDS */ 
    PORTB = 0x00; 
    TRISB = 0x00; /* output mode */ 
    PORTC = 0x03; /* LED R en G off */ 
    TRISC = 0xc0; /* Bit 6 and 7 are used by UART 1 */ 
    PORTD = 0x00; /* used to display ethernetsecond_timer in DEBUG mode*/ 
    TRISD = 0x00; /* output mode */ 
    PORTE = 0x00; 
    TRISE = 0x00; /* output mode */ 
    PORTF = 0x00; 
    TRISF = 0x0E; /* output mode */ 
    PORTG = 0x00; 
    TRISG = 0x00; 
    PORTH = 0x00; 
    TRISH = 0x00; 

    /* interrupt priorities are possible with microC */ 
    IPR1bits.ADIP = 0;  //give ADC LOW interrupt priority 
    RCONbits.IPEN = 1;  //Enable interrupt priorities 
    INTCON2bits.RBPU = 1; // Disable internal PORTB pull-ups 

    INTCONbits.GIEH = 1; 
    INTCONbits.GIEL = 1; 
} 

void interrupt low_priority LowISR(void) { 
    TickUpdate(); 
} 

void interrupt HighISR(void) { 
} 

void HandleTCPConnection(CONNECTION* connection) { 
    switch(connection->state) { 
     case SETUP_CONNECTION: 
      if(!AppConfig.Flags.bInConfigMode) { 
       connection->socketID = TCPOpen((DWORD) (PTR_BASE)&serverIP[0], TCP_OPEN_ROM_HOST, connection->remotePort, connection->purpose); 

       connection->timeOut = TickGet() + TICK_SECOND * 15; 
       connection->previousState = SETUP_CONNECTION; 
       connection->state = CONNECTING; 
       TCPWasReset(connection->socketID); 
      } 
      break; 
     case CONNECTING: 
      if(TCPIsConnected(connection->socketID)) { 
       connection->previousState = CONNECTING; 
       connection->state = CONNECTED; 
       connection->remoteInfo = TCPGetRemoteInfo(connection->socketID); 
       connection->timeOut = TickGet() + TICK_SECOND * 10; 
      } 
      else if(TickGet() >= connection->timeOut) { 
       connection->previousState = CONNECTING; 
       connection->state = CLOSE_CONNECTION; 
      } 
      break; 
     case CONNECTED: 
      if(TickGet() >= connection->timeOut) { 
       connection->previousState = CONNECTED; 
       connection->state = CLOSE_CONNECTION; 
      } 
      else if(TCPWasReset(connection->socketID)) { 
       connection->previousState = CONNECTED; 
       connection->state = CLOSE_CONNECTION; 
      } 
      break; 
     case CLOSE_CONNECTION: 
       connection->previousState = CLOSE_CONNECTION; 
       connection->state = DISCONNECTING; 
       TCPDisconnect(connection->socketID);  //Send a TCP FIN packet 
       connection->timeOut = TickGet() + TICK_SECOND * 5; 
      break; 
     case DISCONNECTING: 
      if(TCPIsConnected(connection->socketID)) { 
       connection->previousState = DISCONNECTING; 
       connection->state = DISCONNECTED; 
      } 
      else if(TickGet() >= connection->timeOut) { 
       TCPDisconnect(connection->socketID); 
       TCPDisconnect(connection->socketID); //Time out: Send a RST packet and proceed 
       connection->previousState = DISCONNECTING; 
       connection->state = DISCONNECTED; 
      } 
      break; 
     case DISCONNECTED: 
      connection->previousState = DISCONNECTED; 
      connection->state = SOCKET_DONE; 
      break; 
     case SOCKET_DONE: 
      break; 
     default: 
      break; 
    } 
} 

void main() { 
    InitHardware(); 
    TickInit(); 
    InitAppConfig(); 
    StackInit(); 

    CONNECTION connection; 
    connection.purpose = TCP_PURPOSE_CUSTOM_FTP_CMD; 
    connection.remoteHostName = serverIP; 
    connection.remotePort = authenticationPort; 
    connection.previousState = SOCKET_DONE; 
    connection.state = SETUP_CONNECTION; 
    while(TRUE) { 
     HandleTCPConnection(&connection); 
     StackTask(); 
     StackApplications(); 
    } 
} 

Voici une capture d'écran de la Wireshark logs.

Merci à l'avance, BitJunky

Edit: Voici le wireshark dumpfile. J'ai filtré sur l'adresse MAC donc une partie du processus DHCP n'est pas affichée dans cette image.

+0

Pouvez-vous poster la trace avec nunmbers complète SEQ/ACK? Peut-être comme un tcpdump? – cxxl

+0

@cxxl voir ma modification dans le message d'origine – Jupiter

Répondre

1

J'ai résolu le problème. Je pensais que la pile TCPIP était compatible avec le compilateur hi-tech mais cela ne semble pas être le cas. Les compilateurs C18 et XC8 fonctionnent parfaitement avec le code que j'ai posté.

Greetz BitJunky