X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/234d0a39eb3e261a1ddfcea31d7104e3400b2491..31d8ebebc0796873f7c70db80a04acdcbb307ed8:/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c diff --git a/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c b/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c index 44a32ea51..2a626e975 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c +++ b/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c @@ -56,27 +56,29 @@ TCP_ConnectionState_t ConnectionStateTable[MAX_TCP_CONNECTIONS]; * level. If an application produces a response, this task constructs the appropriate Ethernet frame and places it into the Ethernet OUT * buffer for later transmission. */ -void TCP_TCPTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo) +void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* RNDISInterfaceInfo) { - /* Task to hand off TCP packets to and from the listening applications. */ - /* Run each application in sequence, to process incoming and generate outgoing packets */ for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++) { /* Find the corresponding port entry in the port table */ - for (uint8_t PTableEntry = 0; PTableEntry < MAX_TCP_CONNECTIONS; PTableEntry++) + for (uint8_t PTableEntry = 0; PTableEntry < MAX_OPEN_TCP_PORTS; PTableEntry++) { /* Run the application handler for the port */ if ((PortStateTable[PTableEntry].Port == ConnectionStateTable[CSTableEntry].Port) && (PortStateTable[PTableEntry].State == TCP_Port_Open)) { - PortStateTable[PTableEntry].ApplicationHandler(&ConnectionStateTable[CSTableEntry], &ConnectionStateTable[CSTableEntry].Info.Buffer); + PortStateTable[PTableEntry].ApplicationHandler(&ConnectionStateTable[CSTableEntry], + &ConnectionStateTable[CSTableEntry].Info.Buffer); } } } + /* Get pointer to the output frame info struct for convenience */ + Ethernet_Frame_Info_t* FrameOUT = (Ethernet_Frame_Info_t*)&RNDISInterfaceInfo->State.FrameOUT; + /* Bail out early if there is already a frame waiting to be sent in the Ethernet OUT buffer */ - if (RNDISInterfaceInfo->FrameOUT.FrameInBuffer) + if (FrameOUT->FrameInBuffer) return; /* Send response packets from each application as the TCP packet buffers are filled by the applications */ @@ -86,13 +88,13 @@ void TCP_TCPTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo) if ((ConnectionStateTable[CSTableEntry].Info.Buffer.Direction == TCP_PACKETDIR_OUT) && (ConnectionStateTable[CSTableEntry].Info.Buffer.Ready)) { - Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData; - IP_Header_t* IPHeaderOUT = (IP_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]; - TCP_Header_t* TCPHeaderOUT = (TCP_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) + - sizeof(IP_Header_t)]; - void* TCPDataOUT = &RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) + - sizeof(IP_Header_t) + - sizeof(TCP_Header_t)]; + Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT->FrameData; + IP_Header_t* IPHeaderOUT = (IP_Header_t*)&FrameOUT->FrameData[sizeof(Ethernet_Frame_Header_t)]; + TCP_Header_t* TCPHeaderOUT = (TCP_Header_t*)&FrameOUT->FrameData[sizeof(Ethernet_Frame_Header_t) + + sizeof(IP_Header_t)]; + void* TCPDataOUT = &FrameOUT->FrameData[sizeof(Ethernet_Frame_Header_t) + + sizeof(IP_Header_t) + + sizeof(TCP_Header_t)]; uint16_t PacketSize = ConnectionStateTable[CSTableEntry].Info.Buffer.Length; @@ -145,8 +147,8 @@ void TCP_TCPTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo) PacketSize += sizeof(Ethernet_Frame_Header_t); /* Set the response length in the buffer and indicate that a response is ready to be sent */ - RNDISInterfaceInfo->FrameOUT.FrameLength = PacketSize; - RNDISInterfaceInfo->FrameOUT.FrameInBuffer = true; + FrameOUT->FrameLength = PacketSize; + FrameOUT->FrameInBuffer = true; ConnectionStateTable[CSTableEntry].Info.Buffer.Ready = false; @@ -171,9 +173,9 @@ void TCP_Init(void) /** Sets the state and callback handler of the given port, specified in big endian to the given state. * - * \param Port Port whose state and callback function to set, specified in big endian - * \param State New state of the port, a value from the TCP_PortStates_t enum - * \param Handler Application callback handler for the port + * \param[in] Port Port whose state and callback function to set, specified in big endian + * \param[in] State New state of the port, a value from the TCP_PortStates_t enum + * \param[in] Handler Application callback handler for the port * * \return Boolean true if the port state was set, false otherwise (no more space in the port state table) */ @@ -220,7 +222,7 @@ bool TCP_SetPortState(uint16_t Port, uint8_t State, void (*Handler)(TCP_Connecti /** Retrieves the current state of a given TCP port, specified in big endian. * - * \param Port TCP port whose state is to be retrieved, given in big-endian + * \param[in] Port TCP port whose state is to be retrieved, given in big-endian * * \return A value from the TCP_PortStates_t enum */ @@ -242,10 +244,10 @@ uint8_t TCP_GetPortState(uint16_t Port) /** Sets the connection state of the given port, remote address and remote port to the given TCP connection state. If the * connection exists in the connection state table it is updated, otherwise it is created if possible. * - * \param Port TCP port of the connection on the device, specified in big endian - * \param RemoteAddress Remote protocol IP address of the connected device - * \param RemotePort TCP port of the remote device in the connection, specified in big endian - * \param State TCP connection state, a value from the TCP_ConnectionStates_t enum + * \param[in] Port TCP port of the connection on the device, specified in big endian + * \param[in] RemoteAddress Remote protocol IP address of the connected device + * \param[in] RemotePort TCP port of the remote device in the connection, specified in big endian + * \param[in] State TCP connection state, a value from the TCP_ConnectionStates_t enum * * \return Boolean true if the connection was updated or created, false otherwise (no more space in the connection state table) */ @@ -283,9 +285,9 @@ bool TCP_SetConnectionState(uint16_t Port, IP_Address_t RemoteAddress, uint16_t /** Retrieves the current state of a given TCP connection to a host. * - * \param Port TCP port on the device in the connection, specified in big endian - * \param RemoteAddress Remote protocol IP address of the connected host - * \param RemotePort Remote TCP port of the connected host, specified in big endian + * \param[in] Port TCP port on the device in the connection, specified in big endian + * \param[in] RemoteAddress Remote protocol IP address of the connected host + * \param[in] RemotePort Remote TCP port of the connected host, specified in big endian * * \return A value from the TCP_ConnectionStates_t enum */ @@ -310,9 +312,9 @@ uint8_t TCP_GetConnectionState(uint16_t Port, IP_Address_t RemoteAddress, uint16 /** Retrieves the connection info structure of a given connection to a host. * - * \param Port TCP port on the device in the connection, specified in big endian - * \param RemoteAddress Remote protocol IP address of the connected host - * \param RemotePort Remote TCP port of the connected host, specified in big endian + * \param[in] Port TCP port on the device in the connection, specified in big endian + * \param[in] RemoteAddress Remote protocol IP address of the connected host + * \param[in] RemotePort Remote TCP port of the connected host, specified in big endian * * \return ConnectionInfo structure of the connection if found, NULL otherwise */ @@ -337,9 +339,9 @@ TCP_ConnectionInfo_t* TCP_GetConnectionInfo(uint16_t Port, IP_Address_t RemoteAd /** Processes a TCP packet inside an Ethernet frame, and writes the appropriate response * to the output Ethernet frame if one is created by a application handler. * - * \param IPHeaderInStart Pointer to the start of the incoming packet's IP header - * \param TCPHeaderInStart Pointer to the start of the incoming packet's TCP header - * \param TCPHeaderOutStart Pointer to the start of the outgoing packet's TCP header + * \param[in] IPHeaderInStart Pointer to the start of the incoming packet's IP header + * \param[in] TCPHeaderInStart Pointer to the start of the incoming packet's TCP header + * \param[out] TCPHeaderOutStart Pointer to the start of the outgoing packet's TCP header * * \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE if no * response was generated, NO_PROCESS if the packet processing was deferred until the @@ -367,11 +369,12 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, void* TCPHeaderInStart, void /* Detect RST from host to abort existing connection */ if (TCPHeaderIN->Flags & TCP_FLAG_RST) { - TCPHeaderOUT->Flags = (TCP_FLAG_RST | TCP_FLAG_ACK); - PacketResponse = true; - - TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, - TCPHeaderIN->SourcePort, TCP_Connection_Closed); + if (TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + TCPHeaderIN->SourcePort, TCP_Connection_Closed)) + { + TCPHeaderOUT->Flags = (TCP_FLAG_RST | TCP_FLAG_ACK); + PacketResponse = true; + } } else { @@ -381,19 +384,24 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, void* TCPHeaderInStart, void case TCP_Connection_Listen: if (TCPHeaderIN->Flags == TCP_FLAG_SYN) { - /* SYN connection when closed starts a connection with a peer */ + /* SYN connection starts a connection with a peer */ + if (TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + TCPHeaderIN->SourcePort, TCP_Connection_SYNReceived)) + { + TCPHeaderOUT->Flags = (TCP_FLAG_SYN | TCP_FLAG_ACK); - TCPHeaderOUT->Flags = (TCP_FLAG_SYN | TCP_FLAG_ACK); - PacketResponse = true; - - TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort, - TCP_Connection_SYNReceived); - - ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort); + ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort); - ConnectionInfo->SequenceNumberIn = (SwapEndian_32(TCPHeaderIN->SequenceNumber) + 1); - ConnectionInfo->SequenceNumberOut = 0; - ConnectionInfo->Buffer.InUse = false; + ConnectionInfo->SequenceNumberIn = (SwapEndian_32(TCPHeaderIN->SequenceNumber) + 1); + ConnectionInfo->SequenceNumberOut = 0; + ConnectionInfo->Buffer.InUse = false; + } + else + { + TCPHeaderOUT->Flags = TCP_FLAG_RST; + } + + PacketResponse = true; } break; @@ -579,10 +587,10 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, void* TCPHeaderInStart, void /** Calculates the appropriate TCP checksum, consisting of the addition of the one's compliment of each word, * complimented. * - * \param TCPHeaderOutStart Pointer to the start of the packet's outgoing TCP header - * \param SourceAddress Source protocol IP address of the outgoing IP header - * \param DestinationAddress Destination protocol IP address of the outgoing IP header - * \param TCPOutSize Size in bytes of the TCP data header and payload + * \param[in] TCPHeaderOutStart Pointer to the start of the packet's outgoing TCP header + * \param[in] SourceAddress Source protocol IP address of the outgoing IP header + * \param[in] DestinationAddress Destination protocol IP address of the outgoing IP header + * \param[in] TCPOutSize Size in bytes of the TCP data header and payload * * \return A 16-bit TCP checksum value */