diff --git a/Demos/Host/Incomplete/RNDISEthernetHost/Lib/RNDISCommands.c b/Demos/Host/Incomplete/RNDISEthernetHost/Lib/RNDISCommands.c index 6bacc8f6dd..e248b18dab 100644 --- a/Demos/Host/Incomplete/RNDISEthernetHost/Lib/RNDISCommands.c +++ b/Demos/Host/Incomplete/RNDISEthernetHost/Lib/RNDISCommands.c @@ -48,17 +48,6 @@ uint8_t RNDIS_SendEncapsulatedCommand(void* Buffer, uint16_t Length) .wIndex = 0, .wLength = Length, }; - - printf("==== RNDIS CONTROL REQUEST ====\r\n"); - uint8_t* Data = Buffer; - for (uint16_t i = 0; i < Length / 8; i++) - { - for (uint16_t j = 0; (j < 8) && i*8+j < Length; j++) - printf("%02X ", *(Data++)); - - printf("\r\n"); - } - printf("==== ********************* ====\r\n"); /* Select the control pipe for the request transfer */ Pipe_SelectPipe(PIPE_CONTROLPIPE); @@ -83,6 +72,32 @@ uint8_t RNDIS_GetEncapsulatedResponse(void* Buffer, uint16_t Length) return USB_Host_SendControlRequest(Buffer); } +uint8_t RNDIS_KeepAlive(void) +{ + uint8_t ErrorCode; + + RNDIS_KeepAlive_Message_t KeepAliveMessage; + RNDIS_KeepAlive_Complete_t KeepAliveMessageResponse; + + KeepAliveMessage.MessageType = REMOTE_NDIS_KEEPALIVE_MSG; + KeepAliveMessage.MessageLength = sizeof(RNDIS_KeepAlive_Message_t); + KeepAliveMessage.RequestId = RequestID++; + + if ((ErrorCode = RNDIS_SendEncapsulatedCommand(&KeepAliveMessage, + sizeof(RNDIS_KeepAlive_Message_t))) != HOST_SENDCONTROL_Successful) + { + return ErrorCode; + } + + if ((ErrorCode = RNDIS_GetEncapsulatedResponse(&KeepAliveMessageResponse, + sizeof(RNDIS_KeepAlive_Complete_t))) != HOST_SENDCONTROL_Successful) + { + return ErrorCode; + } + + return HOST_SENDCONTROL_Successful; +} + uint8_t RNDIS_InitializeDevice(uint16_t MaxPacketSize, RNDIS_Initialize_Complete_t* InitMessageResponse) { uint8_t ErrorCode; @@ -131,7 +146,8 @@ uint8_t RNDIS_SetRNDISProperty(uint32_t Oid, void* Buffer, uint16_t Length) SetMessageData.SetMessage.InformationBufferLength = Length; SetMessageData.SetMessage.InformationBufferOffset = 0; SetMessageData.SetMessage.DeviceVcHandle = 0; - + + memcpy(&SetMessageData.ContigiousBuffer, Buffer, Length); if ((ErrorCode = RNDIS_SendEncapsulatedCommand(&SetMessageData, SetMessageData.SetMessage.MessageLength)) != HOST_SENDCONTROL_Successful) @@ -147,3 +163,57 @@ uint8_t RNDIS_SetRNDISProperty(uint32_t Oid, void* Buffer, uint16_t Length) return HOST_SENDCONTROL_Successful; } + +uint8_t RNDIS_QueryRNDISProperty(uint32_t Oid, void* Buffer, uint16_t Length) +{ + uint8_t ErrorCode; + + RNDIS_Query_Message_t QueryMessage; + + struct + { + RNDIS_Query_Complete_t QueryMessageResponse; + uint8_t ContigiousBuffer[Length]; + } QueryMessageResponseData; + + QueryMessage.MessageType = REMOTE_NDIS_QUERY_MSG; + QueryMessage.MessageLength = sizeof(RNDIS_Query_Message_t); + QueryMessage.RequestId = RequestID++; + + QueryMessage.Oid = Oid; + QueryMessage.InformationBufferLength = Length; + QueryMessage.InformationBufferOffset = 0; + QueryMessage.DeviceVcHandle = 0; + + if ((ErrorCode = RNDIS_SendEncapsulatedCommand(&QueryMessage, + sizeof(RNDIS_Query_Message_t))) != HOST_SENDCONTROL_Successful) + { + return ErrorCode; + } + + if ((ErrorCode = RNDIS_GetEncapsulatedResponse(&QueryMessageResponseData, + sizeof(QueryMessageResponseData))) != HOST_SENDCONTROL_Successful) + { + return ErrorCode; + } + + memcpy(Buffer, &QueryMessageResponseData.ContigiousBuffer, Length); + + return HOST_SENDCONTROL_Successful; +} + +uint8_t RNDIS_GetPacketSize(uint16_t* PacketSize) +{ + uint8_t ErrorCode; + + RNDIS_Packet_Message_t DeviceMessage; + + if ((ErrorCode = Pipe_Read_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t))) != PIPE_RWSTREAM_NoError) + { + return ErrorCode; + } + + *PacketSize = (uint16_t)DeviceMessage.DataLength; + + return PIPE_RWSTREAM_NoError; +} diff --git a/Demos/Host/Incomplete/RNDISEthernetHost/Lib/RNDISCommands.h b/Demos/Host/Incomplete/RNDISEthernetHost/Lib/RNDISCommands.h index dfb43e2e98..55f848bd0f 100644 --- a/Demos/Host/Incomplete/RNDISEthernetHost/Lib/RNDISCommands.h +++ b/Demos/Host/Incomplete/RNDISEthernetHost/Lib/RNDISCommands.h @@ -39,6 +39,7 @@ /* Includes: */ #include #include + #include #include @@ -199,7 +200,10 @@ uint8_t RNDIS_SendEncapsulatedCommand(void* Buffer, uint16_t Length); uint8_t RNDIS_GetEncapsulatedResponse(void* Buffer, uint16_t Length); + uint8_t RNDIS_KeepAlive(void); uint8_t RNDIS_InitializeDevice(uint16_t MaxPacketSize, RNDIS_Initialize_Complete_t* InitMessageResponse); uint8_t RNDIS_SetRNDISProperty(uint32_t Oid, void* Buffer, uint16_t Length); + uint8_t RNDIS_QueryRNDISProperty(uint32_t Oid, void* Buffer, uint16_t Length); + uint8_t RNDIS_GetPacketSize(uint16_t* PacketSize); #endif diff --git a/Demos/Host/Incomplete/RNDISEthernetHost/Lib/RNDISConstants.h b/Demos/Host/Incomplete/RNDISEthernetHost/Lib/RNDISConstants.h index ad66f62db7..f65a66cbf7 100644 --- a/Demos/Host/Incomplete/RNDISEthernetHost/Lib/RNDISConstants.h +++ b/Demos/Host/Incomplete/RNDISEthernetHost/Lib/RNDISConstants.h @@ -95,5 +95,18 @@ #define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101UL #define OID_802_3_XMIT_ONE_COLLISION 0x01020102UL #define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103UL + + #define RNDIS_PACKET_TYPE_DIRECTED 0x00000001UL + #define RNDIS_PACKET_TYPE_MULTICAST 0x00000002UL + #define RNDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004UL + #define RNDIS_PACKET_TYPE_BROADCAST 0x00000008UL + #define RNDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010UL + #define RNDIS_PACKET_TYPE_PROMISCUOUS 0x00000020UL + #define RNDIS_PACKET_TYPE_SMT 0x00000040UL + #define RNDIS_PACKET_TYPE_ALL_LOCAL 0x00000080UL + #define RNDIS_PACKET_TYPE_GROUP 0x00001000UL + #define RNDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00002000UL + #define RNDIS_PACKET_TYPE_FUNCTIONAL 0x00004000UL + #define RNDIS_PACKET_TYPE_MAC_FRAME 0x00008000UL #endif diff --git a/Demos/Host/Incomplete/RNDISEthernetHost/RNDISEthernetHost.c b/Demos/Host/Incomplete/RNDISEthernetHost/RNDISEthernetHost.c index 5b156ecda8..a64dfbdf28 100644 --- a/Demos/Host/Incomplete/RNDISEthernetHost/RNDISEthernetHost.c +++ b/Demos/Host/Incomplete/RNDISEthernetHost/RNDISEthernetHost.c @@ -121,6 +121,54 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8 LEDs_SetAllLEDs(LEDMASK_USB_ERROR); } +void PrintIncommingPackets(void) +{ + uint8_t ErrorCode; + + Pipe_SelectPipe(RNDIS_DATAPIPE_IN); + Pipe_Unfreeze(); + + if (!(Pipe_IsReadWriteAllowed())) + { + Pipe_Freeze(); + return; + } + + LEDs_SetAllLEDs(LEDMASK_USB_BUSY); + + puts_P(PSTR("DATA IN\r\n")); + + uint16_t PacketSize; + if ((ErrorCode = RNDIS_GetPacketSize(&PacketSize)) != HOST_SENDCONTROL_Successful) + { + printf_P(PSTR(ESC_FG_RED "Packet Reception Error.\r\n" + " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); + } + else if (PacketSize > 2048) + { + printf_P(PSTR(ESC_FG_RED "Packet of Size %d Too Large.\r\n" ESC_FG_WHITE), PacketSize); + Pipe_Discard_Stream(PacketSize); + } + else + { + uint8_t PacketBuffer[PacketSize]; + + Pipe_Read_Stream_LE(&PacketBuffer, PacketSize); + + printf("***PACKET (Size %d)***\r\n", PacketSize); + for (uint16_t i = 0; i < PacketSize; i++) + { + printf("%02x ", PacketBuffer[i]); + } + printf("\r\n\r\n"); + } + + LEDs_SetAllLEDs(LEDMASK_USB_READY); + + Pipe_ClearIN(); + Pipe_Freeze(); +} + /** Task to set the configuration of the attached device after it has been enumerated, and to read in * data received from the attached RNDIS device and print it to the serial port. */ @@ -181,7 +229,8 @@ void RNDIS_Host_Task(void) printf_P(PSTR("Device Max Transfer Size: %lu bytes.\r\n"), InitMessageResponse.MaxTransferSize); - uint32_t PacketFilter = 0xFFFFFFFF; + /* We set the default filter to only receive packets we would be interested in */ + uint32_t PacketFilter = (RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST | RNDIS_PACKET_TYPE_ALL_MULTICAST); if ((ErrorCode = RNDIS_SetRNDISProperty(OID_GEN_CURRENT_PACKET_FILTER, &PacketFilter, sizeof(PacketFilter))) != HOST_SENDCONTROL_Successful) { @@ -195,13 +244,32 @@ void RNDIS_Host_Task(void) USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } + + uint32_t VendorID; + if ((ErrorCode = RNDIS_QueryRNDISProperty(OID_GEN_VENDOR_ID, + &VendorID, sizeof(VendorID))) != HOST_SENDCONTROL_Successful) + { + printf_P(PSTR(ESC_FG_RED "Error Getting Vendor ID.\r\n" + " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); + + /* Indicate error via status LEDs */ + LEDs_SetAllLEDs(LEDMASK_USB_ERROR); + + /* Wait until USB device disconnected */ + USB_HostState = HOST_STATE_WaitForDeviceRemoval; + break; + } + + printf_P(PSTR("Device Vendor ID: 0x%08X\r\n"), VendorID); puts_P(PSTR("RNDIS Device Enumerated.\r\n")); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: - + PrintIncommingPackets(); + break; } } + diff --git a/Demos/Host/Incomplete/RNDISEthernetHost/RNDISEthernetHost.h b/Demos/Host/Incomplete/RNDISEthernetHost/RNDISEthernetHost.h index caca9c60db..47e5c24d15 100644 --- a/Demos/Host/Incomplete/RNDISEthernetHost/RNDISEthernetHost.h +++ b/Demos/Host/Incomplete/RNDISEthernetHost/RNDISEthernetHost.h @@ -66,8 +66,25 @@ /** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */ #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3) + /** LED mask for the library LED driver, to indicate that the USB interface is busy. */ + #define LEDMASK_USB_BUSY (LEDS_LED2) + + /* Type Defines: */ + /** Type define for a RNDIS notification message, for transmission to the RNDIS host via the notification + * Endpoint. + */ + typedef struct + { + uint8_t bmRequestType; /**< Notification type, a mask of values from SrdRequestType.h */ + uint8_t bNotification; /**< Notification index, indicating what the RNDIS notification relates to */ + uint16_t wValue; /**< Two byte notification value parameter */ + uint16_t wIndex; /**< Two byte notification index parameter */ + uint16_t wLength; /**< Size of data payload following the notification header */ + } USB_Notification_t; + /* Function Prototypes: */ void SetupHardware(void); + void PrintIncommingPackets(void); void RNDIS_Host_Task(void); void EVENT_USB_Host_HostError(const uint8_t ErrorCode);