3      Copyright (C) Dean Camera, 2011. 
   5   dean [at] fourwalledcubicle [dot] com 
  10   Copyright 2011  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 disclaim 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 
  40 static const uint32_t PROGMEM AdapterSupportedOIDList
[]  = 
  42                 OID_GEN_SUPPORTED_LIST
, 
  43                 OID_GEN_PHYSICAL_MEDIUM
, 
  44                 OID_GEN_HARDWARE_STATUS
, 
  45                 OID_GEN_MEDIA_SUPPORTED
, 
  47                 OID_GEN_MAXIMUM_FRAME_SIZE
, 
  48                 OID_GEN_MAXIMUM_TOTAL_SIZE
, 
  50                 OID_GEN_TRANSMIT_BLOCK_SIZE
, 
  51                 OID_GEN_RECEIVE_BLOCK_SIZE
, 
  53                 OID_GEN_VENDOR_DESCRIPTION
, 
  54                 OID_GEN_CURRENT_PACKET_FILTER
, 
  55                 OID_GEN_MAXIMUM_TOTAL_SIZE
, 
  56                 OID_GEN_MEDIA_CONNECT_STATUS
, 
  61                 OID_GEN_RCV_NO_BUFFER
, 
  62                 OID_802_3_PERMANENT_ADDRESS
, 
  63                 OID_802_3_CURRENT_ADDRESS
, 
  64                 OID_802_3_MULTICAST_LIST
, 
  65                 OID_802_3_MAXIMUM_LIST_SIZE
, 
  66                 OID_802_3_RCV_ERROR_ALIGNMENT
, 
  67                 OID_802_3_XMIT_ONE_COLLISION
, 
  68                 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 
= 1; 
 103                                 Endpoint_ClearSETUP(); 
 104                                 Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo
->State
.RNDISMessageBuffer
, MessageHeader
->MessageLength
); 
 107                                 MessageHeader
->MessageLength 
= 0; 
 114 bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
) 
 116         memset(&RNDISInterfaceInfo
->State
, 0x00, sizeof(RNDISInterfaceInfo
->State
)); 
 118         for (uint8_t EndpointNum 
= 1; EndpointNum 
< ENDPOINT_TOTAL_ENDPOINTS
; EndpointNum
++) 
 125                 if (EndpointNum 
== RNDISInterfaceInfo
->Config
.DataINEndpointNumber
) 
 127                         Size         
= RNDISInterfaceInfo
->Config
.DataINEndpointSize
; 
 128                         Direction    
= ENDPOINT_DIR_IN
; 
 130                         DoubleBanked 
= RNDISInterfaceInfo
->Config
.DataINEndpointDoubleBank
; 
 132                 else if (EndpointNum 
== RNDISInterfaceInfo
->Config
.DataOUTEndpointNumber
) 
 134                         Size         
= RNDISInterfaceInfo
->Config
.DataOUTEndpointSize
; 
 135                         Direction    
= ENDPOINT_DIR_OUT
; 
 137                         DoubleBanked 
= RNDISInterfaceInfo
->Config
.DataOUTEndpointDoubleBank
; 
 139                 else if (EndpointNum 
== RNDISInterfaceInfo
->Config
.NotificationEndpointNumber
) 
 141                         Size         
= RNDISInterfaceInfo
->Config
.NotificationEndpointSize
; 
 142                         Direction    
= ENDPOINT_DIR_IN
; 
 143                         Type         
= EP_TYPE_INTERRUPT
; 
 144                         DoubleBanked 
= RNDISInterfaceInfo
->Config
.NotificationEndpointDoubleBank
; 
 151                 if (!(Endpoint_ConfigureEndpoint(EndpointNum
, Type
, Direction
, Size
, 
 152                                                  DoubleBanked ? ENDPOINT_BANK_DOUBLE 
: ENDPOINT_BANK_SINGLE
))) 
 161 void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
) 
 163         if (USB_DeviceState 
!= DEVICE_STATE_Configured
) 
 166         Endpoint_SelectEndpoint(RNDISInterfaceInfo
->Config
.NotificationEndpointNumber
); 
 168         if (Endpoint_IsINReady() && RNDISInterfaceInfo
->State
.ResponseReady
) 
 170                 USB_Request_Header_t Notification 
= (USB_Request_Header_t
) 
 172                                 .bmRequestType 
= (REQDIR_DEVICETOHOST 
| REQTYPE_CLASS 
| REQREC_INTERFACE
), 
 173                                 .bRequest      
= RNDIS_NOTIF_ResponseAvailable
, 
 179                 Endpoint_Write_Stream_LE(&Notification
, sizeof(USB_Request_Header_t
), NULL
); 
 183                 RNDISInterfaceInfo
->State
.ResponseReady 
= false; 
 187 void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
) 
 189         /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of 
 190                  this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */ 
 192         RNDIS_Message_Header_t
* MessageHeader 
= (RNDIS_Message_Header_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 194         switch (MessageHeader
->MessageType
) 
 196                 case REMOTE_NDIS_INITIALIZE_MSG
: 
 197                         RNDISInterfaceInfo
->State
.ResponseReady 
= true; 
 199                         RNDIS_Initialize_Message_t
*  INITIALIZE_Message  
= 
 200                                        (RNDIS_Initialize_Message_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 201                         RNDIS_Initialize_Complete_t
* INITIALIZE_Response 
= 
 202                                        (RNDIS_Initialize_Complete_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 204                         INITIALIZE_Response
->MessageType           
= REMOTE_NDIS_INITIALIZE_CMPLT
; 
 205                         INITIALIZE_Response
->MessageLength         
= sizeof(RNDIS_Initialize_Complete_t
); 
 206                         INITIALIZE_Response
->RequestId             
= INITIALIZE_Message
->RequestId
; 
 207                         INITIALIZE_Response
->Status                
= REMOTE_NDIS_STATUS_SUCCESS
; 
 209                         INITIALIZE_Response
->MajorVersion          
= REMOTE_NDIS_VERSION_MAJOR
; 
 210                         INITIALIZE_Response
->MinorVersion          
= REMOTE_NDIS_VERSION_MINOR
; 
 211                         INITIALIZE_Response
->DeviceFlags           
= REMOTE_NDIS_DF_CONNECTIONLESS
; 
 212                         INITIALIZE_Response
->Medium                
= REMOTE_NDIS_MEDIUM_802_3
; 
 213                         INITIALIZE_Response
->MaxPacketsPerTransfer 
= 1; 
 214                         INITIALIZE_Response
->MaxTransferSize       
= (sizeof(RNDIS_Packet_Message_t
) + ETHERNET_FRAME_SIZE_MAX
); 
 215                         INITIALIZE_Response
->PacketAlignmentFactor 
= 0; 
 216                         INITIALIZE_Response
->AFListOffset          
= 0; 
 217                         INITIALIZE_Response
->AFListSize            
= 0; 
 219                         RNDISInterfaceInfo
->State
.CurrRNDISState 
= RNDIS_Initialized
; 
 222                 case REMOTE_NDIS_HALT_MSG
: 
 223                         RNDISInterfaceInfo
->State
.ResponseReady 
= false; 
 224                         MessageHeader
->MessageLength 
= 0; 
 226                         RNDISInterfaceInfo
->State
.CurrRNDISState 
= RNDIS_Uninitialized
; 
 229                 case REMOTE_NDIS_QUERY_MSG
: 
 230                         RNDISInterfaceInfo
->State
.ResponseReady 
= true; 
 232                         RNDIS_Query_Message_t
*  QUERY_Message  
= (RNDIS_Query_Message_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 233                         RNDIS_Query_Complete_t
* QUERY_Response 
= (RNDIS_Query_Complete_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 234                         uint32_t                Query_Oid      
= QUERY_Message
->Oid
; 
 236                         void*     QueryData    
= &RNDISInterfaceInfo
->State
.RNDISMessageBuffer
[sizeof(RNDIS_Message_Header_t
) + 
 237                                                                                                QUERY_Message
->InformationBufferOffset
]; 
 238                         void*     ResponseData 
= &RNDISInterfaceInfo
->State
.RNDISMessageBuffer
[sizeof(RNDIS_Query_Complete_t
)]; 
 239                         uint16_t  ResponseSize
; 
 241                         QUERY_Response
->MessageType   
= REMOTE_NDIS_QUERY_CMPLT
; 
 242                         QUERY_Response
->MessageLength 
= sizeof(RNDIS_Query_Complete_t
); 
 244                         if (RNDIS_Device_ProcessNDISQuery(RNDISInterfaceInfo
, Query_Oid
, QueryData
, QUERY_Message
->InformationBufferLength
, 
 245                                                           ResponseData
, &ResponseSize
)) 
 247                                 QUERY_Response
->Status                  
= REMOTE_NDIS_STATUS_SUCCESS
; 
 248                                 QUERY_Response
->MessageLength          
+= ResponseSize
; 
 250                                 QUERY_Response
->InformationBufferLength 
= ResponseSize
; 
 251                                 QUERY_Response
->InformationBufferOffset 
= (sizeof(RNDIS_Query_Complete_t
) - sizeof(RNDIS_Message_Header_t
)); 
 255                                 QUERY_Response
->Status                  
= REMOTE_NDIS_STATUS_NOT_SUPPORTED
; 
 257                                 QUERY_Response
->InformationBufferLength 
= 0; 
 258                                 QUERY_Response
->InformationBufferOffset 
= 0; 
 262                 case REMOTE_NDIS_SET_MSG
: 
 263                         RNDISInterfaceInfo
->State
.ResponseReady 
= true; 
 265                         RNDIS_Set_Message_t
*  SET_Message  
= (RNDIS_Set_Message_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 266                         RNDIS_Set_Complete_t
* SET_Response 
= (RNDIS_Set_Complete_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 267                         uint32_t              SET_Oid      
= SET_Message
->Oid
; 
 269                         SET_Response
->MessageType   
= REMOTE_NDIS_SET_CMPLT
; 
 270                         SET_Response
->MessageLength 
= sizeof(RNDIS_Set_Complete_t
); 
 271                         SET_Response
->RequestId     
= SET_Message
->RequestId
; 
 273                         void* SetData 
= &RNDISInterfaceInfo
->State
.RNDISMessageBuffer
[sizeof(RNDIS_Message_Header_t
) + 
 274                                                                                       SET_Message
->InformationBufferOffset
]; 
 276                         SET_Response
->Status 
= RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo
, SET_Oid
, SetData
, 
 277                                                                            SET_Message
->InformationBufferLength
) ?
 
 278                                                                            REMOTE_NDIS_STATUS_SUCCESS 
: REMOTE_NDIS_STATUS_NOT_SUPPORTED
; 
 280                 case REMOTE_NDIS_RESET_MSG
: 
 281                         RNDISInterfaceInfo
->State
.ResponseReady 
= true; 
 283                         RNDIS_Reset_Complete_t
* RESET_Response 
= (RNDIS_Reset_Complete_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 285                         RESET_Response
->MessageType     
= REMOTE_NDIS_RESET_CMPLT
; 
 286                         RESET_Response
->MessageLength   
= sizeof(RNDIS_Reset_Complete_t
); 
 287                         RESET_Response
->Status          
= REMOTE_NDIS_STATUS_SUCCESS
; 
 288                         RESET_Response
->AddressingReset 
= 0; 
 291                 case REMOTE_NDIS_KEEPALIVE_MSG
: 
 292                         RNDISInterfaceInfo
->State
.ResponseReady 
= true; 
 294                         RNDIS_KeepAlive_Message_t
*  KEEPALIVE_Message  
= 
 295                                         (RNDIS_KeepAlive_Message_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 296                         RNDIS_KeepAlive_Complete_t
* KEEPALIVE_Response 
= 
 297                                         (RNDIS_KeepAlive_Complete_t
*)&RNDISInterfaceInfo
->State
.RNDISMessageBuffer
; 
 299                         KEEPALIVE_Response
->MessageType   
= REMOTE_NDIS_KEEPALIVE_CMPLT
; 
 300                         KEEPALIVE_Response
->MessageLength 
= sizeof(RNDIS_KeepAlive_Complete_t
); 
 301                         KEEPALIVE_Response
->RequestId     
= KEEPALIVE_Message
->RequestId
; 
 302                         KEEPALIVE_Response
->Status        
= REMOTE_NDIS_STATUS_SUCCESS
; 
 308 static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
, 
 310                                           void* const QueryData
, 
 311                                           const uint16_t QuerySize
, 
 313                                           uint16_t* const ResponseSize
) 
 320                 case OID_GEN_SUPPORTED_LIST
: 
 321                         *ResponseSize 
= sizeof(AdapterSupportedOIDList
); 
 323                         memcpy_P(ResponseData
, AdapterSupportedOIDList
, sizeof(AdapterSupportedOIDList
)); 
 326                 case OID_GEN_PHYSICAL_MEDIUM
: 
 327                         *ResponseSize 
= sizeof(uint32_t); 
 329                         /* Indicate that the device is a true ethernet link */ 
 330                         *((uint32_t*)ResponseData
) = 0; 
 333                 case OID_GEN_HARDWARE_STATUS
: 
 334                         *ResponseSize 
= sizeof(uint32_t); 
 336                         *((uint32_t*)ResponseData
) = NDIS_HardwareStatus_Ready
; 
 339                 case OID_GEN_MEDIA_SUPPORTED
: 
 340                 case OID_GEN_MEDIA_IN_USE
: 
 341                         *ResponseSize 
= sizeof(uint32_t); 
 343                         *((uint32_t*)ResponseData
) = REMOTE_NDIS_MEDIUM_802_3
; 
 346                 case OID_GEN_VENDOR_ID
: 
 347                         *ResponseSize 
= sizeof(uint32_t); 
 349                         /* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */ 
 350                         *((uint32_t*)ResponseData
) = 0x00FFFFFF; 
 353                 case OID_GEN_MAXIMUM_FRAME_SIZE
: 
 354                 case OID_GEN_TRANSMIT_BLOCK_SIZE
: 
 355                 case OID_GEN_RECEIVE_BLOCK_SIZE
: 
 356                         *ResponseSize 
= sizeof(uint32_t); 
 358                         *((uint32_t*)ResponseData
) = ETHERNET_FRAME_SIZE_MAX
; 
 361                 case OID_GEN_VENDOR_DESCRIPTION
: 
 362                         *ResponseSize 
= (strlen(RNDISInterfaceInfo
->Config
.AdapterVendorDescription
) + 1); 
 364                         memcpy(ResponseData
, RNDISInterfaceInfo
->Config
.AdapterVendorDescription
, *ResponseSize
); 
 367                 case OID_GEN_MEDIA_CONNECT_STATUS
: 
 368                         *ResponseSize 
= sizeof(uint32_t); 
 370                         *((uint32_t*)ResponseData
) = REMOTE_NDIS_MEDIA_STATE_CONNECTED
; 
 373                 case OID_GEN_LINK_SPEED
: 
 374                         *ResponseSize 
= sizeof(uint32_t); 
 376                         /* Indicate 10Mb/s link speed */ 
 377                         *((uint32_t*)ResponseData
) = 100000; 
 380                 case OID_802_3_PERMANENT_ADDRESS
: 
 381                 case OID_802_3_CURRENT_ADDRESS
: 
 382                         *ResponseSize 
= sizeof(MAC_Address_t
); 
 384                         memcpy(ResponseData
, &RNDISInterfaceInfo
->Config
.AdapterMACAddress
, sizeof(MAC_Address_t
)); 
 387                 case OID_802_3_MAXIMUM_LIST_SIZE
: 
 388                         *ResponseSize 
= sizeof(uint32_t); 
 390                         /* Indicate only one multicast address supported */ 
 391                         *((uint32_t*)ResponseData
) = 1; 
 394                 case OID_GEN_CURRENT_PACKET_FILTER
: 
 395                         *ResponseSize 
= sizeof(uint32_t); 
 397                         *((uint32_t*)ResponseData
) = RNDISInterfaceInfo
->State
.CurrPacketFilter
; 
 400                 case OID_GEN_XMIT_OK
: 
 402                 case OID_GEN_XMIT_ERROR
: 
 403                 case OID_GEN_RCV_ERROR
: 
 404                 case OID_GEN_RCV_NO_BUFFER
: 
 405                 case OID_802_3_RCV_ERROR_ALIGNMENT
: 
 406                 case OID_802_3_XMIT_ONE_COLLISION
: 
 407                 case OID_802_3_XMIT_MORE_COLLISIONS
: 
 408                         *ResponseSize 
= sizeof(uint32_t); 
 410                         /* Unused statistic OIDs - always return 0 for each */ 
 411                         *((uint32_t*)ResponseData
) = 0; 
 414                 case OID_GEN_MAXIMUM_TOTAL_SIZE
: 
 415                         *ResponseSize 
= sizeof(uint32_t); 
 417                         /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */ 
 418                         *((uint32_t*)ResponseData
) = (RNDIS_MESSAGE_BUFFER_SIZE 
+ ETHERNET_FRAME_SIZE_MAX
); 
 426 static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
, 
 429                                         const uint16_t SetSize
) 
 435                 case OID_GEN_CURRENT_PACKET_FILTER
: 
 436                         RNDISInterfaceInfo
->State
.CurrPacketFilter 
= *((uint32_t*)SetData
); 
 437                         RNDISInterfaceInfo
->State
.CurrRNDISState 
= ((RNDISInterfaceInfo
->State
.CurrPacketFilter
) ?
 
 438                                                               RNDIS_Data_Initialized 
: RNDIS_Data_Initialized
); 
 441                 case OID_802_3_MULTICAST_LIST
: 
 442                         /* Do nothing - throw away the value from the host as it is unused */ 
 450 bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
) 
 452         if ((USB_DeviceState 
!= DEVICE_STATE_Configured
) || 
 453             (RNDISInterfaceInfo
->State
.CurrRNDISState 
!= RNDIS_Data_Initialized
)) 
 458         Endpoint_SelectEndpoint(RNDISInterfaceInfo
->Config
.DataOUTEndpointNumber
); 
 459         return Endpoint_IsOUTReceived(); 
 462 uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
, 
 464                                 uint16_t* const PacketLength
) 
 466         if ((USB_DeviceState 
!= DEVICE_STATE_Configured
) || 
 467             (RNDISInterfaceInfo
->State
.CurrRNDISState 
!= RNDIS_Data_Initialized
)) 
 469                 return ENDPOINT_RWSTREAM_DeviceDisconnected
; 
 472         Endpoint_SelectEndpoint(RNDISInterfaceInfo
->Config
.DataOUTEndpointNumber
); 
 476         if (!(Endpoint_IsOUTReceived())) 
 477                 return ENDPOINT_RWSTREAM_NoError
; 
 479         RNDIS_Packet_Message_t RNDISPacketHeader
;        
 480         Endpoint_Read_Stream_LE(&RNDISPacketHeader
, sizeof(RNDIS_Packet_Message_t
), NULL
); 
 482         if (RNDISPacketHeader
.DataLength 
> ETHERNET_FRAME_SIZE_MAX
) 
 484                 Endpoint_StallTransaction(); 
 486                 return RNDIS_ERROR_LOGICAL_CMD_FAILED
; 
 489         *PacketLength 
= (uint16_t)RNDISPacketHeader
.DataLength
; 
 491         Endpoint_Read_Stream_LE(Buffer
, RNDISPacketHeader
.DataLength
, NULL
); 
 494         return ENDPOINT_RWSTREAM_NoError
; 
 497 uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t
* const RNDISInterfaceInfo
, 
 499                                 const uint16_t PacketLength
) 
 503         if ((USB_DeviceState 
!= DEVICE_STATE_Configured
) || 
 504             (RNDISInterfaceInfo
->State
.CurrRNDISState 
!= RNDIS_Data_Initialized
)) 
 506                 return ENDPOINT_RWSTREAM_DeviceDisconnected
; 
 509         Endpoint_SelectEndpoint(RNDISInterfaceInfo
->Config
.DataINEndpointNumber
); 
 511         if ((ErrorCode 
= Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError
) 
 514         RNDIS_Packet_Message_t RNDISPacketHeader
; 
 516         memset(&RNDISPacketHeader
, 0, sizeof(RNDIS_Packet_Message_t
)); 
 518         RNDISPacketHeader
.MessageType   
= REMOTE_NDIS_PACKET_MSG
; 
 519         RNDISPacketHeader
.MessageLength 
= (sizeof(RNDIS_Packet_Message_t
) + PacketLength
); 
 520         RNDISPacketHeader
.DataOffset    
= (sizeof(RNDIS_Packet_Message_t
) - sizeof(RNDIS_Message_Header_t
)); 
 521         RNDISPacketHeader
.DataLength    
= PacketLength
; 
 523         Endpoint_Write_Stream_LE(&RNDISPacketHeader
, sizeof(RNDIS_Packet_Message_t
), NULL
); 
 524         Endpoint_Write_Stream_LE(Buffer
, PacketLength
, NULL
); 
 527         return ENDPOINT_RWSTREAM_NoError
;