3      Copyright (C) Dean Camera, 2021. 
   5   dean [at] fourwalledcubicle [dot] com 
  10   Copyright 2021  Dean Camera (dean [at] fourwalledcubicle [dot] com) 
  12   Permission to use, copy, modify, distribute, and sell this 
  13   software and its documentation for any purpose is hereby granted 
  14   without fee, provided that the above copyright notice appear in 
  15   all copies and that both that the copyright notice and this 
  16   permission notice and warranty disclaimer appear in supporting 
  17   documentation, and that the name of the author not be used in 
  18   advertising or publicity pertaining to distribution of the 
  19   software without specific, written prior permission. 
  21   The author disclaims all warranties with regard to this 
  22   software, including all implied warranties of merchantability 
  23   and fitness.  In no event shall the author be liable for any 
  24   special, indirect or consequential damages or any damages 
  25   whatsoever resulting from loss of use, data or profits, whether 
  26   in an action of contract, negligence or other tortious action, 
  27   arising out of or in connection with the use or performance of 
  31 #define  __INCLUDE_FROM_USB_DRIVER 
  32 #include "../../Core/USBMode.h" 
  34 #if defined(USB_CAN_BE_DEVICE) 
  36 #define  __INCLUDE_FROM_RNDIS_DRIVER 
  37 #define  __INCLUDE_FROM_RNDIS_DEVICE_C 
  38 #include "RNDISClassDevice.h" 
  40 static const uint32_t PROGMEM AdapterSupportedOIDList
[]  = 
  42                 CPU_TO_LE32(OID_GEN_SUPPORTED_LIST
), 
  43                 CPU_TO_LE32(OID_GEN_PHYSICAL_MEDIUM
), 
  44                 CPU_TO_LE32(OID_GEN_HARDWARE_STATUS
), 
  45                 CPU_TO_LE32(OID_GEN_MEDIA_SUPPORTED
), 
  46                 CPU_TO_LE32(OID_GEN_MEDIA_IN_USE
), 
  47                 CPU_TO_LE32(OID_GEN_MAXIMUM_FRAME_SIZE
), 
  48                 CPU_TO_LE32(OID_GEN_MAXIMUM_TOTAL_SIZE
), 
  49                 CPU_TO_LE32(OID_GEN_LINK_SPEED
), 
  50                 CPU_TO_LE32(OID_GEN_TRANSMIT_BLOCK_SIZE
), 
  51                 CPU_TO_LE32(OID_GEN_RECEIVE_BLOCK_SIZE
), 
  52                 CPU_TO_LE32(OID_GEN_VENDOR_ID
), 
  53                 CPU_TO_LE32(OID_GEN_VENDOR_DESCRIPTION
), 
  54                 CPU_TO_LE32(OID_GEN_CURRENT_PACKET_FILTER
), 
  55                 CPU_TO_LE32(OID_GEN_MAXIMUM_TOTAL_SIZE
), 
  56                 CPU_TO_LE32(OID_GEN_MEDIA_CONNECT_STATUS
), 
  57                 CPU_TO_LE32(OID_GEN_XMIT_OK
), 
  58                 CPU_TO_LE32(OID_GEN_RCV_OK
), 
  59                 CPU_TO_LE32(OID_GEN_XMIT_ERROR
), 
  60                 CPU_TO_LE32(OID_GEN_RCV_ERROR
), 
  61                 CPU_TO_LE32(OID_GEN_RCV_NO_BUFFER
), 
  62                 CPU_TO_LE32(OID_802_3_PERMANENT_ADDRESS
), 
  63                 CPU_TO_LE32(OID_802_3_CURRENT_ADDRESS
), 
  64                 CPU_TO_LE32(OID_802_3_MULTICAST_LIST
), 
  65                 CPU_TO_LE32(OID_802_3_MAXIMUM_LIST_SIZE
), 
  66                 CPU_TO_LE32(OID_802_3_RCV_ERROR_ALIGNMENT
), 
  67                 CPU_TO_LE32(OID_802_3_XMIT_ONE_COLLISION
), 
  68                 CPU_TO_LE32(OID_802_3_XMIT_MORE_COLLISIONS
), 
  71 void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
) 
  73         if (!(Endpoint_IsSETUPReceived())) 
  76         if (USB_ControlRequest
.wIndex 
!= RNDISInterfaceInfo
->Config
.ControlInterfaceNumber
) 
  79         switch (USB_ControlRequest
.bRequest
) 
  81                 case RNDIS_REQ_SendEncapsulatedCommand
: 
  82                         if (USB_ControlRequest
.bmRequestType 
== (REQDIR_HOSTTODEVICE 
| REQTYPE_CLASS 
| REQREC_INTERFACE
)) 
  84                                 if (USB_ControlRequest
.wLength 
>= sizeof(RNDISInterfaceInfo
->Config
.MessageBuffer
)) 
  87                                 Endpoint_ClearSETUP(); 
  88                                 Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo
->Config
.MessageBuffer
, USB_ControlRequest
.wLength
); 
  91                                 RNDIS_Device_ProcessRNDISControlMessage(RNDISInterfaceInfo
); 
  95                 case RNDIS_REQ_GetEncapsulatedResponse
: 
  96                         if (USB_ControlRequest
.bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_CLASS 
| REQREC_INTERFACE
)) 
  98                                 RNDIS_Message_Header_t
* MessageHeader 
= (RNDIS_Message_Header_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 100                                 if (!(MessageHeader
->MessageLength
)) 
 102                                         RNDISInterfaceInfo
->Config
.MessageBuffer
[0] = 0; 
 103                                         MessageHeader
->MessageLength                
= CPU_TO_LE32(1); 
 106                                 Endpoint_ClearSETUP(); 
 107                                 Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo
->Config
.MessageBuffer
, le32_to_cpu(MessageHeader
->MessageLength
)); 
 110                                 MessageHeader
->MessageLength 
= CPU_TO_LE32(0); 
 117 bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
) 
 119         memset(&RNDISInterfaceInfo
->State
, 0x00, sizeof(RNDISInterfaceInfo
->State
)); 
 121         RNDISInterfaceInfo
->Config
.DataINEndpoint
.Type       
= EP_TYPE_BULK
; 
 122         RNDISInterfaceInfo
->Config
.DataOUTEndpoint
.Type      
= EP_TYPE_BULK
; 
 123         RNDISInterfaceInfo
->Config
.NotificationEndpoint
.Type 
= EP_TYPE_INTERRUPT
; 
 125         if (RNDISInterfaceInfo
->Config
.MessageBuffer 
== NULL
) 
 128         if (RNDISInterfaceInfo
->Config
.MessageBufferLength 
< RNDIS_DEVICE_MIN_MESSAGE_BUFFER_LENGTH
) 
 131         if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo
->Config
.DataINEndpoint
, 1))) 
 134         if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo
->Config
.DataOUTEndpoint
, 1))) 
 137         if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo
->Config
.NotificationEndpoint
, 1))) 
 143 void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
) 
 145         if (USB_DeviceState 
!= DEVICE_STATE_Configured
) 
 148         Endpoint_SelectEndpoint(RNDISInterfaceInfo
->Config
.NotificationEndpoint
.Address
); 
 150         if (Endpoint_IsINReady() && RNDISInterfaceInfo
->State
.ResponseReady
) 
 152                 USB_Request_Header_t Notification 
= (USB_Request_Header_t
) 
 154                                 .bmRequestType 
= (REQDIR_DEVICETOHOST 
| REQTYPE_CLASS 
| REQREC_INTERFACE
), 
 155                                 .bRequest      
= RNDIS_NOTIF_ResponseAvailable
, 
 156                                 .wValue        
= CPU_TO_LE16(0), 
 157                                 .wIndex        
= CPU_TO_LE16(0), 
 158                                 .wLength       
= CPU_TO_LE16(0), 
 161                 Endpoint_Write_Stream_LE(&Notification
, sizeof(USB_Request_Header_t
), NULL
); 
 165                 RNDISInterfaceInfo
->State
.ResponseReady 
= false; 
 169 void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
) 
 171         /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of 
 172                  this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */ 
 174         RNDIS_Message_Header_t
* MessageHeader 
= (RNDIS_Message_Header_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 176         switch (le32_to_cpu(MessageHeader
->MessageType
)) 
 178                 case REMOTE_NDIS_INITIALIZE_MSG
: 
 179                         RNDISInterfaceInfo
->State
.ResponseReady     
= true; 
 181                         RNDIS_Initialize_Message_t
*  INITIALIZE_Message  
= 
 182                                        (RNDIS_Initialize_Message_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 183                         RNDIS_Initialize_Complete_t
* INITIALIZE_Response 
= 
 184                                        (RNDIS_Initialize_Complete_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 186                         INITIALIZE_Response
->MessageType            
= CPU_TO_LE32(REMOTE_NDIS_INITIALIZE_CMPLT
); 
 187                         INITIALIZE_Response
->MessageLength          
= CPU_TO_LE32(sizeof(RNDIS_Initialize_Complete_t
)); 
 188                         INITIALIZE_Response
->RequestId              
= INITIALIZE_Message
->RequestId
; 
 189                         INITIALIZE_Response
->Status                 
= CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS
); 
 191                         INITIALIZE_Response
->MajorVersion           
= CPU_TO_LE32(REMOTE_NDIS_VERSION_MAJOR
); 
 192                         INITIALIZE_Response
->MinorVersion           
= CPU_TO_LE32(REMOTE_NDIS_VERSION_MINOR
); 
 193                         INITIALIZE_Response
->DeviceFlags            
= CPU_TO_LE32(REMOTE_NDIS_DF_CONNECTIONLESS
); 
 194                         INITIALIZE_Response
->Medium                 
= CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3
); 
 195                         INITIALIZE_Response
->MaxPacketsPerTransfer  
= CPU_TO_LE32(1); 
 196                         INITIALIZE_Response
->MaxTransferSize        
= CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t
) + ETHERNET_FRAME_SIZE_MAX
); 
 197                         INITIALIZE_Response
->PacketAlignmentFactor  
= CPU_TO_LE32(0); 
 198                         INITIALIZE_Response
->AFListOffset           
= CPU_TO_LE32(0); 
 199                         INITIALIZE_Response
->AFListSize             
= CPU_TO_LE32(0); 
 201                         RNDISInterfaceInfo
->State
.CurrRNDISState    
= RNDIS_Initialized
; 
 203                 case REMOTE_NDIS_HALT_MSG
: 
 204                         RNDISInterfaceInfo
->State
.ResponseReady     
= false; 
 206                         MessageHeader
->MessageLength                
= CPU_TO_LE32(0); 
 208                         RNDISInterfaceInfo
->State
.CurrRNDISState    
= RNDIS_Uninitialized
; 
 210                 case REMOTE_NDIS_QUERY_MSG
: 
 211                         RNDISInterfaceInfo
->State
.ResponseReady     
= true; 
 213                         RNDIS_Query_Message_t
*  QUERY_Message       
= (RNDIS_Query_Message_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 214                         RNDIS_Query_Complete_t
* QUERY_Response      
= (RNDIS_Query_Complete_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 215                         uint32_t                Query_Oid           
= CPU_TO_LE32(QUERY_Message
->Oid
); 
 217                         void*    QueryData    
= &RNDISInterfaceInfo
->Config
.MessageBuffer
[sizeof(RNDIS_Message_Header_t
) + 
 218                                                                                           le32_to_cpu(QUERY_Message
->InformationBufferOffset
)]; 
 219                         void*    ResponseData 
= &RNDISInterfaceInfo
->Config
.MessageBuffer
[sizeof(RNDIS_Query_Complete_t
)]; 
 220                         uint16_t ResponseSize
; 
 222                         QUERY_Response
->MessageType                 
= CPU_TO_LE32(REMOTE_NDIS_QUERY_CMPLT
); 
 224                         if (RNDIS_Device_ProcessNDISQuery(RNDISInterfaceInfo
, Query_Oid
, QueryData
, le32_to_cpu(QUERY_Message
->InformationBufferLength
), 
 225                                                           ResponseData
, &ResponseSize
)) 
 227                                 QUERY_Response
->Status                  
= CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS
); 
 228                                 QUERY_Response
->MessageLength           
= cpu_to_le32(sizeof(RNDIS_Query_Complete_t
) + ResponseSize
); 
 230                                 QUERY_Response
->InformationBufferLength 
= CPU_TO_LE32(ResponseSize
); 
 231                                 QUERY_Response
->InformationBufferOffset 
= CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t
) - sizeof(RNDIS_Message_Header_t
)); 
 235                                 QUERY_Response
->Status                  
= CPU_TO_LE32(REMOTE_NDIS_STATUS_NOT_SUPPORTED
); 
 236                                 QUERY_Response
->MessageLength           
= CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t
)); 
 238                                 QUERY_Response
->InformationBufferLength 
= CPU_TO_LE32(0); 
 239                                 QUERY_Response
->InformationBufferOffset 
= CPU_TO_LE32(0); 
 243                 case REMOTE_NDIS_SET_MSG
: 
 244                         RNDISInterfaceInfo
->State
.ResponseReady     
= true; 
 246                         RNDIS_Set_Message_t
*  SET_Message           
= (RNDIS_Set_Message_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 247                         RNDIS_Set_Complete_t
* SET_Response          
= (RNDIS_Set_Complete_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 248                         uint32_t              SET_Oid               
= le32_to_cpu(SET_Message
->Oid
); 
 250                         SET_Response
->MessageType                   
= CPU_TO_LE32(REMOTE_NDIS_SET_CMPLT
); 
 251                         SET_Response
->MessageLength                 
= CPU_TO_LE32(sizeof(RNDIS_Set_Complete_t
)); 
 252                         SET_Response
->RequestId                     
= SET_Message
->RequestId
; 
 254                         void* SetData 
= &RNDISInterfaceInfo
->Config
.MessageBuffer
[sizeof(RNDIS_Message_Header_t
) + 
 255                                                                                       le32_to_cpu(SET_Message
->InformationBufferOffset
)]; 
 257                         SET_Response
->Status 
= RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo
, SET_Oid
, SetData
, 
 258                                                                            le32_to_cpu(SET_Message
->InformationBufferLength
)) ?
 
 259                                                                            REMOTE_NDIS_STATUS_SUCCESS 
: REMOTE_NDIS_STATUS_NOT_SUPPORTED
; 
 261                 case REMOTE_NDIS_RESET_MSG
: 
 262                         RNDISInterfaceInfo
->State
.ResponseReady     
= true; 
 264                         RNDIS_Reset_Complete_t
* RESET_Response      
= (RNDIS_Reset_Complete_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 266                         RESET_Response
->MessageType                 
= CPU_TO_LE32(REMOTE_NDIS_RESET_CMPLT
); 
 267                         RESET_Response
->MessageLength               
= CPU_TO_LE32(sizeof(RNDIS_Reset_Complete_t
)); 
 268                         RESET_Response
->Status                      
= CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS
); 
 269                         RESET_Response
->AddressingReset             
= CPU_TO_LE32(0); 
 272                 case REMOTE_NDIS_KEEPALIVE_MSG
: 
 273                         RNDISInterfaceInfo
->State
.ResponseReady     
= true; 
 275                         RNDIS_KeepAlive_Message_t
*  KEEPALIVE_Message  
= 
 276                                         (RNDIS_KeepAlive_Message_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 277                         RNDIS_KeepAlive_Complete_t
* KEEPALIVE_Response 
= 
 278                                         (RNDIS_KeepAlive_Complete_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 280                         KEEPALIVE_Response
->MessageType             
= CPU_TO_LE32(REMOTE_NDIS_KEEPALIVE_CMPLT
); 
 281                         KEEPALIVE_Response
->MessageLength           
= CPU_TO_LE32(sizeof(RNDIS_KeepAlive_Complete_t
)); 
 282                         KEEPALIVE_Response
->RequestId               
= KEEPALIVE_Message
->RequestId
; 
 283                         KEEPALIVE_Response
->Status                  
= CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS
); 
 289 static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
, 
 291                                           void* const QueryData
, 
 292                                           const uint16_t QuerySize
, 
 294                                           uint16_t* const ResponseSize
) 
 301                 case OID_GEN_SUPPORTED_LIST
: 
 302                         *ResponseSize 
= sizeof(AdapterSupportedOIDList
); 
 304                         memcpy_P(ResponseData
, AdapterSupportedOIDList
, sizeof(AdapterSupportedOIDList
)); 
 307                 case OID_GEN_PHYSICAL_MEDIUM
: 
 308                         *ResponseSize 
= sizeof(uint32_t); 
 310                         /* Indicate that the device is a true ethernet link */ 
 311                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(0); 
 314                 case OID_GEN_HARDWARE_STATUS
: 
 315                         *ResponseSize 
= sizeof(uint32_t); 
 317                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(NDIS_HardwareStatus_Ready
); 
 320                 case OID_GEN_MEDIA_SUPPORTED
: 
 321                 case OID_GEN_MEDIA_IN_USE
: 
 322                         *ResponseSize 
= sizeof(uint32_t); 
 324                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3
); 
 327                 case OID_GEN_VENDOR_ID
: 
 328                         *ResponseSize 
= sizeof(uint32_t); 
 330                         /* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */ 
 331                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(0x00FFFFFF); 
 334                 case OID_GEN_MAXIMUM_FRAME_SIZE
: 
 335                 case OID_GEN_TRANSMIT_BLOCK_SIZE
: 
 336                 case OID_GEN_RECEIVE_BLOCK_SIZE
: 
 337                         *ResponseSize 
= sizeof(uint32_t); 
 339                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(ETHERNET_FRAME_SIZE_MAX
); 
 342                 case OID_GEN_VENDOR_DESCRIPTION
: 
 343                         *ResponseSize 
= (strlen(RNDISInterfaceInfo
->Config
.AdapterVendorDescription
) + 1); 
 345                         memcpy(ResponseData
, RNDISInterfaceInfo
->Config
.AdapterVendorDescription
, *ResponseSize
); 
 348                 case OID_GEN_MEDIA_CONNECT_STATUS
: 
 349                         *ResponseSize 
= sizeof(uint32_t); 
 351                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(REMOTE_NDIS_MEDIA_STATE_CONNECTED
); 
 354                 case OID_GEN_LINK_SPEED
: 
 355                         *ResponseSize 
= sizeof(uint32_t); 
 357                         /* Indicate 10Mb/s link speed */ 
 358                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(100000); 
 361                 case OID_802_3_PERMANENT_ADDRESS
: 
 362                 case OID_802_3_CURRENT_ADDRESS
: 
 363                         *ResponseSize 
= sizeof(MAC_Address_t
); 
 365                         memcpy(ResponseData
, &RNDISInterfaceInfo
->Config
.AdapterMACAddress
, sizeof(MAC_Address_t
)); 
 368                 case OID_802_3_MAXIMUM_LIST_SIZE
: 
 369                         *ResponseSize 
= sizeof(uint32_t); 
 371                         /* Indicate only one multicast address supported */ 
 372                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(1); 
 375                 case OID_GEN_CURRENT_PACKET_FILTER
: 
 376                         *ResponseSize 
= sizeof(uint32_t); 
 378                         *((uint32_t*)ResponseData
) = cpu_to_le32(RNDISInterfaceInfo
->State
.CurrPacketFilter
); 
 381                 case OID_GEN_XMIT_OK
: 
 383                 case OID_GEN_XMIT_ERROR
: 
 384                 case OID_GEN_RCV_ERROR
: 
 385                 case OID_GEN_RCV_NO_BUFFER
: 
 386                 case OID_802_3_RCV_ERROR_ALIGNMENT
: 
 387                 case OID_802_3_XMIT_ONE_COLLISION
: 
 388                 case OID_802_3_XMIT_MORE_COLLISIONS
: 
 389                         *ResponseSize 
= sizeof(uint32_t); 
 391                         /* Unused statistic OIDs - always return 0 for each */ 
 392                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(0); 
 395                 case OID_GEN_MAXIMUM_TOTAL_SIZE
: 
 396                         *ResponseSize 
= sizeof(uint32_t); 
 398                         /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */ 
 399                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(RNDISInterfaceInfo
->Config
.MessageBufferLength 
+ ETHERNET_FRAME_SIZE_MAX
); 
 407 static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
, 
 410                                         const uint16_t SetSize
) 
 416                 case OID_GEN_CURRENT_PACKET_FILTER
: 
 417                         RNDISInterfaceInfo
->State
.CurrPacketFilter 
= le32_to_cpu(*((uint32_t*)SetData
)); 
 418                         RNDISInterfaceInfo
->State
.CurrRNDISState   
= (RNDISInterfaceInfo
->State
.CurrPacketFilter
) ? RNDIS_Data_Initialized 
: RNDIS_Initialized
; 
 421                 case OID_802_3_MULTICAST_LIST
: 
 422                         /* Do nothing - throw away the value from the host as it is unused */ 
 430 bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
) 
 432         if ((USB_DeviceState 
!= DEVICE_STATE_Configured
) || 
 433             (RNDISInterfaceInfo
->State
.CurrRNDISState 
!= RNDIS_Data_Initialized
)) 
 438         Endpoint_SelectEndpoint(RNDISInterfaceInfo
->Config
.DataOUTEndpoint
.Address
); 
 439         return Endpoint_IsOUTReceived(); 
 442 uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
, 
 444                                 const uint16_t BufferSize
, 
 445                                 uint16_t* PacketLength
) 
 447         if ((USB_DeviceState 
!= DEVICE_STATE_Configured
) || 
 448             (RNDISInterfaceInfo
->State
.CurrRNDISState 
!= RNDIS_Data_Initialized
)) 
 450                 return ENDPOINT_RWSTREAM_DeviceDisconnected
; 
 455         Endpoint_SelectEndpoint(RNDISInterfaceInfo
->Config
.DataOUTEndpoint
.Address
); 
 457         if (!(Endpoint_IsOUTReceived())) 
 458                 return ENDPOINT_RWSTREAM_NoError
; 
 460         RNDIS_Packet_Message_t RNDISPacketHeader
; 
 461         Endpoint_Read_Stream_LE(&RNDISPacketHeader
, sizeof(RNDIS_Packet_Message_t
), NULL
); 
 463         if (le32_to_cpu(RNDISPacketHeader
.DataLength
) > ETHERNET_FRAME_SIZE_MAX
) 
 465                 Endpoint_StallTransaction(); 
 467                 return RNDIS_ERROR_LOGICAL_CMD_FAILED
; 
 470         const size_t ExpectedLength 
= (uint16_t)le32_to_cpu(RNDISPacketHeader
.DataLength
); 
 472         if (ExpectedLength 
> BufferSize
) 
 473                 *PacketLength 
= BufferSize
; 
 475                 *PacketLength 
= ExpectedLength
; 
 477         Endpoint_Read_Stream_LE(Buffer
, *PacketLength
, NULL
); 
 478         if (ExpectedLength 
> BufferSize
) 
 479                 Endpoint_Discard_Stream(ExpectedLength 
- BufferSize
, NULL
); 
 482         return ENDPOINT_RWSTREAM_NoError
; 
 485 uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
, 
 487                                 const uint16_t PacketLength
) 
 491         if ((USB_DeviceState 
!= DEVICE_STATE_Configured
) || 
 492             (RNDISInterfaceInfo
->State
.CurrRNDISState 
!= RNDIS_Data_Initialized
)) 
 494                 return ENDPOINT_RWSTREAM_DeviceDisconnected
; 
 497         Endpoint_SelectEndpoint(RNDISInterfaceInfo
->Config
.DataINEndpoint
.Address
); 
 499         if ((ErrorCode 
= Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError
) 
 502         RNDIS_Packet_Message_t RNDISPacketHeader
; 
 504         memset(&RNDISPacketHeader
, 0, sizeof(RNDIS_Packet_Message_t
)); 
 506         RNDISPacketHeader
.MessageType   
= CPU_TO_LE32(REMOTE_NDIS_PACKET_MSG
); 
 507         RNDISPacketHeader
.MessageLength 
= cpu_to_le32(sizeof(RNDIS_Packet_Message_t
) + PacketLength
); 
 508         RNDISPacketHeader
.DataOffset    
= CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t
) - sizeof(RNDIS_Message_Header_t
)); 
 509         RNDISPacketHeader
.DataLength    
= cpu_to_le32(PacketLength
); 
 511         Endpoint_Write_Stream_LE(&RNDISPacketHeader
, sizeof(RNDIS_Packet_Message_t
), NULL
); 
 512         Endpoint_Write_Stream_LE(Buffer
, PacketLength
, NULL
); 
 515         return ENDPOINT_RWSTREAM_NoError
;