From 4421782b7fb49e160b1c18f2295e6cd1f0b00c04 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Wed, 5 Aug 2009 11:39:28 +0000 Subject: [PATCH] Make Control Endpoint stream transfers more reliable by adding in early aborts for unexpected new SETUP tokens, or unexpected status stage during control stream writes. Fix corruption in Device RNDIS demos TCP stack when too many connections attempted simultaneously, freezing the device when a page was re-fetched before the first connection was closed. Fix incorrect model compatibility information in the Host LowLevel demo overview text files. --- .../ClassDriver/RNDISEthernet/Lib/TCP.c | 27 +++++++----- .../ClassDriver/RNDISEthernet/Lib/TCP.h | 2 +- Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.c | 27 +++++++----- Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.h | 2 +- Demos/Host/LowLevel/CDCHost/CDCHost.txt | 2 +- .../GenericHIDHost/GenericHIDHost.txt | 2 +- .../LowLevel/KeyboardHost/KeyboardHost.txt | 2 +- .../KeyboardHostWithParser.txt | 2 +- .../MassStorageHost/MassStorageHost.txt | 2 +- Demos/Host/LowLevel/MouseHost/MouseHost.txt | 2 +- .../MouseHostWithParser.txt | 2 +- .../Host/LowLevel/PrinterHost/PrinterHost.txt | 2 +- .../StillImageHost/StillImageHost.txt | 2 +- LUFA.pnproj | 2 +- LUFA/Drivers/USB/LowLevel/Endpoint.c | 2 +- .../Template/Template_Endpoint_Control_R.c | 11 +++-- .../Template/Template_Endpoint_Control_W.c | 44 ++++++++----------- LUFA/ManPages/ChangeLog.txt | 1 + 18 files changed, 71 insertions(+), 65 deletions(-) diff --git a/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c b/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c index 674643381d..c94495dc33 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c +++ b/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c @@ -381,19 +381,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; diff --git a/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.h b/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.h index b61de7e18c..4e1e0d7a62 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.h +++ b/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.h @@ -49,7 +49,7 @@ #define MAX_OPEN_TCP_PORTS 1 /** Maximum number of TCP connections which can be sustained at the one time */ - #define MAX_TCP_CONNECTIONS 1 + #define MAX_TCP_CONNECTIONS 3 /** TCP window size, giving the maximum number of bytes which can be buffered at the one time */ #define TCP_WINDOW_SIZE 512 diff --git a/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.c b/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.c index b4fc12c934..57b3f3a8cf 100644 --- a/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.c +++ b/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.c @@ -381,19 +381,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; diff --git a/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.h b/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.h index eac682547e..460e3f819f 100644 --- a/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.h +++ b/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.h @@ -49,7 +49,7 @@ #define MAX_OPEN_TCP_PORTS 1 /** Maximum number of TCP connections which can be sustained at the one time */ - #define MAX_TCP_CONNECTIONS 1 + #define MAX_TCP_CONNECTIONS 3 /** TCP window size, giving the maximum number of bytes which can be buffered at the one time */ #define TCP_WINDOW_SIZE 512 diff --git a/Demos/Host/LowLevel/CDCHost/CDCHost.txt b/Demos/Host/LowLevel/CDCHost/CDCHost.txt index 30a88ba0c8..58469ab457 100644 --- a/Demos/Host/LowLevel/CDCHost/CDCHost.txt +++ b/Demos/Host/LowLevel/CDCHost/CDCHost.txt @@ -11,7 +11,7 @@ * The following table indicates what microcontrollers are compatible with this demo. * * - AT90USB1287 - * - AT90USB1286 + * - AT90USB647 * * \section SSec_Info USB Information: * diff --git a/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.txt b/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.txt index 0a82aaa0d4..51d91cc6e3 100644 --- a/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.txt +++ b/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.txt @@ -11,7 +11,7 @@ * The following table indicates what microcontrollers are compatible with this demo. * * - AT90USB1287 - * - AT90USB1286 + * - AT90USB647 * * \section SSec_Info USB Information: * diff --git a/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.txt b/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.txt index 6eba0ae2ea..42009a3cad 100644 --- a/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.txt +++ b/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.txt @@ -11,7 +11,7 @@ * The following table indicates what microcontrollers are compatible with this demo. * * - AT90USB1287 - * - AT90USB1286 + * - AT90USB647 * * \section SSec_Info USB Information: * diff --git a/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.txt b/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.txt index cc883ea2d6..b9ad58b929 100644 --- a/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.txt +++ b/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.txt @@ -11,7 +11,7 @@ * The following table indicates what microcontrollers are compatible with this demo. * * - AT90USB1287 - * - AT90USB1286 + * - AT90USB647 * * \section SSec_Info USB Information: * diff --git a/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.txt b/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.txt index 165245c2f1..5872d1947f 100644 --- a/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.txt +++ b/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.txt @@ -11,7 +11,7 @@ * The following table indicates what microcontrollers are compatible with this demo. * * - AT90USB1287 - * - AT90USB1286 + * - AT90USB647 * * \section SSec_Info USB Information: * diff --git a/Demos/Host/LowLevel/MouseHost/MouseHost.txt b/Demos/Host/LowLevel/MouseHost/MouseHost.txt index d3106256d6..8a3c1674c1 100644 --- a/Demos/Host/LowLevel/MouseHost/MouseHost.txt +++ b/Demos/Host/LowLevel/MouseHost/MouseHost.txt @@ -11,7 +11,7 @@ * The following table indicates what microcontrollers are compatible with this demo. * * - AT90USB1287 - * - AT90USB1286 + * - AT90USB647 * * \section SSec_Info USB Information: * diff --git a/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.txt b/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.txt index 77bd16f33f..c0ff4bfbbd 100644 --- a/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.txt +++ b/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.txt @@ -11,7 +11,7 @@ * The following table indicates what microcontrollers are compatible with this demo. * * - AT90USB1287 - * - AT90USB1286 + * - AT90USB647 * * \section SSec_Info USB Information: * diff --git a/Demos/Host/LowLevel/PrinterHost/PrinterHost.txt b/Demos/Host/LowLevel/PrinterHost/PrinterHost.txt index 6326469e02..79310310ff 100644 --- a/Demos/Host/LowLevel/PrinterHost/PrinterHost.txt +++ b/Demos/Host/LowLevel/PrinterHost/PrinterHost.txt @@ -11,7 +11,7 @@ * The following table indicates what microcontrollers are compatible with this demo. * * - AT90USB1287 - * - AT90USB1286 + * - AT90USB647 * * \section SSec_Info USB Information: * diff --git a/Demos/Host/LowLevel/StillImageHost/StillImageHost.txt b/Demos/Host/LowLevel/StillImageHost/StillImageHost.txt index b2a8a84cf4..776e1a49cf 100644 --- a/Demos/Host/LowLevel/StillImageHost/StillImageHost.txt +++ b/Demos/Host/LowLevel/StillImageHost/StillImageHost.txt @@ -11,7 +11,7 @@ * The following table indicates what microcontrollers are compatible with this demo. * * - AT90USB1287 - * - AT90USB1286 + * - AT90USB647 * * \section SSec_Info USB Information: * diff --git a/LUFA.pnproj b/LUFA.pnproj index fec63be62a..dd3739e949 100644 --- a/LUFA.pnproj +++ b/LUFA.pnproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/LUFA/Drivers/USB/LowLevel/Endpoint.c b/LUFA/Drivers/USB/LowLevel/Endpoint.c index e4d01404dd..8b3922a4a8 100644 --- a/LUFA/Drivers/USB/LowLevel/Endpoint.c +++ b/LUFA/Drivers/USB/LowLevel/Endpoint.c @@ -76,7 +76,7 @@ void Endpoint_ClearStatusStage(void) if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST) { while (!(Endpoint_IsOUTReceived())) - { + { if (USB_DeviceState == DEVICE_STATE_Unattached) return; } diff --git a/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_R.c b/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_R.c index b85705c226..a2a0c3bd59 100644 --- a/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_R.c +++ b/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_R.c @@ -4,6 +4,12 @@ uint8_t TEMPLATE_FUNC_NAME (void* Buffer, uint16_t Length) while (Length) { + if (Endpoint_IsSETUPReceived()) + return ENDPOINT_RWCSTREAM_HostAborted; + + if (USB_DeviceState == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + if (Endpoint_IsOUTReceived()) { while (Length && Endpoint_BytesInEndpoint()) @@ -13,10 +19,7 @@ uint8_t TEMPLATE_FUNC_NAME (void* Buffer, uint16_t Length) } Endpoint_ClearOUT(); - } - - if (USB_DeviceState == DEVICE_STATE_Unattached) - return ENDPOINT_RWCSTREAM_DeviceDisconnected; + } } while (!(Endpoint_IsINReady())) diff --git a/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_W.c b/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_W.c index 43a9f3d42c..6c1445ee0c 100644 --- a/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_W.c +++ b/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_W.c @@ -6,36 +6,28 @@ uint8_t TEMPLATE_FUNC_NAME (void* Buffer, uint16_t Length) if (Length > USB_ControlRequest.wLength) Length = USB_ControlRequest.wLength; - while (Length && !(Endpoint_IsOUTReceived())) + while (Length || LastPacketFull) { - while (!(Endpoint_IsINReady())) - { - if (USB_DeviceState == DEVICE_STATE_Unattached) - return ENDPOINT_RWCSTREAM_DeviceDisconnected; - } - - while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize)) - { - TEMPLATE_TRANSFER_BYTE(DataStream); - Length--; - } + if (Endpoint_IsSETUPReceived()) + return ENDPOINT_RWCSTREAM_HostAborted; + + if (Endpoint_IsOUTReceived()) + break; - LastPacketFull = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize); - Endpoint_ClearIN(); - } - - if (Endpoint_IsOUTReceived()) - return ENDPOINT_RWCSTREAM_HostAborted; - - if (LastPacketFull) - { - while (!(Endpoint_IsINReady())) + if (USB_DeviceState == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + + if (Endpoint_IsINReady()) { - if (USB_DeviceState == DEVICE_STATE_Unattached) - return ENDPOINT_RWCSTREAM_DeviceDisconnected; + while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize)) + { + TEMPLATE_TRANSFER_BYTE(DataStream); + Length--; + } + + LastPacketFull = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize); + Endpoint_ClearIN(); } - - Endpoint_ClearIN(); } while (!(Endpoint_IsOUTReceived())) diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 1a3d0d86c4..6037593e2c 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -85,6 +85,7 @@ * - Fixed report data alignment issues in the MouseHostWithParser demo when X and Y movement data size is not a multiple of 8 bits * - Fixed HID Report Descriptor Parser not correctly resetting internal states when a REPORT ID element is encountered * - Fixed incorrect BUTTONS_BUTTON1 for the STK526 target + * - Fixed RNDIS demos freezing when more than one connection was attempted simultaneously, causing memory corruption * * * \section Sec_ChangeLog090605 Version 090605