Device mode class driver callbacks are now fired before the control request status...
[pub/USBasp.git] / Demos / Device / ClassDriver / RNDISEthernet / Lib / TCP.c
index 6746433..6500f3b 100644 (file)
@@ -1,21 +1,21 @@
 /*\r
              LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
+     Copyright (C) Dean Camera, 2010.\r
               \r
   dean [at] fourwalledcubicle [dot] com\r
       www.fourwalledcubicle.com\r
 */\r
 \r
 /*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
+  Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, distribute, and sell this \r
+  software and its documentation for any purpose is hereby granted\r
+  without fee, provided that the above copyright notice appear in \r
+  all copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting \r
+  documentation, and that the name of the author not be used in \r
+  advertising or publicity pertaining to distribution of the \r
   software without specific, written prior permission.\r
 \r
   The author disclaim all warranties with regard to this\r
@@ -38,7 +38,6 @@
 #define  INCLUDE_FROM_TCP_C\r
 #include "TCP.h"\r
 \r
-/* Global Variables: */\r
 /** Port state table array. This contains the current status of TCP ports in the device. To save on space, only open ports are\r
  *  stored - closed ports may be overwritten at any time, and the system will assume any ports not present in the array are closed. This\r
  *  allows for MAX_OPEN_TCP_PORTS to be less than the number of ports used by the application if desired.\r
@@ -58,25 +57,27 @@ TCP_ConnectionState_t  ConnectionStateTable[MAX_TCP_CONNECTIONS];
  */\r
 void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo)\r
 {\r
-       /* Task to hand off TCP packets to and from the listening applications. */\r
-\r
        /* Run each application in sequence, to process incoming and generate outgoing packets */\r
        for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++)\r
        {\r
                /* Find the corresponding port entry in the port table */\r
-               for (uint8_t PTableEntry = 0; PTableEntry < MAX_TCP_CONNECTIONS; PTableEntry++)\r
+               for (uint8_t PTableEntry = 0; PTableEntry < MAX_OPEN_TCP_PORTS; PTableEntry++)\r
                {\r
                        /* Run the application handler for the port */\r
                        if ((PortStateTable[PTableEntry].Port  == ConnectionStateTable[CSTableEntry].Port) && \r
                            (PortStateTable[PTableEntry].State == TCP_Port_Open))\r
                        {\r
-                               PortStateTable[PTableEntry].ApplicationHandler(&ConnectionStateTable[CSTableEntry], &ConnectionStateTable[CSTableEntry].Info.Buffer);\r
+                               PortStateTable[PTableEntry].ApplicationHandler(&ConnectionStateTable[CSTableEntry],\r
+                                                                              &ConnectionStateTable[CSTableEntry].Info.Buffer);\r
                        }\r
                }\r
        }\r
        \r
+       /* Get pointer to the output frame info struct for convenience */\r
+       Ethernet_Frame_Info_t* FrameOUT = &RNDISInterfaceInfo->State.FrameOUT;\r
+       \r
        /* Bail out early if there is already a frame waiting to be sent in the Ethernet OUT buffer */\r
-       if (RNDISInterfaceInfo->State.FrameOUT.FrameInBuffer)\r
+       if (FrameOUT->FrameInBuffer)\r
          return;\r
        \r
        /* Send response packets from each application as the TCP packet buffers are filled by the applications */\r
@@ -86,13 +87,13 @@ void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo)
                if ((ConnectionStateTable[CSTableEntry].Info.Buffer.Direction == TCP_PACKETDIR_OUT) &&\r
                    (ConnectionStateTable[CSTableEntry].Info.Buffer.Ready))\r
                {\r
-                       Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&RNDISInterfaceInfo->State.FrameOUT.FrameData;\r
-                       IP_Header_t*    IPHeaderOUT  = (IP_Header_t*)&RNDISInterfaceInfo->State.FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)];\r
-                       TCP_Header_t*   TCPHeaderOUT = (TCP_Header_t*)&RNDISInterfaceInfo->State.FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +\r
-                                                                                                             sizeof(IP_Header_t)];                                             \r
-                       void*           TCPDataOUT     = &RNDISInterfaceInfo->State.FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +\r
-                                                                                                sizeof(IP_Header_t) +\r
-                                                                                                sizeof(TCP_Header_t)];\r
+                       Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT->FrameData;\r
+                       IP_Header_t*             IPHeaderOUT    = (IP_Header_t*)&FrameOUT->FrameData[sizeof(Ethernet_Frame_Header_t)];\r
+                       TCP_Header_t*            TCPHeaderOUT   = (TCP_Header_t*)&FrameOUT->FrameData[sizeof(Ethernet_Frame_Header_t) +\r
+                                                                                                     sizeof(IP_Header_t)];\r
+                       void*                    TCPDataOUT     = &FrameOUT->FrameData[sizeof(Ethernet_Frame_Header_t) +\r
+                                                                                      sizeof(IP_Header_t) +\r
+                                                                                      sizeof(TCP_Header_t)];\r
 \r
                        uint16_t PacketSize = ConnectionStateTable[CSTableEntry].Info.Buffer.Length;\r
 \r
@@ -145,8 +146,8 @@ void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo)
                        PacketSize += sizeof(Ethernet_Frame_Header_t);\r
 \r
                        /* Set the response length in the buffer and indicate that a response is ready to be sent */\r
-                       RNDISInterfaceInfo->State.FrameOUT.FrameLength   = PacketSize;\r
-                       RNDISInterfaceInfo->State.FrameOUT.FrameInBuffer = true;\r
+                       FrameOUT->FrameLength           = PacketSize;\r
+                       FrameOUT->FrameInBuffer         = true;\r
                        \r
                        ConnectionStateTable[CSTableEntry].Info.Buffer.Ready = false;\r
                        \r
@@ -367,11 +368,12 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, void* TCPHeaderInStart, void
                /* Detect RST from host to abort existing connection */\r
                if (TCPHeaderIN->Flags & TCP_FLAG_RST)\r
                {\r
-                       TCPHeaderOUT->Flags = (TCP_FLAG_RST | TCP_FLAG_ACK);                            \r
-                       PacketResponse = true;\r
-                       \r
-                       TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
-                                              TCPHeaderIN->SourcePort, TCP_Connection_Closed);                 \r
+                       if (TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                                  TCPHeaderIN->SourcePort, TCP_Connection_Closed))\r
+                       {\r
+                               TCPHeaderOUT->Flags = (TCP_FLAG_RST | TCP_FLAG_ACK);                            \r
+                               PacketResponse = true;                  \r
+                       }\r
                }\r
                else\r
                {\r
@@ -381,19 +383,24 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, void* TCPHeaderInStart, void
                                case TCP_Connection_Listen:\r
                                        if (TCPHeaderIN->Flags == TCP_FLAG_SYN)\r
                                        {\r
-                                               /* SYN connection when closed starts a connection with a peer */\r
+                                               /* SYN connection starts a connection with a peer */\r
+                                               if (TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                                                          TCPHeaderIN->SourcePort, TCP_Connection_SYNReceived))\r
+                                               {\r
+                                                       TCPHeaderOUT->Flags = (TCP_FLAG_SYN | TCP_FLAG_ACK);                                            \r
 \r
-                                               TCPHeaderOUT->Flags = (TCP_FLAG_SYN | TCP_FLAG_ACK);                            \r
-                                               PacketResponse      = true;\r
-                                                                       \r
-                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort,\r
-                                                                                          TCP_Connection_SYNReceived);\r
-                                                                                          \r
-                                               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort);\r
+                                                       ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort);\r
 \r
-                                               ConnectionInfo->SequenceNumberIn  = (SwapEndian_32(TCPHeaderIN->SequenceNumber) + 1);\r
-                                               ConnectionInfo->SequenceNumberOut = 0;\r
-                                               ConnectionInfo->Buffer.InUse      = false;\r
+                                                       ConnectionInfo->SequenceNumberIn  = (SwapEndian_32(TCPHeaderIN->SequenceNumber) + 1);\r
+                                                       ConnectionInfo->SequenceNumberOut = 0;\r
+                                                       ConnectionInfo->Buffer.InUse      = false;\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       TCPHeaderOUT->Flags = TCP_FLAG_RST;\r
+                                               }\r
+                                                                                          \r
+                                               PacketResponse      = true;\r
                                        }\r
                                        \r
                                        break;\r