3      Copyright (C) Dean Camera, 2015. 
   5   dean [at] fourwalledcubicle [dot] com 
  10   Copyright 2015  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                                 Endpoint_ClearSETUP(); 
  85                                 Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo
->Config
.MessageBuffer
, USB_ControlRequest
.wLength
); 
  88                                 RNDIS_Device_ProcessRNDISControlMessage(RNDISInterfaceInfo
); 
  92                 case RNDIS_REQ_GetEncapsulatedResponse
: 
  93                         if (USB_ControlRequest
.bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_CLASS 
| REQREC_INTERFACE
)) 
  95                                 RNDIS_Message_Header_t
* MessageHeader 
= (RNDIS_Message_Header_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
  97                                 if (!(MessageHeader
->MessageLength
)) 
  99                                         RNDISInterfaceInfo
->Config
.MessageBuffer
[0] = 0; 
 100                                         MessageHeader
->MessageLength                
= CPU_TO_LE32(1); 
 103                                 Endpoint_ClearSETUP(); 
 104                                 Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo
->Config
.MessageBuffer
, le32_to_cpu(MessageHeader
->MessageLength
)); 
 107                                 MessageHeader
->MessageLength 
= CPU_TO_LE32(0); 
 114 bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
) 
 116         memset(&RNDISInterfaceInfo
->State
, 0x00, sizeof(RNDISInterfaceInfo
->State
)); 
 118         RNDISInterfaceInfo
->Config
.DataINEndpoint
.Type       
= EP_TYPE_BULK
; 
 119         RNDISInterfaceInfo
->Config
.DataOUTEndpoint
.Type      
= EP_TYPE_BULK
; 
 120         RNDISInterfaceInfo
->Config
.NotificationEndpoint
.Type 
= EP_TYPE_INTERRUPT
; 
 122         if (RNDISInterfaceInfo
->Config
.MessageBuffer 
== NULL
) 
 125         if (RNDISInterfaceInfo
->Config
.MessageBufferLength 
< RNDIS_DEVICE_MIN_MESSAGE_BUFFER_LENGTH
) 
 128         if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo
->Config
.DataINEndpoint
, 1))) 
 131         if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo
->Config
.DataOUTEndpoint
, 1))) 
 134         if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo
->Config
.NotificationEndpoint
, 1))) 
 140 void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
) 
 142         if (USB_DeviceState 
!= DEVICE_STATE_Configured
) 
 145         Endpoint_SelectEndpoint(RNDISInterfaceInfo
->Config
.NotificationEndpoint
.Address
); 
 147         if (Endpoint_IsINReady() && RNDISInterfaceInfo
->State
.ResponseReady
) 
 149                 USB_Request_Header_t Notification 
= (USB_Request_Header_t
) 
 151                                 .bmRequestType 
= (REQDIR_DEVICETOHOST 
| REQTYPE_CLASS 
| REQREC_INTERFACE
), 
 152                                 .bRequest      
= RNDIS_NOTIF_ResponseAvailable
, 
 153                                 .wValue        
= CPU_TO_LE16(0), 
 154                                 .wIndex        
= CPU_TO_LE16(0), 
 155                                 .wLength       
= CPU_TO_LE16(0), 
 158                 Endpoint_Write_Stream_LE(&Notification
, sizeof(USB_Request_Header_t
), NULL
); 
 162                 RNDISInterfaceInfo
->State
.ResponseReady 
= false; 
 166 void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
) 
 168         /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of 
 169                  this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */ 
 171         RNDIS_Message_Header_t
* MessageHeader 
= (RNDIS_Message_Header_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 173         switch (le32_to_cpu(MessageHeader
->MessageType
)) 
 175                 case REMOTE_NDIS_INITIALIZE_MSG
: 
 176                         RNDISInterfaceInfo
->State
.ResponseReady     
= true; 
 178                         RNDIS_Initialize_Message_t
*  INITIALIZE_Message  
= 
 179                                        (RNDIS_Initialize_Message_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 180                         RNDIS_Initialize_Complete_t
* INITIALIZE_Response 
= 
 181                                        (RNDIS_Initialize_Complete_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 183                         INITIALIZE_Response
->MessageType            
= CPU_TO_LE32(REMOTE_NDIS_INITIALIZE_CMPLT
); 
 184                         INITIALIZE_Response
->MessageLength          
= CPU_TO_LE32(sizeof(RNDIS_Initialize_Complete_t
)); 
 185                         INITIALIZE_Response
->RequestId              
= INITIALIZE_Message
->RequestId
; 
 186                         INITIALIZE_Response
->Status                 
= CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS
); 
 188                         INITIALIZE_Response
->MajorVersion           
= CPU_TO_LE32(REMOTE_NDIS_VERSION_MAJOR
); 
 189                         INITIALIZE_Response
->MinorVersion           
= CPU_TO_LE32(REMOTE_NDIS_VERSION_MINOR
); 
 190                         INITIALIZE_Response
->DeviceFlags            
= CPU_TO_LE32(REMOTE_NDIS_DF_CONNECTIONLESS
); 
 191                         INITIALIZE_Response
->Medium                 
= CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3
); 
 192                         INITIALIZE_Response
->MaxPacketsPerTransfer  
= CPU_TO_LE32(1); 
 193                         INITIALIZE_Response
->MaxTransferSize        
= CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t
) + ETHERNET_FRAME_SIZE_MAX
); 
 194                         INITIALIZE_Response
->PacketAlignmentFactor  
= CPU_TO_LE32(0); 
 195                         INITIALIZE_Response
->AFListOffset           
= CPU_TO_LE32(0); 
 196                         INITIALIZE_Response
->AFListSize             
= CPU_TO_LE32(0); 
 198                         RNDISInterfaceInfo
->State
.CurrRNDISState    
= RNDIS_Initialized
; 
 200                 case REMOTE_NDIS_HALT_MSG
: 
 201                         RNDISInterfaceInfo
->State
.ResponseReady     
= false; 
 203                         MessageHeader
->MessageLength                
= CPU_TO_LE32(0); 
 205                         RNDISInterfaceInfo
->State
.CurrRNDISState    
= RNDIS_Uninitialized
; 
 207                 case REMOTE_NDIS_QUERY_MSG
: 
 208                         RNDISInterfaceInfo
->State
.ResponseReady     
= true; 
 210                         RNDIS_Query_Message_t
*  QUERY_Message       
= (RNDIS_Query_Message_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 211                         RNDIS_Query_Complete_t
* QUERY_Response      
= (RNDIS_Query_Complete_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 212                         uint32_t                Query_Oid           
= CPU_TO_LE32(QUERY_Message
->Oid
); 
 214                         void*    QueryData    
= &RNDISInterfaceInfo
->Config
.MessageBuffer
[sizeof(RNDIS_Message_Header_t
) + 
 215                                                                                           le32_to_cpu(QUERY_Message
->InformationBufferOffset
)]; 
 216                         void*    ResponseData 
= &RNDISInterfaceInfo
->Config
.MessageBuffer
[sizeof(RNDIS_Query_Complete_t
)]; 
 217                         uint16_t ResponseSize
; 
 219                         QUERY_Response
->MessageType                 
= CPU_TO_LE32(REMOTE_NDIS_QUERY_CMPLT
); 
 221                         if (RNDIS_Device_ProcessNDISQuery(RNDISInterfaceInfo
, Query_Oid
, QueryData
, le32_to_cpu(QUERY_Message
->InformationBufferLength
), 
 222                                                           ResponseData
, &ResponseSize
)) 
 224                                 QUERY_Response
->Status                  
= CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS
); 
 225                                 QUERY_Response
->MessageLength           
= cpu_to_le32(sizeof(RNDIS_Query_Complete_t
) + ResponseSize
); 
 227                                 QUERY_Response
->InformationBufferLength 
= CPU_TO_LE32(ResponseSize
); 
 228                                 QUERY_Response
->InformationBufferOffset 
= CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t
) - sizeof(RNDIS_Message_Header_t
)); 
 232                                 QUERY_Response
->Status                  
= CPU_TO_LE32(REMOTE_NDIS_STATUS_NOT_SUPPORTED
); 
 233                                 QUERY_Response
->MessageLength           
= CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t
)); 
 235                                 QUERY_Response
->InformationBufferLength 
= CPU_TO_LE32(0); 
 236                                 QUERY_Response
->InformationBufferOffset 
= CPU_TO_LE32(0); 
 240                 case REMOTE_NDIS_SET_MSG
: 
 241                         RNDISInterfaceInfo
->State
.ResponseReady     
= true; 
 243                         RNDIS_Set_Message_t
*  SET_Message           
= (RNDIS_Set_Message_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 244                         RNDIS_Set_Complete_t
* SET_Response          
= (RNDIS_Set_Complete_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 245                         uint32_t              SET_Oid               
= le32_to_cpu(SET_Message
->Oid
); 
 247                         SET_Response
->MessageType                   
= CPU_TO_LE32(REMOTE_NDIS_SET_CMPLT
); 
 248                         SET_Response
->MessageLength                 
= CPU_TO_LE32(sizeof(RNDIS_Set_Complete_t
)); 
 249                         SET_Response
->RequestId                     
= SET_Message
->RequestId
; 
 251                         void* SetData 
= &RNDISInterfaceInfo
->Config
.MessageBuffer
[sizeof(RNDIS_Message_Header_t
) + 
 252                                                                                       le32_to_cpu(SET_Message
->InformationBufferOffset
)]; 
 254                         SET_Response
->Status 
= RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo
, SET_Oid
, SetData
, 
 255                                                                            le32_to_cpu(SET_Message
->InformationBufferLength
)) ?
 
 256                                                                            REMOTE_NDIS_STATUS_SUCCESS 
: REMOTE_NDIS_STATUS_NOT_SUPPORTED
; 
 258                 case REMOTE_NDIS_RESET_MSG
: 
 259                         RNDISInterfaceInfo
->State
.ResponseReady     
= true; 
 261                         RNDIS_Reset_Complete_t
* RESET_Response      
= (RNDIS_Reset_Complete_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 263                         RESET_Response
->MessageType                 
= CPU_TO_LE32(REMOTE_NDIS_RESET_CMPLT
); 
 264                         RESET_Response
->MessageLength               
= CPU_TO_LE32(sizeof(RNDIS_Reset_Complete_t
)); 
 265                         RESET_Response
->Status                      
= CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS
); 
 266                         RESET_Response
->AddressingReset             
= CPU_TO_LE32(0); 
 269                 case REMOTE_NDIS_KEEPALIVE_MSG
: 
 270                         RNDISInterfaceInfo
->State
.ResponseReady     
= true; 
 272                         RNDIS_KeepAlive_Message_t
*  KEEPALIVE_Message  
= 
 273                                         (RNDIS_KeepAlive_Message_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 274                         RNDIS_KeepAlive_Complete_t
* KEEPALIVE_Response 
= 
 275                                         (RNDIS_KeepAlive_Complete_t
*)RNDISInterfaceInfo
->Config
.MessageBuffer
; 
 277                         KEEPALIVE_Response
->MessageType             
= CPU_TO_LE32(REMOTE_NDIS_KEEPALIVE_CMPLT
); 
 278                         KEEPALIVE_Response
->MessageLength           
= CPU_TO_LE32(sizeof(RNDIS_KeepAlive_Complete_t
)); 
 279                         KEEPALIVE_Response
->RequestId               
= KEEPALIVE_Message
->RequestId
; 
 280                         KEEPALIVE_Response
->Status                  
= CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS
); 
 286 static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
, 
 288                                           void* const QueryData
, 
 289                                           const uint16_t QuerySize
, 
 291                                           uint16_t* const ResponseSize
) 
 298                 case OID_GEN_SUPPORTED_LIST
: 
 299                         *ResponseSize 
= sizeof(AdapterSupportedOIDList
); 
 301                         memcpy_P(ResponseData
, AdapterSupportedOIDList
, sizeof(AdapterSupportedOIDList
)); 
 304                 case OID_GEN_PHYSICAL_MEDIUM
: 
 305                         *ResponseSize 
= sizeof(uint32_t); 
 307                         /* Indicate that the device is a true ethernet link */ 
 308                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(0); 
 311                 case OID_GEN_HARDWARE_STATUS
: 
 312                         *ResponseSize 
= sizeof(uint32_t); 
 314                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(NDIS_HardwareStatus_Ready
); 
 317                 case OID_GEN_MEDIA_SUPPORTED
: 
 318                 case OID_GEN_MEDIA_IN_USE
: 
 319                         *ResponseSize 
= sizeof(uint32_t); 
 321                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3
); 
 324                 case OID_GEN_VENDOR_ID
: 
 325                         *ResponseSize 
= sizeof(uint32_t); 
 327                         /* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */ 
 328                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(0x00FFFFFF); 
 331                 case OID_GEN_MAXIMUM_FRAME_SIZE
: 
 332                 case OID_GEN_TRANSMIT_BLOCK_SIZE
: 
 333                 case OID_GEN_RECEIVE_BLOCK_SIZE
: 
 334                         *ResponseSize 
= sizeof(uint32_t); 
 336                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(ETHERNET_FRAME_SIZE_MAX
); 
 339                 case OID_GEN_VENDOR_DESCRIPTION
: 
 340                         *ResponseSize 
= (strlen(RNDISInterfaceInfo
->Config
.AdapterVendorDescription
) + 1); 
 342                         memcpy(ResponseData
, RNDISInterfaceInfo
->Config
.AdapterVendorDescription
, *ResponseSize
); 
 345                 case OID_GEN_MEDIA_CONNECT_STATUS
: 
 346                         *ResponseSize 
= sizeof(uint32_t); 
 348                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(REMOTE_NDIS_MEDIA_STATE_CONNECTED
); 
 351                 case OID_GEN_LINK_SPEED
: 
 352                         *ResponseSize 
= sizeof(uint32_t); 
 354                         /* Indicate 10Mb/s link speed */ 
 355                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(100000); 
 358                 case OID_802_3_PERMANENT_ADDRESS
: 
 359                 case OID_802_3_CURRENT_ADDRESS
: 
 360                         *ResponseSize 
= sizeof(MAC_Address_t
); 
 362                         memcpy(ResponseData
, &RNDISInterfaceInfo
->Config
.AdapterMACAddress
, sizeof(MAC_Address_t
)); 
 365                 case OID_802_3_MAXIMUM_LIST_SIZE
: 
 366                         *ResponseSize 
= sizeof(uint32_t); 
 368                         /* Indicate only one multicast address supported */ 
 369                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(1); 
 372                 case OID_GEN_CURRENT_PACKET_FILTER
: 
 373                         *ResponseSize 
= sizeof(uint32_t); 
 375                         *((uint32_t*)ResponseData
) = cpu_to_le32(RNDISInterfaceInfo
->State
.CurrPacketFilter
); 
 378                 case OID_GEN_XMIT_OK
: 
 380                 case OID_GEN_XMIT_ERROR
: 
 381                 case OID_GEN_RCV_ERROR
: 
 382                 case OID_GEN_RCV_NO_BUFFER
: 
 383                 case OID_802_3_RCV_ERROR_ALIGNMENT
: 
 384                 case OID_802_3_XMIT_ONE_COLLISION
: 
 385                 case OID_802_3_XMIT_MORE_COLLISIONS
: 
 386                         *ResponseSize 
= sizeof(uint32_t); 
 388                         /* Unused statistic OIDs - always return 0 for each */ 
 389                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(0); 
 392                 case OID_GEN_MAXIMUM_TOTAL_SIZE
: 
 393                         *ResponseSize 
= sizeof(uint32_t); 
 395                         /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */ 
 396                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(RNDISInterfaceInfo
->Config
.MessageBufferLength 
+ ETHERNET_FRAME_SIZE_MAX
); 
 404 static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
, 
 407                                         const uint16_t SetSize
) 
 413                 case OID_GEN_CURRENT_PACKET_FILTER
: 
 414                         RNDISInterfaceInfo
->State
.CurrPacketFilter 
= le32_to_cpu(*((uint32_t*)SetData
)); 
 415                         RNDISInterfaceInfo
->State
.CurrRNDISState   
= (RNDISInterfaceInfo
->State
.CurrPacketFilter
) ? RNDIS_Data_Initialized 
: RNDIS_Initialized
; 
 418                 case OID_802_3_MULTICAST_LIST
: 
 419                         /* Do nothing - throw away the value from the host as it is unused */ 
 427 bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
) 
 429         if ((USB_DeviceState 
!= DEVICE_STATE_Configured
) || 
 430             (RNDISInterfaceInfo
->State
.CurrRNDISState 
!= RNDIS_Data_Initialized
)) 
 435         Endpoint_SelectEndpoint(RNDISInterfaceInfo
->Config
.DataOUTEndpoint
.Address
); 
 436         return Endpoint_IsOUTReceived(); 
 439 uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
, 
 441                                 uint16_t* const PacketLength
) 
 443         if ((USB_DeviceState 
!= DEVICE_STATE_Configured
) || 
 444             (RNDISInterfaceInfo
->State
.CurrRNDISState 
!= RNDIS_Data_Initialized
)) 
 446                 return ENDPOINT_RWSTREAM_DeviceDisconnected
; 
 449         Endpoint_SelectEndpoint(RNDISInterfaceInfo
->Config
.DataOUTEndpoint
.Address
); 
 453         if (!(Endpoint_IsOUTReceived())) 
 454                 return ENDPOINT_RWSTREAM_NoError
; 
 456         RNDIS_Packet_Message_t RNDISPacketHeader
; 
 457         Endpoint_Read_Stream_LE(&RNDISPacketHeader
, sizeof(RNDIS_Packet_Message_t
), NULL
); 
 459         if (le32_to_cpu(RNDISPacketHeader
.DataLength
) > ETHERNET_FRAME_SIZE_MAX
) 
 461                 Endpoint_StallTransaction(); 
 463                 return RNDIS_ERROR_LOGICAL_CMD_FAILED
; 
 466         *PacketLength 
= (uint16_t)le32_to_cpu(RNDISPacketHeader
.DataLength
); 
 468         Endpoint_Read_Stream_LE(Buffer
, *PacketLength
, NULL
); 
 471         return ENDPOINT_RWSTREAM_NoError
; 
 474 uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
, 
 476                                 const uint16_t PacketLength
) 
 480         if ((USB_DeviceState 
!= DEVICE_STATE_Configured
) || 
 481             (RNDISInterfaceInfo
->State
.CurrRNDISState 
!= RNDIS_Data_Initialized
)) 
 483                 return ENDPOINT_RWSTREAM_DeviceDisconnected
; 
 486         Endpoint_SelectEndpoint(RNDISInterfaceInfo
->Config
.DataINEndpoint
.Address
); 
 488         if ((ErrorCode 
= Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError
) 
 491         RNDIS_Packet_Message_t RNDISPacketHeader
; 
 493         memset(&RNDISPacketHeader
, 0, sizeof(RNDIS_Packet_Message_t
)); 
 495         RNDISPacketHeader
.MessageType   
= CPU_TO_LE32(REMOTE_NDIS_PACKET_MSG
); 
 496         RNDISPacketHeader
.MessageLength 
= cpu_to_le32(sizeof(RNDIS_Packet_Message_t
) + PacketLength
); 
 497         RNDISPacketHeader
.DataOffset    
= CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t
) - sizeof(RNDIS_Message_Header_t
)); 
 498         RNDISPacketHeader
.DataLength    
= cpu_to_le32(PacketLength
); 
 500         Endpoint_Write_Stream_LE(&RNDISPacketHeader
, sizeof(RNDIS_Packet_Message_t
), NULL
); 
 501         Endpoint_Write_Stream_LE(Buffer
, PacketLength
, NULL
); 
 504         return ENDPOINT_RWSTREAM_NoError
;