3      Copyright (C) Dean Camera, 2013. 
   5   dean [at] fourwalledcubicle [dot] com 
  10   Copyright 2013  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
->State
.RNDISMessageBuffer
, 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
->State
.RNDISMessageBuffer
; 
  97                                 if (!(MessageHeader
->MessageLength
)) 
  99                                         RNDISInterfaceInfo
->State
.RNDISMessageBuffer
[0] = 0; 
 100                                         MessageHeader
->MessageLength                    
= CPU_TO_LE32(1); 
 103                                 Endpoint_ClearSETUP(); 
 104                                 Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo
->State
.RNDISMessageBuffer
, 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 (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo
->Config
.DataINEndpoint
, 1))) 
 125         if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo
->Config
.DataOUTEndpoint
, 1))) 
 128         if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo
->Config
.NotificationEndpoint
, 1))) 
 134 void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
) 
 136         if (USB_DeviceState 
!= DEVICE_STATE_Configured
) 
 139         Endpoint_SelectEndpoint(RNDISInterfaceInfo
->Config
.NotificationEndpoint
.Address
); 
 141         if (Endpoint_IsINReady() && RNDISInterfaceInfo
->State
.ResponseReady
) 
 143                 USB_Request_Header_t Notification 
= (USB_Request_Header_t
) 
 145                                 .bmRequestType 
= (REQDIR_DEVICETOHOST 
| REQTYPE_CLASS 
| REQREC_INTERFACE
), 
 146                                 .bRequest      
= RNDIS_NOTIF_ResponseAvailable
, 
 147                                 .wValue        
= CPU_TO_LE16(0), 
 148                                 .wIndex        
= CPU_TO_LE16(0), 
 149                                 .wLength       
= CPU_TO_LE16(0), 
 152                 Endpoint_Write_Stream_LE(&Notification
, sizeof(USB_Request_Header_t
), NULL
); 
 156                 RNDISInterfaceInfo
->State
.ResponseReady 
= false; 
 160 void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
) 
 162         /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of 
 163                  this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */ 
 165         RNDIS_Message_Header_t
* MessageHeader 
= (RNDIS_Message_Header_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 167         switch (le32_to_cpu(MessageHeader
->MessageType
)) 
 169                 case REMOTE_NDIS_INITIALIZE_MSG
: 
 170                         RNDISInterfaceInfo
->State
.ResponseReady     
= true; 
 172                         RNDIS_Initialize_Message_t
*  INITIALIZE_Message  
= 
 173                                        (RNDIS_Initialize_Message_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 174                         RNDIS_Initialize_Complete_t
* INITIALIZE_Response 
= 
 175                                        (RNDIS_Initialize_Complete_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 177                         INITIALIZE_Response
->MessageType            
= CPU_TO_LE32(REMOTE_NDIS_INITIALIZE_CMPLT
); 
 178                         INITIALIZE_Response
->MessageLength          
= CPU_TO_LE32(sizeof(RNDIS_Initialize_Complete_t
)); 
 179                         INITIALIZE_Response
->RequestId              
= INITIALIZE_Message
->RequestId
; 
 180                         INITIALIZE_Response
->Status                 
= CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS
); 
 182                         INITIALIZE_Response
->MajorVersion           
= CPU_TO_LE32(REMOTE_NDIS_VERSION_MAJOR
); 
 183                         INITIALIZE_Response
->MinorVersion           
= CPU_TO_LE32(REMOTE_NDIS_VERSION_MINOR
); 
 184                         INITIALIZE_Response
->DeviceFlags            
= CPU_TO_LE32(REMOTE_NDIS_DF_CONNECTIONLESS
); 
 185                         INITIALIZE_Response
->Medium                 
= CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3
); 
 186                         INITIALIZE_Response
->MaxPacketsPerTransfer  
= CPU_TO_LE32(1); 
 187                         INITIALIZE_Response
->MaxTransferSize        
= CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t
) + ETHERNET_FRAME_SIZE_MAX
); 
 188                         INITIALIZE_Response
->PacketAlignmentFactor  
= CPU_TO_LE32(0); 
 189                         INITIALIZE_Response
->AFListOffset           
= CPU_TO_LE32(0); 
 190                         INITIALIZE_Response
->AFListSize             
= CPU_TO_LE32(0); 
 192                         RNDISInterfaceInfo
->State
.CurrRNDISState    
= RNDIS_Initialized
; 
 194                 case REMOTE_NDIS_HALT_MSG
: 
 195                         RNDISInterfaceInfo
->State
.ResponseReady     
= false; 
 197                         MessageHeader
->MessageLength                
= CPU_TO_LE32(0); 
 199                         RNDISInterfaceInfo
->State
.CurrRNDISState    
= RNDIS_Uninitialized
; 
 201                 case REMOTE_NDIS_QUERY_MSG
: 
 202                         RNDISInterfaceInfo
->State
.ResponseReady     
= true; 
 204                         RNDIS_Query_Message_t
*  QUERY_Message       
= (RNDIS_Query_Message_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 205                         RNDIS_Query_Complete_t
* QUERY_Response      
= (RNDIS_Query_Complete_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 206                         uint32_t                Query_Oid           
= CPU_TO_LE32(QUERY_Message
->Oid
); 
 208                         void*    QueryData    
= &RNDISInterfaceInfo
->State
.RNDISMessageBuffer
[sizeof(RNDIS_Message_Header_t
) + 
 209                                                                                               le32_to_cpu(QUERY_Message
->InformationBufferOffset
)]; 
 210                         void*    ResponseData 
= &RNDISInterfaceInfo
->State
.RNDISMessageBuffer
[sizeof(RNDIS_Query_Complete_t
)]; 
 211                         uint16_t ResponseSize
; 
 213                         QUERY_Response
->MessageType                 
= CPU_TO_LE32(REMOTE_NDIS_QUERY_CMPLT
); 
 215                         if (RNDIS_Device_ProcessNDISQuery(RNDISInterfaceInfo
, Query_Oid
, QueryData
, le32_to_cpu(QUERY_Message
->InformationBufferLength
), 
 216                                                           ResponseData
, &ResponseSize
)) 
 218                                 QUERY_Response
->Status                  
= CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS
); 
 219                                 QUERY_Response
->MessageLength           
= cpu_to_le32(sizeof(RNDIS_Query_Complete_t
) + ResponseSize
); 
 221                                 QUERY_Response
->InformationBufferLength 
= CPU_TO_LE32(ResponseSize
); 
 222                                 QUERY_Response
->InformationBufferOffset 
= CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t
) - sizeof(RNDIS_Message_Header_t
)); 
 226                                 QUERY_Response
->Status                  
= CPU_TO_LE32(REMOTE_NDIS_STATUS_NOT_SUPPORTED
); 
 227                                 QUERY_Response
->MessageLength           
= CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t
)); 
 229                                 QUERY_Response
->InformationBufferLength 
= CPU_TO_LE32(0); 
 230                                 QUERY_Response
->InformationBufferOffset 
= CPU_TO_LE32(0); 
 234                 case REMOTE_NDIS_SET_MSG
: 
 235                         RNDISInterfaceInfo
->State
.ResponseReady     
= true; 
 237                         RNDIS_Set_Message_t
*  SET_Message           
= (RNDIS_Set_Message_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 238                         RNDIS_Set_Complete_t
* SET_Response          
= (RNDIS_Set_Complete_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 239                         uint32_t              SET_Oid               
= le32_to_cpu(SET_Message
->Oid
); 
 241                         SET_Response
->MessageType                   
= CPU_TO_LE32(REMOTE_NDIS_SET_CMPLT
); 
 242                         SET_Response
->MessageLength                 
= CPU_TO_LE32(sizeof(RNDIS_Set_Complete_t
)); 
 243                         SET_Response
->RequestId                     
= SET_Message
->RequestId
; 
 245                         void* SetData 
= &RNDISInterfaceInfo
->State
.RNDISMessageBuffer
[sizeof(RNDIS_Message_Header_t
) + 
 246                                                                                       le32_to_cpu(SET_Message
->InformationBufferOffset
)]; 
 248                         SET_Response
->Status 
= RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo
, SET_Oid
, SetData
, 
 249                                                                            le32_to_cpu(SET_Message
->InformationBufferLength
)) ?
 
 250                                                                            REMOTE_NDIS_STATUS_SUCCESS 
: REMOTE_NDIS_STATUS_NOT_SUPPORTED
; 
 252                 case REMOTE_NDIS_RESET_MSG
: 
 253                         RNDISInterfaceInfo
->State
.ResponseReady     
= true; 
 255                         RNDIS_Reset_Complete_t
* RESET_Response      
= (RNDIS_Reset_Complete_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 257                         RESET_Response
->MessageType                 
= CPU_TO_LE32(REMOTE_NDIS_RESET_CMPLT
); 
 258                         RESET_Response
->MessageLength               
= CPU_TO_LE32(sizeof(RNDIS_Reset_Complete_t
)); 
 259                         RESET_Response
->Status                      
= CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS
); 
 260                         RESET_Response
->AddressingReset             
= CPU_TO_LE32(0); 
 263                 case REMOTE_NDIS_KEEPALIVE_MSG
: 
 264                         RNDISInterfaceInfo
->State
.ResponseReady     
= true; 
 266                         RNDIS_KeepAlive_Message_t
*  KEEPALIVE_Message  
= 
 267                                         (RNDIS_KeepAlive_Message_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 268                         RNDIS_KeepAlive_Complete_t
* KEEPALIVE_Response 
= 
 269                                         (RNDIS_KeepAlive_Complete_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 271                         KEEPALIVE_Response
->MessageType             
= CPU_TO_LE32(REMOTE_NDIS_KEEPALIVE_CMPLT
); 
 272                         KEEPALIVE_Response
->MessageLength           
= CPU_TO_LE32(sizeof(RNDIS_KeepAlive_Complete_t
)); 
 273                         KEEPALIVE_Response
->RequestId               
= KEEPALIVE_Message
->RequestId
; 
 274                         KEEPALIVE_Response
->Status                  
= CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS
); 
 280 static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
, 
 282                                           void* const QueryData
, 
 283                                           const uint16_t QuerySize
, 
 285                                           uint16_t* const ResponseSize
) 
 292                 case OID_GEN_SUPPORTED_LIST
: 
 293                         *ResponseSize 
= sizeof(AdapterSupportedOIDList
); 
 295                         memcpy_P(ResponseData
, AdapterSupportedOIDList
, sizeof(AdapterSupportedOIDList
)); 
 298                 case OID_GEN_PHYSICAL_MEDIUM
: 
 299                         *ResponseSize 
= sizeof(uint32_t); 
 301                         /* Indicate that the device is a true ethernet link */ 
 302                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(0); 
 305                 case OID_GEN_HARDWARE_STATUS
: 
 306                         *ResponseSize 
= sizeof(uint32_t); 
 308                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(NDIS_HardwareStatus_Ready
); 
 311                 case OID_GEN_MEDIA_SUPPORTED
: 
 312                 case OID_GEN_MEDIA_IN_USE
: 
 313                         *ResponseSize 
= sizeof(uint32_t); 
 315                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3
); 
 318                 case OID_GEN_VENDOR_ID
: 
 319                         *ResponseSize 
= sizeof(uint32_t); 
 321                         /* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */ 
 322                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(0x00FFFFFF); 
 325                 case OID_GEN_MAXIMUM_FRAME_SIZE
: 
 326                 case OID_GEN_TRANSMIT_BLOCK_SIZE
: 
 327                 case OID_GEN_RECEIVE_BLOCK_SIZE
: 
 328                         *ResponseSize 
= sizeof(uint32_t); 
 330                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(ETHERNET_FRAME_SIZE_MAX
); 
 333                 case OID_GEN_VENDOR_DESCRIPTION
: 
 334                         *ResponseSize 
= (strlen(RNDISInterfaceInfo
->Config
.AdapterVendorDescription
) + 1); 
 336                         memcpy(ResponseData
, RNDISInterfaceInfo
->Config
.AdapterVendorDescription
, *ResponseSize
); 
 339                 case OID_GEN_MEDIA_CONNECT_STATUS
: 
 340                         *ResponseSize 
= sizeof(uint32_t); 
 342                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(REMOTE_NDIS_MEDIA_STATE_CONNECTED
); 
 345                 case OID_GEN_LINK_SPEED
: 
 346                         *ResponseSize 
= sizeof(uint32_t); 
 348                         /* Indicate 10Mb/s link speed */ 
 349                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(100000); 
 352                 case OID_802_3_PERMANENT_ADDRESS
: 
 353                 case OID_802_3_CURRENT_ADDRESS
: 
 354                         *ResponseSize 
= sizeof(MAC_Address_t
); 
 356                         memcpy(ResponseData
, &RNDISInterfaceInfo
->Config
.AdapterMACAddress
, sizeof(MAC_Address_t
)); 
 359                 case OID_802_3_MAXIMUM_LIST_SIZE
: 
 360                         *ResponseSize 
= sizeof(uint32_t); 
 362                         /* Indicate only one multicast address supported */ 
 363                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(1); 
 366                 case OID_GEN_CURRENT_PACKET_FILTER
: 
 367                         *ResponseSize 
= sizeof(uint32_t); 
 369                         *((uint32_t*)ResponseData
) = cpu_to_le32(RNDISInterfaceInfo
->State
.CurrPacketFilter
); 
 372                 case OID_GEN_XMIT_OK
: 
 374                 case OID_GEN_XMIT_ERROR
: 
 375                 case OID_GEN_RCV_ERROR
: 
 376                 case OID_GEN_RCV_NO_BUFFER
: 
 377                 case OID_802_3_RCV_ERROR_ALIGNMENT
: 
 378                 case OID_802_3_XMIT_ONE_COLLISION
: 
 379                 case OID_802_3_XMIT_MORE_COLLISIONS
: 
 380                         *ResponseSize 
= sizeof(uint32_t); 
 382                         /* Unused statistic OIDs - always return 0 for each */ 
 383                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(0); 
 386                 case OID_GEN_MAXIMUM_TOTAL_SIZE
: 
 387                         *ResponseSize 
= sizeof(uint32_t); 
 389                         /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */ 
 390                         *((uint32_t*)ResponseData
) = CPU_TO_LE32(RNDIS_MESSAGE_BUFFER_SIZE 
+ ETHERNET_FRAME_SIZE_MAX
); 
 398 static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
, 
 401                                         const uint16_t SetSize
) 
 407                 case OID_GEN_CURRENT_PACKET_FILTER
: 
 408                         RNDISInterfaceInfo
->State
.CurrPacketFilter 
= le32_to_cpu(*((uint32_t*)SetData
)); 
 409                         RNDISInterfaceInfo
->State
.CurrRNDISState   
= (RNDISInterfaceInfo
->State
.CurrPacketFilter
) ? RNDIS_Data_Initialized 
: RNDIS_Initialized
; 
 412                 case OID_802_3_MULTICAST_LIST
: 
 413                         /* Do nothing - throw away the value from the host as it is unused */ 
 421 bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
) 
 423         if ((USB_DeviceState 
!= DEVICE_STATE_Configured
) || 
 424             (RNDISInterfaceInfo
->State
.CurrRNDISState 
!= RNDIS_Data_Initialized
)) 
 429         Endpoint_SelectEndpoint(RNDISInterfaceInfo
->Config
.DataOUTEndpoint
.Address
); 
 430         return Endpoint_IsOUTReceived(); 
 433 uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
, 
 435                                 uint16_t* const PacketLength
) 
 437         if ((USB_DeviceState 
!= DEVICE_STATE_Configured
) || 
 438             (RNDISInterfaceInfo
->State
.CurrRNDISState 
!= RNDIS_Data_Initialized
)) 
 440                 return ENDPOINT_RWSTREAM_DeviceDisconnected
; 
 443         Endpoint_SelectEndpoint(RNDISInterfaceInfo
->Config
.DataOUTEndpoint
.Address
); 
 447         if (!(Endpoint_IsOUTReceived())) 
 448                 return ENDPOINT_RWSTREAM_NoError
; 
 450         RNDIS_Packet_Message_t RNDISPacketHeader
; 
 451         Endpoint_Read_Stream_LE(&RNDISPacketHeader
, sizeof(RNDIS_Packet_Message_t
), NULL
); 
 453         if (le32_to_cpu(RNDISPacketHeader
.DataLength
) > ETHERNET_FRAME_SIZE_MAX
) 
 455                 Endpoint_StallTransaction(); 
 457                 return RNDIS_ERROR_LOGICAL_CMD_FAILED
; 
 460         *PacketLength 
= (uint16_t)le32_to_cpu(RNDISPacketHeader
.DataLength
); 
 462         Endpoint_Read_Stream_LE(Buffer
, *PacketLength
, NULL
); 
 465         return ENDPOINT_RWSTREAM_NoError
; 
 468 uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
, 
 470                                 const uint16_t PacketLength
) 
 474         if ((USB_DeviceState 
!= DEVICE_STATE_Configured
) || 
 475             (RNDISInterfaceInfo
->State
.CurrRNDISState 
!= RNDIS_Data_Initialized
)) 
 477                 return ENDPOINT_RWSTREAM_DeviceDisconnected
; 
 480         Endpoint_SelectEndpoint(RNDISInterfaceInfo
->Config
.DataINEndpoint
.Address
); 
 482         if ((ErrorCode 
= Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError
) 
 485         RNDIS_Packet_Message_t RNDISPacketHeader
; 
 487         memset(&RNDISPacketHeader
, 0, sizeof(RNDIS_Packet_Message_t
)); 
 489         RNDISPacketHeader
.MessageType   
= CPU_TO_LE32(REMOTE_NDIS_PACKET_MSG
); 
 490         RNDISPacketHeader
.MessageLength 
= cpu_to_le32(sizeof(RNDIS_Packet_Message_t
) + PacketLength
); 
 491         RNDISPacketHeader
.DataOffset    
= CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t
) - sizeof(RNDIS_Message_Header_t
)); 
 492         RNDISPacketHeader
.DataLength    
= cpu_to_le32(PacketLength
); 
 494         Endpoint_Write_Stream_LE(&RNDISPacketHeader
, sizeof(RNDIS_Packet_Message_t
), NULL
); 
 495         Endpoint_Write_Stream_LE(Buffer
, PacketLength
, NULL
); 
 498         return ENDPOINT_RWSTREAM_NoError
;