X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/cb779e3d7d32d7c43e0a45bb526de0a04135b0c7..6f90d45684206e5dfca3c4554a14a5784da49d92:/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 4f49bdd99..ad79736f1 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c +++ b/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c @@ -1,13 +1,13 @@ /* LUFA Library - Copyright (C) Dean Camera, 2010. + Copyright (C) Dean Camera, 2012. dean [at] fourwalledcubicle [dot] com www.lufa-lib.org */ /* - Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted @@ -55,7 +55,8 @@ 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_Device_t* const RNDISInterfaceInfo) +void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, + Ethernet_Frame_Info_t* const FrameOUT) { /* Run each application in sequence, to process incoming and generate outgoing packets */ for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++) @@ -73,11 +74,8 @@ void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) } } - /* Get pointer to the output frame info struct for convenience */ - Ethernet_Frame_Info_t* FrameOUT = &RNDISInterfaceInfo->State.FrameOUT; - /* Bail out early if there is already a frame waiting to be sent in the Ethernet OUT buffer */ - if (FrameOUT->FrameInBuffer) + if (FrameOUT->FrameLength) return; /* Send response packets from each application as the TCP packet buffers are filled by the applications */ @@ -114,8 +112,8 @@ void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ConnectionStateTable[CSTableEntry].Info.SequenceNumberOut += PacketSize; - TCPHeaderOUT->Checksum = TCP_Checksum16(TCPHeaderOUT, ServerIPAddress, - ConnectionStateTable[CSTableEntry].RemoteAddress, + TCPHeaderOUT->Checksum = TCP_Checksum16(TCPHeaderOUT, &ServerIPAddress, + &ConnectionStateTable[CSTableEntry].RemoteAddress, (sizeof(TCP_Header_t) + PacketSize)); PacketSize += sizeof(TCP_Header_t); @@ -147,7 +145,6 @@ void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) /* Set the response length in the buffer and indicate that a response is ready to be sent */ FrameOUT->FrameLength = PacketSize; - FrameOUT->FrameInBuffer = true; ConnectionStateTable[CSTableEntry].Info.Buffer.Ready = false; @@ -156,7 +153,7 @@ void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) } } -/** Initialises the TCP protocol handler, clearing the port and connection state tables. This must be called before TCP packets are +/** Initializes the TCP protocol handler, clearing the port and connection state tables. This must be called before TCP packets are * processed. */ void TCP_Init(void) @@ -173,7 +170,7 @@ void TCP_Init(void) /** Sets the state and callback handler of the given port, specified in big endian to the given state. * * \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] State New state of the port, a value from the \ref 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) @@ -185,7 +182,7 @@ bool TCP_SetPortState(const uint16_t Port, /* Note, Port number should be specified in BIG endian to simplify network code */ /* Check to see if the port entry is already in the port state table */ - for (uint8_t PTableEntry = 0; PTableEntry < MAX_TCP_CONNECTIONS; PTableEntry++) + for (uint8_t PTableEntry = 0; PTableEntry < MAX_OPEN_TCP_PORTS; PTableEntry++) { /* Find existing entry for the port in the table, update it if found */ if (PortStateTable[PTableEntry].Port == Port) @@ -199,7 +196,7 @@ bool TCP_SetPortState(const uint16_t Port, /* Check if trying to open the port -- if so we need to find an unused (closed) entry and replace it */ if (State == TCP_Port_Open) { - for (uint8_t PTableEntry = 0; PTableEntry < MAX_TCP_CONNECTIONS; PTableEntry++) + for (uint8_t PTableEntry = 0; PTableEntry < MAX_OPEN_TCP_PORTS; PTableEntry++) { /* Find a closed port entry in the table, change it to the given port and state */ if (PortStateTable[PTableEntry].State == TCP_Port_Closed) @@ -225,13 +222,13 @@ bool TCP_SetPortState(const uint16_t Port, * * \param[in] Port TCP port whose state is to be retrieved, given in big-endian * - * \return A value from the TCP_PortStates_t enum + * \return A value from the \ref TCP_PortStates_t enum */ uint8_t TCP_GetPortState(const uint16_t Port) { /* Note, Port number should be specified in BIG endian to simplify network code */ - for (uint8_t PTableEntry = 0; PTableEntry < MAX_TCP_CONNECTIONS; PTableEntry++) + for (uint8_t PTableEntry = 0; PTableEntry < MAX_OPEN_TCP_PORTS; PTableEntry++) { /* Find existing entry for the port in the table, return the port status if found */ if (PortStateTable[PTableEntry].Port == Port) @@ -248,12 +245,12 @@ uint8_t TCP_GetPortState(const uint16_t Port) * \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 + * \param[in] State TCP connection state, a value from the \ref TCP_ConnectionStates_t enum * * \return Boolean true if the connection was updated or created, false otherwise (no more space in the connection state table) */ bool TCP_SetConnectionState(const uint16_t Port, - const IP_Address_t RemoteAddress, + const IP_Address_t* RemoteAddress, const uint16_t RemotePort, const uint8_t State) { @@ -263,7 +260,7 @@ bool TCP_SetConnectionState(const uint16_t Port, { /* Find port entry in the table */ if ((ConnectionStateTable[CSTableEntry].Port == Port) && - IP_COMPARE(&ConnectionStateTable[CSTableEntry].RemoteAddress, &RemoteAddress) && + IP_COMPARE(&ConnectionStateTable[CSTableEntry].RemoteAddress, RemoteAddress) && ConnectionStateTable[CSTableEntry].RemotePort == RemotePort) { ConnectionStateTable[CSTableEntry].State = State; @@ -277,7 +274,7 @@ bool TCP_SetConnectionState(const uint16_t Port, if (ConnectionStateTable[CSTableEntry].State == TCP_Connection_Closed) { ConnectionStateTable[CSTableEntry].Port = Port; - ConnectionStateTable[CSTableEntry].RemoteAddress = RemoteAddress; + ConnectionStateTable[CSTableEntry].RemoteAddress = *RemoteAddress; ConnectionStateTable[CSTableEntry].RemotePort = RemotePort; ConnectionStateTable[CSTableEntry].State = State; return true; @@ -293,10 +290,10 @@ bool TCP_SetConnectionState(const uint16_t Port, * \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 + * \return A value from the \ref TCP_ConnectionStates_t enum */ uint8_t TCP_GetConnectionState(const uint16_t Port, - const IP_Address_t RemoteAddress, + const IP_Address_t* RemoteAddress, const uint16_t RemotePort) { /* Note, Port number should be specified in BIG endian to simplify network code */ @@ -305,7 +302,7 @@ uint8_t TCP_GetConnectionState(const uint16_t Port, { /* Find port entry in the table */ if ((ConnectionStateTable[CSTableEntry].Port == Port) && - IP_COMPARE(&ConnectionStateTable[CSTableEntry].RemoteAddress, &RemoteAddress) && + IP_COMPARE(&ConnectionStateTable[CSTableEntry].RemoteAddress, RemoteAddress) && ConnectionStateTable[CSTableEntry].RemotePort == RemotePort) { @@ -325,7 +322,7 @@ uint8_t TCP_GetConnectionState(const uint16_t Port, * \return ConnectionInfo structure of the connection if found, NULL otherwise */ TCP_ConnectionInfo_t* TCP_GetConnectionInfo(const uint16_t Port, - const IP_Address_t RemoteAddress, + const IP_Address_t* RemoteAddress, const uint16_t RemotePort) { /* Note, Port number should be specified in BIG endian to simplify network code */ @@ -334,7 +331,7 @@ TCP_ConnectionInfo_t* TCP_GetConnectionInfo(const uint16_t Port, { /* Find port entry in the table */ if ((ConnectionStateTable[CSTableEntry].Port == Port) && - IP_COMPARE(&ConnectionStateTable[CSTableEntry].RemoteAddress, &RemoteAddress) && + IP_COMPARE(&ConnectionStateTable[CSTableEntry].RemoteAddress, RemoteAddress) && ConnectionStateTable[CSTableEntry].RemotePort == RemotePort) { return &ConnectionStateTable[CSTableEntry].Info; @@ -374,12 +371,12 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, { /* Detect SYN from host to start a connection */ if (TCPHeaderIN->Flags & TCP_FLAG_SYN) - TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort, TCP_Connection_Listen); + TCP_SetConnectionState(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort, TCP_Connection_Listen); /* Detect RST from host to abort existing connection */ if (TCPHeaderIN->Flags & TCP_FLAG_RST) { - if (TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + if (TCP_SetConnectionState(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort, TCP_Connection_Closed)) { TCPHeaderOUT->Flags = (TCP_FLAG_RST | TCP_FLAG_ACK); @@ -389,18 +386,18 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, else { /* Process the incoming TCP packet based on the current connection state for the sender and port */ - switch (TCP_GetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort)) + switch (TCP_GetConnectionState(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort)) { case TCP_Connection_Listen: if (TCPHeaderIN->Flags == TCP_FLAG_SYN) { /* SYN connection starts a connection with a peer */ - if (TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + if (TCP_SetConnectionState(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort, TCP_Connection_SYNReceived)) { TCPHeaderOUT->Flags = (TCP_FLAG_SYN | TCP_FLAG_ACK); - 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; @@ -420,10 +417,10 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, { /* ACK during the connection process completes the connection to a peer */ - TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + TCP_SetConnectionState(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort, TCP_Connection_Established); - ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort); ConnectionInfo->SequenceNumberOut++; @@ -438,10 +435,10 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, TCPHeaderOUT->Flags = (TCP_FLAG_FIN | TCP_FLAG_ACK); PacketResponse = true; - TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + TCP_SetConnectionState(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort, TCP_Connection_CloseWait); - ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort); ConnectionInfo->SequenceNumberIn++; @@ -449,7 +446,7 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, } else if ((TCPHeaderIN->Flags == TCP_FLAG_ACK) || (TCPHeaderIN->Flags == (TCP_FLAG_ACK | TCP_FLAG_PSH))) { - ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort); /* Check if the buffer is currently in use either by a buffered data to send, or receive */ @@ -495,7 +492,7 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, break; case TCP_Connection_Closing: - ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort); TCPHeaderOUT->Flags = (TCP_FLAG_ACK | TCP_FLAG_FIN); @@ -503,14 +500,14 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, ConnectionInfo->Buffer.InUse = false; - TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + TCP_SetConnectionState(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort, TCP_Connection_FINWait1); break; case TCP_Connection_FINWait1: if (TCPHeaderIN->Flags == (TCP_FLAG_FIN | TCP_FLAG_ACK)) { - ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort); TCPHeaderOUT->Flags = TCP_FLAG_ACK; @@ -519,12 +516,12 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, ConnectionInfo->SequenceNumberIn++; ConnectionInfo->SequenceNumberOut++; - TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + TCP_SetConnectionState(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort, TCP_Connection_Closed); } else if (TCPHeaderIN->Flags == TCP_FLAG_ACK) { - TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + TCP_SetConnectionState(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort, TCP_Connection_FINWait2); } @@ -532,7 +529,7 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, case TCP_Connection_FINWait2: if (TCPHeaderIN->Flags == (TCP_FLAG_FIN | TCP_FLAG_ACK)) { - ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort); TCPHeaderOUT->Flags = TCP_FLAG_ACK; @@ -541,7 +538,7 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, ConnectionInfo->SequenceNumberIn++; ConnectionInfo->SequenceNumberOut++; - TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + TCP_SetConnectionState(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort, TCP_Connection_Closed); } @@ -549,7 +546,7 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, case TCP_Connection_CloseWait: if (TCPHeaderIN->Flags == TCP_FLAG_ACK) { - TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + TCP_SetConnectionState(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort, TCP_Connection_Closed); } @@ -567,7 +564,7 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, /* Check if we need to respond to the sent packet */ if (PacketResponse) { - ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, + ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, &IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort); TCPHeaderOUT->SourcePort = TCPHeaderIN->DestinationPort; @@ -585,8 +582,8 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, TCPHeaderOUT->Checksum = 0; TCPHeaderOUT->Reserved = 0; - TCPHeaderOUT->Checksum = TCP_Checksum16(TCPHeaderOUT, IPHeaderIN->DestinationAddress, - IPHeaderIN->SourceAddress, sizeof(TCP_Header_t)); + TCPHeaderOUT->Checksum = TCP_Checksum16(TCPHeaderOUT, &IPHeaderIN->DestinationAddress, + &IPHeaderIN->SourceAddress, sizeof(TCP_Header_t)); return sizeof(TCP_Header_t); } @@ -605,19 +602,19 @@ int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, * \return A 16-bit TCP checksum value */ static uint16_t TCP_Checksum16(void* TCPHeaderOutStart, - const IP_Address_t SourceAddress, - const IP_Address_t DestinationAddress, - const uint16_t TCPOutSize) + const IP_Address_t* SourceAddress, + const IP_Address_t* DestinationAddress, + uint16_t TCPOutSize) { uint32_t Checksum = 0; /* TCP/IP checksums are the addition of the one's compliment of each word including the IP pseudo-header, complimented */ - Checksum += ((uint16_t*)&SourceAddress)[0]; - Checksum += ((uint16_t*)&SourceAddress)[1]; - Checksum += ((uint16_t*)&DestinationAddress)[0]; - Checksum += ((uint16_t*)&DestinationAddress)[1]; + Checksum += ((uint16_t*)SourceAddress)[0]; + Checksum += ((uint16_t*)SourceAddress)[1]; + Checksum += ((uint16_t*)DestinationAddress)[0]; + Checksum += ((uint16_t*)DestinationAddress)[1]; Checksum += SwapEndian_16(PROTOCOL_TCP); Checksum += SwapEndian_16(TCPOutSize);