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 674643381d2..c94495dc33f 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->SequenceNumberIn = (SwapEndian_32(TCPHeaderIN->SequenceNumber) + 1); + ConnectionInfo->SequenceNumberOut = 0; + ConnectionInfo->Buffer.InUse = false; + } + else + { + TCPHeaderOUT->Flags = TCP_FLAG_RST; + } - ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort); - - ConnectionInfo->SequenceNumberIn = (SwapEndian_32(TCPHeaderIN->SequenceNumber) + 1); - ConnectionInfo->SequenceNumberOut = 0; - ConnectionInfo->Buffer.InUse = false; + PacketResponse = true; } break; diff --git a/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.h b/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.h index b61de7e18cf..4e1e0d7a625 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 b4fc12c934d..57b3f3a8cf5 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->SequenceNumberIn = (SwapEndian_32(TCPHeaderIN->SequenceNumber) + 1); + ConnectionInfo->SequenceNumberOut = 0; + ConnectionInfo->Buffer.InUse = false; + } + else + { + TCPHeaderOUT->Flags = TCP_FLAG_RST; + } - ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort); - - ConnectionInfo->SequenceNumberIn = (SwapEndian_32(TCPHeaderIN->SequenceNumber) + 1); - ConnectionInfo->SequenceNumberOut = 0; - ConnectionInfo->Buffer.InUse = false; + PacketResponse = true; } break; diff --git a/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.h b/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.h index eac682547ec..460e3f819fa 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 30a88ba0c8b..58469ab4570 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 0a82aaa0d4e..51d91cc6e30 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 6eba0ae2ea4..42009a3cadc 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 cc883ea2d61..b9ad58b929f 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 165245c2f10..5872d1947f4 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 d3106256d62..8a3c1674c18 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 77bd16f33f7..c0ff4bfbbd1 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 6326469e028..79310310ff8 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 b2a8a84cf49..776e1a49cf0 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 fec63be62a1..dd3739e949a 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 e4d01404ddc..8b3922a4a86 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 b85705c2267..a2a0c3bd598 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 43a9f3d42c1..6c1445ee0cb 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; - } + if (Endpoint_IsSETUPReceived()) + return ENDPOINT_RWCSTREAM_HostAborted; + + if (Endpoint_IsOUTReceived()) + break; - while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize)) + if (USB_DeviceState == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + + if (Endpoint_IsINReady()) { - TEMPLATE_TRANSFER_BYTE(DataStream); - Length--; + while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize)) + { + TEMPLATE_TRANSFER_BYTE(DataStream); + Length--; + } + + LastPacketFull = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize); + Endpoint_ClearIN(); } - - 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; - } - - Endpoint_ClearIN(); } while (!(Endpoint_IsOUTReceived())) diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 1a3d0d86c41..6037593e2c1 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