diff --git a/Demos/Device/ClassDriver/RNDISEthernet/Lib/DHCP.c b/Demos/Device/ClassDriver/RNDISEthernet/Lib/DHCP.c index a72a6ce3fd..b3b5d6943b 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/Lib/DHCP.c +++ b/Demos/Device/ClassDriver/RNDISEthernet/Lib/DHCP.c @@ -54,8 +54,8 @@ int16_t DHCP_ProcessDHCPPacket(void* IPHeaderInStart, DHCP_Header_t* DHCPHeaderIN = (DHCP_Header_t*)DHCPHeaderInStart; DHCP_Header_t* DHCPHeaderOUT = (DHCP_Header_t*)DHCPHeaderOutStart; - uint8_t* DHCPOptionsINStart = (uint8_t*)(DHCPHeaderInStart + sizeof(DHCP_Header_t)); - uint8_t* DHCPOptionsOUTStart = (uint8_t*)(DHCPHeaderOutStart + sizeof(DHCP_Header_t)); + uint8_t* DHCPOptionsINStart = ((uint8_t*)DHCPHeaderInStart + sizeof(DHCP_Header_t)); + uint8_t* DHCPOptionsOUTStart = ((uint8_t*)DHCPHeaderOutStart + sizeof(DHCP_Header_t)); DecodeDHCPHeader(DHCPHeaderInStart); diff --git a/Demos/Device/ClassDriver/RNDISEthernet/Lib/Webserver.h b/Demos/Device/ClassDriver/RNDISEthernet/Lib/Webserver.h index 8307d46dad..142dc7a039 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/Lib/Webserver.h +++ b/Demos/Device/ClassDriver/RNDISEthernet/Lib/Webserver.h @@ -46,7 +46,7 @@ /* Macros: */ /** Maximum size of a HTTP response per transmission */ - #define HTTP_REPLY_BLOCK_SIZE 128 + #define HTTP_REPLY_BLOCK_SIZE 128 /* Function Prototypes: */ void Webserver_Init(void); diff --git a/Demos/Device/ClassDriver/RNDISEthernet/RNDISEthernet.c b/Demos/Device/ClassDriver/RNDISEthernet/RNDISEthernet.c index 95d93549ec..bdb5061178 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/RNDISEthernet.c +++ b/Demos/Device/ClassDriver/RNDISEthernet/RNDISEthernet.c @@ -36,6 +36,15 @@ #include "RNDISEthernet.h" +/** Message buffer for RNDIS messages processed by the RNDIS device class driver. */ +static uint8_t RNDIS_Message_Buffer[192]; + +/** Global to store the incoming frame from the host before it is processed by the device. */ +static Ethernet_Frame_Info_t FrameIN; + +/** Global to store the outgoing frame created in the device before it is sent to the host. */ +static Ethernet_Frame_Info_t FrameOUT; + /** LUFA RNDIS Class driver interface configuration and state information. This structure is * passed to all RNDIS Class driver functions, so that multiple instances of the same class * within a device can be differentiated from one another. @@ -65,14 +74,11 @@ USB_ClassInfo_RNDIS_Device_t Ethernet_RNDIS_Interface = }, .AdapterVendorDescription = "LUFA RNDIS Demo Adapter", .AdapterMACAddress = {ADAPTER_MAC_ADDRESS}, + .MessageBuffer = RNDIS_Message_Buffer, + .MessageBufferLength = sizeof(RNDIS_Message_Buffer), }, }; -/** Global to store the incoming frame from the host before it is processed by the device. */ -static Ethernet_Frame_Info_t FrameIN; - -/** Global to store the outgoing frame created in the device before it is sent to the host. */ -static Ethernet_Frame_Info_t FrameOUT; /** Main program entry point. This routine contains the overall program flow, including initial * setup of all components and the main program loop. diff --git a/Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.h b/Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.h index d01b3cb23e..90fbae3350 100644 --- a/Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.h +++ b/Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.h @@ -58,9 +58,6 @@ #include /* Macros: */ - /** Notification value to indicate that a frame is ready to be read by the host. */ - #define NOTIF_RESPONSE_AVAILABLE 0x01 - /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */ #define LEDMASK_USB_NOTREADY LEDS_LED1 diff --git a/LUFA/DoxygenPages/ChangeLog.txt b/LUFA/DoxygenPages/ChangeLog.txt index 3eab8b0a4c..db10c2ad82 100644 --- a/LUFA/DoxygenPages/ChangeLog.txt +++ b/LUFA/DoxygenPages/ChangeLog.txt @@ -12,6 +12,11 @@ * - Updated the BUILD build system module to add a new COMPILER_PATH optional variable * - Added Serial_IsSendReady() and Serial_IsSendComplete() functions to the Serial hardware peripheral driver * + * Changed: + * - Core: + * - The RNDIS device class driver now takes a user-supplied buffer and buffer length for the internal RNDIS + * message management (thanks to Peter Mc Shane) + * * Fixed: * - Core: * - Fixed device class driver pipe configuration routines returning success with a partially constructed instance diff --git a/LUFA/DoxygenPages/MigrationInformation.txt b/LUFA/DoxygenPages/MigrationInformation.txt index e87fa1618d..e2e0f9ae73 100644 --- a/LUFA/DoxygenPages/MigrationInformation.txt +++ b/LUFA/DoxygenPages/MigrationInformation.txt @@ -11,7 +11,9 @@ * areas relevant to making older projects compatible with the API changes of each new release. * * \section Sec_MigrationXXXXXX Migrating from 140302 to XXXXXX - * None + * Device Mode + * - The device mode RNDIS class driver now requires a user-supplied buffer and buffer length to operate, rather + * than allocating this buffer internally. * * \section Sec_Migration140302 Migrating from 130901 to 140302 * USB Core diff --git a/LUFA/Drivers/USB/Class/Common/RNDISClassCommon.h b/LUFA/Drivers/USB/Class/Common/RNDISClassCommon.h index 5c6d3fdcc5..640745efe8 100644 --- a/LUFA/Drivers/USB/Class/Common/RNDISClassCommon.h +++ b/LUFA/Drivers/USB/Class/Common/RNDISClassCommon.h @@ -172,9 +172,6 @@ #define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103UL //@} - /** Maximum size in bytes of a RNDIS control message which can be sent or received. */ - #define RNDIS_MESSAGE_BUFFER_SIZE 128 - /** Maximum size in bytes of an Ethernet frame according to the Ethernet standard. */ #define ETHERNET_FRAME_SIZE_MAX 1500 diff --git a/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c b/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c index 061f1b2496..6ee73c5bb9 100644 --- a/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c +++ b/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c @@ -82,7 +82,7 @@ void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDI if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) { Endpoint_ClearSETUP(); - Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, USB_ControlRequest.wLength); + Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->Config.MessageBuffer, USB_ControlRequest.wLength); Endpoint_ClearIN(); RNDIS_Device_ProcessRNDISControlMessage(RNDISInterfaceInfo); @@ -92,16 +92,16 @@ void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDI case RNDIS_REQ_GetEncapsulatedResponse: if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) { - RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)RNDISInterfaceInfo->Config.MessageBuffer; if (!(MessageHeader->MessageLength)) { - RNDISInterfaceInfo->State.RNDISMessageBuffer[0] = 0; - MessageHeader->MessageLength = CPU_TO_LE32(1); + RNDISInterfaceInfo->Config.MessageBuffer[0] = 0; + MessageHeader->MessageLength = CPU_TO_LE32(1); } Endpoint_ClearSETUP(); - Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, le32_to_cpu(MessageHeader->MessageLength)); + Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->Config.MessageBuffer, le32_to_cpu(MessageHeader->MessageLength)); Endpoint_ClearOUT(); MessageHeader->MessageLength = CPU_TO_LE32(0); @@ -119,6 +119,12 @@ bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISIn RNDISInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK; RNDISInterfaceInfo->Config.NotificationEndpoint.Type = EP_TYPE_INTERRUPT; + if (RNDISInterfaceInfo->Config.MessageBuffer == NULL) + return false; + + if (RNDISInterfaceInfo->Config.MessageBufferLength < RNDIS_DEVICE_MIN_MESSAGE_BUFFER_LENGTH) + return false; + if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.DataINEndpoint, 1))) return false; @@ -162,7 +168,7 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */ - RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)RNDISInterfaceInfo->Config.MessageBuffer; switch (le32_to_cpu(MessageHeader->MessageType)) { @@ -170,9 +176,9 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo->State.ResponseReady = true; RNDIS_Initialize_Message_t* INITIALIZE_Message = - (RNDIS_Initialize_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + (RNDIS_Initialize_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer; RNDIS_Initialize_Complete_t* INITIALIZE_Response = - (RNDIS_Initialize_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + (RNDIS_Initialize_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer; INITIALIZE_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_INITIALIZE_CMPLT); INITIALIZE_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Initialize_Complete_t)); @@ -201,13 +207,13 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const case REMOTE_NDIS_QUERY_MSG: RNDISInterfaceInfo->State.ResponseReady = true; - RNDIS_Query_Message_t* QUERY_Message = (RNDIS_Query_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; - RNDIS_Query_Complete_t* QUERY_Response = (RNDIS_Query_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + RNDIS_Query_Message_t* QUERY_Message = (RNDIS_Query_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer; + RNDIS_Query_Complete_t* QUERY_Response = (RNDIS_Query_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer; uint32_t Query_Oid = CPU_TO_LE32(QUERY_Message->Oid); - void* QueryData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) + - le32_to_cpu(QUERY_Message->InformationBufferOffset)]; - void* ResponseData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Query_Complete_t)]; + void* QueryData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Message_Header_t) + + le32_to_cpu(QUERY_Message->InformationBufferOffset)]; + void* ResponseData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Query_Complete_t)]; uint16_t ResponseSize; QUERY_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_QUERY_CMPLT); @@ -234,15 +240,15 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const case REMOTE_NDIS_SET_MSG: RNDISInterfaceInfo->State.ResponseReady = true; - RNDIS_Set_Message_t* SET_Message = (RNDIS_Set_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; - RNDIS_Set_Complete_t* SET_Response = (RNDIS_Set_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + RNDIS_Set_Message_t* SET_Message = (RNDIS_Set_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer; + RNDIS_Set_Complete_t* SET_Response = (RNDIS_Set_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer; uint32_t SET_Oid = le32_to_cpu(SET_Message->Oid); SET_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_SET_CMPLT); SET_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Set_Complete_t)); SET_Response->RequestId = SET_Message->RequestId; - void* SetData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) + + void* SetData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Message_Header_t) + le32_to_cpu(SET_Message->InformationBufferOffset)]; SET_Response->Status = RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData, @@ -252,7 +258,7 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const case REMOTE_NDIS_RESET_MSG: RNDISInterfaceInfo->State.ResponseReady = true; - RNDIS_Reset_Complete_t* RESET_Response = (RNDIS_Reset_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + RNDIS_Reset_Complete_t* RESET_Response = (RNDIS_Reset_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer; RESET_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_RESET_CMPLT); RESET_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Reset_Complete_t)); @@ -264,9 +270,9 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo->State.ResponseReady = true; RNDIS_KeepAlive_Message_t* KEEPALIVE_Message = - (RNDIS_KeepAlive_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + (RNDIS_KeepAlive_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer; RNDIS_KeepAlive_Complete_t* KEEPALIVE_Response = - (RNDIS_KeepAlive_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + (RNDIS_KeepAlive_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer; KEEPALIVE_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_KEEPALIVE_CMPLT); KEEPALIVE_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_KeepAlive_Complete_t)); @@ -387,7 +393,7 @@ static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RN *ResponseSize = sizeof(uint32_t); /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */ - *((uint32_t*)ResponseData) = CPU_TO_LE32(RNDIS_MESSAGE_BUFFER_SIZE + ETHERNET_FRAME_SIZE_MAX); + *((uint32_t*)ResponseData) = CPU_TO_LE32(RNDISInterfaceInfo->Config.MessageBufferLength + ETHERNET_FRAME_SIZE_MAX); return true; default: diff --git a/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h b/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h index 4ba729a7e9..2821d7deba 100644 --- a/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h +++ b/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h @@ -87,14 +87,15 @@ char* AdapterVendorDescription; /**< String description of the adapter vendor. */ MAC_Address_t AdapterMACAddress; /**< MAC address of the adapter. */ + + uint8_t* MessageBuffer; /**< Buffer where RNDIS messages can be stored by the internal driver. This + * should be at least 132 bytes in length for minimal functionality. */ + uint16_t MessageBufferLength; /**< Length in bytes of the \ref MessageBuffer RNDIS buffer. */ } Config; /**< Config data for the USB class interface within the device. All elements in this section * must be set or the interface will fail to enumerate and operate correctly. */ struct { - uint8_t RNDISMessageBuffer[RNDIS_MESSAGE_BUFFER_SIZE]; /**< Buffer to hold RNDIS messages to and from the host, - * managed by the class driver. - */ bool ResponseReady; /**< Internal flag indicating if a RNDIS message is waiting to be returned to the host. */ uint8_t CurrRNDISState; /**< Current RNDIS state of the adapter, a value from the \ref RNDIS_States_t enum. */ uint32_t CurrPacketFilter; /**< Current packet filter mode, used internally by the class driver. */ @@ -172,6 +173,9 @@ /* Private Interface - For use in library only: */ #if !defined(__DOXYGEN__) + /* Macros: */ + #define RNDIS_DEVICE_MIN_MESSAGE_BUFFER_LENGTH sizeof(AdapterSupportedOIDList) + sizeof(RNDIS_Query_Complete_t) + /* Function Prototypes: */ #if defined(__INCLUDE_FROM_RNDIS_DEVICE_C) static void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) diff --git a/Projects/Webserver/USBDeviceMode.c b/Projects/Webserver/USBDeviceMode.c index b8e41f4c0c..b2c6b39094 100644 --- a/Projects/Webserver/USBDeviceMode.c +++ b/Projects/Webserver/USBDeviceMode.c @@ -36,6 +36,9 @@ #include "USBDeviceMode.h" +/** Message buffer for RNDIS messages processed by the RNDIS device class driver. */ +static uint8_t RNDIS_Message_Buffer[192]; + /** LUFA RNDIS Class driver interface configuration and state information. This structure is * passed to all RNDIS Class driver functions, so that multiple instances of the same class * within a device can be differentiated from one another. @@ -65,6 +68,8 @@ USB_ClassInfo_RNDIS_Device_t Ethernet_RNDIS_Interface_Device = }, .AdapterVendorDescription = "LUFA RNDIS Adapter", .AdapterMACAddress = {{0x02, 0x00, 0x02, 0x00, 0x02, 0x00}}, + .MessageBuffer = RNDIS_Message_Buffer, + .MessageBufferLength = sizeof(RNDIS_Message_Buffer), }, };