3      Copyright (C) Dean Camera, 2010. 
   5   dean [at] fourwalledcubicle [dot] com 
   6       www.fourwalledcubicle.com 
  10   Copyright 2010  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 "../../HighLevel/USBMode.h" 
  33 #if defined(USB_CAN_BE_HOST) 
  35 #define  __INCLUDE_FROM_RNDIS_CLASS_HOST_C 
  36 #define  __INCLUDE_FROM_RNDIS_DRIVER 
  39 uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t
* const RNDISInterfaceInfo
, uint16_t ConfigDescriptorSize
, 
  40                                 void* ConfigDescriptorData
) 
  42         uint8_t FoundEndpoints 
= 0; 
  44         memset(&RNDISInterfaceInfo
->State
, 0x00, sizeof(RNDISInterfaceInfo
->State
)); 
  46         if (DESCRIPTOR_TYPE(ConfigDescriptorData
) != DTYPE_Configuration
) 
  47           return RNDIS_ENUMERROR_InvalidConfigDescriptor
; 
  49         if (USB_GetNextDescriptorComp(&ConfigDescriptorSize
, &ConfigDescriptorData
, 
  50                                       DCOMP_RNDIS_Host_NextRNDISControlInterface
) != DESCRIPTOR_SEARCH_COMP_Found
) 
  52                 return RNDIS_ENUMERROR_NoRNDISInterfaceFound
; 
  55         RNDISInterfaceInfo
->State
.ControlInterfaceNumber 
= DESCRIPTOR_CAST(ConfigDescriptorData
, USB_Descriptor_Interface_t
).InterfaceNumber
; 
  57         while (FoundEndpoints 
!= (RNDIS_FOUND_NOTIFICATION_IN 
| RNDIS_FOUND_DATAPIPE_IN 
| RNDIS_FOUND_DATAPIPE_OUT
)) 
  59                 if (USB_GetNextDescriptorComp(&ConfigDescriptorSize
, &ConfigDescriptorData
, 
  60                                               DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint
) != DESCRIPTOR_SEARCH_COMP_Found
) 
  62                         if (FoundEndpoints 
& RNDIS_FOUND_NOTIFICATION_IN
) 
  64                                 if (USB_GetNextDescriptorComp(&ConfigDescriptorSize
, &ConfigDescriptorData
,  
  65                                                               DCOMP_RNDIS_Host_NextRNDISDataInterface
) != DESCRIPTOR_SEARCH_COMP_Found
) 
  67                                         return RNDIS_ENUMERROR_NoRNDISInterfaceFound
; 
  74                                 Pipe_SelectPipe(RNDISInterfaceInfo
->Config
.DataINPipeNumber
); 
  76                                 Pipe_SelectPipe(RNDISInterfaceInfo
->Config
.DataOUTPipeNumber
); 
  78                                 Pipe_SelectPipe(RNDISInterfaceInfo
->Config
.NotificationPipeNumber
); 
  81                                 if (USB_GetNextDescriptorComp(&ConfigDescriptorSize
, &ConfigDescriptorData
, 
  82                                                               DCOMP_RNDIS_Host_NextRNDISControlInterface
) != DESCRIPTOR_SEARCH_COMP_Found
) 
  84                                         return RNDIS_ENUMERROR_NoRNDISInterfaceFound
; 
  88                         if (USB_GetNextDescriptorComp(&ConfigDescriptorSize
, &ConfigDescriptorData
, 
  89                                                       DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint
) != DESCRIPTOR_SEARCH_COMP_Found
) 
  91                                 return RNDIS_ENUMERROR_EndpointsNotFound
; 
  95                 USB_Descriptor_Endpoint_t
* EndpointData 
= DESCRIPTOR_PCAST(ConfigDescriptorData
, USB_Descriptor_Endpoint_t
); 
  97                 if ((EndpointData
->Attributes 
& EP_TYPE_MASK
) == EP_TYPE_INTERRUPT
) 
  99                         if (EndpointData
->EndpointAddress 
& ENDPOINT_DESCRIPTOR_DIR_IN
) 
 101                                 Pipe_ConfigurePipe(RNDISInterfaceInfo
->Config
.NotificationPipeNumber
, EP_TYPE_INTERRUPT
, PIPE_TOKEN_IN
, 
 102                                                                    EndpointData
->EndpointAddress
, EndpointData
->EndpointSize
, 
 103                                                                    RNDISInterfaceInfo
->Config
.NotificationPipeDoubleBank ? PIPE_BANK_DOUBLE 
: PIPE_BANK_SINGLE
); 
 104                                 RNDISInterfaceInfo
->State
.NotificationPipeSize 
= EndpointData
->EndpointSize
; 
 106                                 Pipe_SetInterruptPeriod(EndpointData
->PollingIntervalMS
); 
 108                                 FoundEndpoints 
|= RNDIS_FOUND_NOTIFICATION_IN
; 
 113                         if (EndpointData
->EndpointAddress 
& ENDPOINT_DESCRIPTOR_DIR_IN
) 
 115                                 Pipe_ConfigurePipe(RNDISInterfaceInfo
->Config
.DataINPipeNumber
, EP_TYPE_BULK
, PIPE_TOKEN_IN
, 
 116                                                    EndpointData
->EndpointAddress
, EndpointData
->EndpointSize
,  
 117                                                    RNDISInterfaceInfo
->Config
.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE 
: PIPE_BANK_SINGLE
); 
 118                                 RNDISInterfaceInfo
->State
.DataINPipeSize 
= EndpointData
->EndpointSize
; 
 120                                 FoundEndpoints 
|= RNDIS_FOUND_DATAPIPE_IN
; 
 124                                 Pipe_ConfigurePipe(RNDISInterfaceInfo
->Config
.DataOUTPipeNumber
, EP_TYPE_BULK
, PIPE_TOKEN_OUT
, 
 125                                                    EndpointData
->EndpointAddress
, EndpointData
->EndpointSize
,  
 126                                                    RNDISInterfaceInfo
->Config
.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE 
: PIPE_BANK_SINGLE
); 
 127                                 RNDISInterfaceInfo
->State
.DataOUTPipeSize 
= EndpointData
->EndpointSize
; 
 129                                 FoundEndpoints 
|= RNDIS_FOUND_DATAPIPE_OUT
; 
 134         RNDISInterfaceInfo
->State
.IsActive 
= true; 
 135         return RNDIS_ENUMERROR_NoError
; 
 138 static uint8_t DCOMP_RNDIS_Host_NextRNDISControlInterface(void* const CurrentDescriptor
) 
 140         if (DESCRIPTOR_TYPE(CurrentDescriptor
) == DTYPE_Interface
) 
 142                 USB_Descriptor_Interface_t
* CurrentInterface 
= DESCRIPTOR_PCAST(CurrentDescriptor
, 
 143                                                                                 USB_Descriptor_Interface_t
); 
 145                 if ((CurrentInterface
->Class    
== RNDIS_CONTROL_CLASS
)    && 
 146                     (CurrentInterface
->SubClass 
== RNDIS_CONTROL_SUBCLASS
) && 
 147                         (CurrentInterface
->Protocol 
== RNDIS_CONTROL_PROTOCOL
)) 
 149                         return DESCRIPTOR_SEARCH_Found
; 
 153         return DESCRIPTOR_SEARCH_NotFound
; 
 156 static uint8_t DCOMP_RNDIS_Host_NextRNDISDataInterface(void* const CurrentDescriptor
) 
 158         if (DESCRIPTOR_TYPE(CurrentDescriptor
) == DTYPE_Interface
) 
 160                 USB_Descriptor_Interface_t
* CurrentInterface 
= DESCRIPTOR_PCAST(CurrentDescriptor
, 
 161                                                                                 USB_Descriptor_Interface_t
); 
 163                 if ((CurrentInterface
->Class    
== RNDIS_DATA_CLASS
)    && 
 164                     (CurrentInterface
->SubClass 
== RNDIS_DATA_SUBCLASS
) && 
 165                         (CurrentInterface
->Protocol 
== RNDIS_DATA_PROTOCOL
)) 
 167                         return DESCRIPTOR_SEARCH_Found
; 
 171         return DESCRIPTOR_SEARCH_NotFound
; 
 174 static uint8_t DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint(void* const CurrentDescriptor
) 
 176         if (DESCRIPTOR_TYPE(CurrentDescriptor
) == DTYPE_Endpoint
) 
 178                 USB_Descriptor_Endpoint_t
* CurrentEndpoint 
= DESCRIPTOR_PCAST(CurrentDescriptor
, 
 179                                                                               USB_Descriptor_Endpoint_t
); 
 181                 uint8_t EndpointType 
= (CurrentEndpoint
->Attributes 
& EP_TYPE_MASK
); 
 183                 if (((EndpointType 
== EP_TYPE_BULK
) || (EndpointType 
== EP_TYPE_INTERRUPT
)) && 
 184                     !(Pipe_IsEndpointBound(CurrentEndpoint
->EndpointAddress
))) 
 186                         return DESCRIPTOR_SEARCH_Found
; 
 189         else if (DESCRIPTOR_TYPE(CurrentDescriptor
) == DTYPE_Interface
) 
 191                 return DESCRIPTOR_SEARCH_Fail
; 
 194         return DESCRIPTOR_SEARCH_NotFound
; 
 197 static uint8_t RNDIS_SendEncapsulatedCommand(USB_ClassInfo_RNDIS_Host_t
* const RNDISInterfaceInfo
, 
 198                                              void* Buffer
, uint16_t Length
) 
 200         USB_ControlRequest 
= (USB_Request_Header_t
) 
 202                         .bmRequestType 
= (REQDIR_HOSTTODEVICE 
| REQTYPE_CLASS 
| REQREC_INTERFACE
), 
 203                         .bRequest      
= REQ_SendEncapsulatedCommand
, 
 205                         .wIndex        
= RNDISInterfaceInfo
->State
.ControlInterfaceNumber
, 
 209         Pipe_SelectPipe(PIPE_CONTROLPIPE
); 
 210         return USB_Host_SendControlRequest(Buffer
); 
 213 static uint8_t RNDIS_GetEncapsulatedResponse(USB_ClassInfo_RNDIS_Host_t
* const RNDISInterfaceInfo
, 
 214                                              void* Buffer
, uint16_t Length
) 
 216         USB_ControlRequest 
= (USB_Request_Header_t
) 
 218                         .bmRequestType 
= (REQDIR_DEVICETOHOST 
| REQTYPE_CLASS 
| REQREC_INTERFACE
), 
 219                         .bRequest      
= REQ_GetEncapsulatedResponse
, 
 221                         .wIndex        
= RNDISInterfaceInfo
->State
.ControlInterfaceNumber
, 
 225         Pipe_SelectPipe(PIPE_CONTROLPIPE
); 
 226         return USB_Host_SendControlRequest(Buffer
); 
 229 uint8_t RNDIS_Host_SendKeepAlive(USB_ClassInfo_RNDIS_Host_t
* const RNDISInterfaceInfo
) 
 233         RNDIS_KeepAlive_Message_t  KeepAliveMessage
; 
 234         RNDIS_KeepAlive_Complete_t KeepAliveMessageResponse
; 
 236         KeepAliveMessage
.MessageType     
= REMOTE_NDIS_KEEPALIVE_MSG
; 
 237         KeepAliveMessage
.MessageLength   
= sizeof(RNDIS_KeepAlive_Message_t
); 
 238         KeepAliveMessage
.RequestId       
= RNDISInterfaceInfo
->State
.RequestID
++; 
 240         if ((ErrorCode 
= RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo
, &KeepAliveMessage
, 
 241                                                        sizeof(RNDIS_KeepAlive_Message_t
))) != HOST_SENDCONTROL_Successful
) 
 246         if ((ErrorCode 
= RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo
, &KeepAliveMessageResponse
, 
 247                                                        sizeof(RNDIS_KeepAlive_Complete_t
))) != HOST_SENDCONTROL_Successful
) 
 252         return HOST_SENDCONTROL_Successful
; 
 255 uint8_t RNDIS_Host_InitializeDevice(USB_ClassInfo_RNDIS_Host_t
* const RNDISInterfaceInfo
) 
 259         RNDIS_Initialize_Message_t  InitMessage
; 
 260         RNDIS_Initialize_Complete_t InitMessageResponse
; 
 262         InitMessage
.MessageType     
= REMOTE_NDIS_INITIALIZE_MSG
; 
 263         InitMessage
.MessageLength   
= sizeof(RNDIS_Initialize_Message_t
); 
 264         InitMessage
.RequestId       
= RNDISInterfaceInfo
->State
.RequestID
++; 
 266         InitMessage
.MajorVersion    
= REMOTE_NDIS_VERSION_MAJOR
; 
 267         InitMessage
.MinorVersion    
= REMOTE_NDIS_VERSION_MINOR
; 
 268         InitMessage
.MaxTransferSize 
= RNDISInterfaceInfo
->Config
.HostMaxPacketSize
; 
 270         if ((ErrorCode 
= RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo
, &InitMessage
, 
 271                                                        sizeof(RNDIS_Initialize_Message_t
))) != HOST_SENDCONTROL_Successful
) 
 276         if ((ErrorCode 
= RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo
, &InitMessageResponse
, 
 277                                                        sizeof(RNDIS_Initialize_Complete_t
))) != HOST_SENDCONTROL_Successful
) 
 282         if (InitMessageResponse
.Status 
!= REMOTE_NDIS_STATUS_SUCCESS
) 
 283           return RNDIS_COMMAND_FAILED
; 
 285         RNDISInterfaceInfo
->State
.DeviceMaxPacketSize 
= InitMessageResponse
.MaxTransferSize
; 
 287         return HOST_SENDCONTROL_Successful
; 
 290 uint8_t RNDIS_Host_SetRNDISProperty(USB_ClassInfo_RNDIS_Host_t
* const RNDISInterfaceInfo
, uint32_t Oid
, void* Buffer
, uint16_t Length
) 
 296                 RNDIS_Set_Message_t SetMessage
; 
 297                 uint8_t             ContigiousBuffer
[Length
]; 
 300         RNDIS_Set_Complete_t SetMessageResponse
; 
 302         SetMessageData
.SetMessage
.MessageType    
= REMOTE_NDIS_SET_MSG
; 
 303         SetMessageData
.SetMessage
.MessageLength  
= sizeof(RNDIS_Set_Message_t
) + Length
; 
 304         SetMessageData
.SetMessage
.RequestId      
= RNDISInterfaceInfo
->State
.RequestID
++; 
 306         SetMessageData
.SetMessage
.Oid            
= Oid
; 
 307         SetMessageData
.SetMessage
.InformationBufferLength 
= Length
; 
 308         SetMessageData
.SetMessage
.InformationBufferOffset 
= (sizeof(RNDIS_Set_Message_t
) - sizeof(RNDIS_Message_Header_t
)); 
 309         SetMessageData
.SetMessage
.DeviceVcHandle 
= 0; 
 311         memcpy(&SetMessageData
.ContigiousBuffer
, Buffer
, Length
); 
 313         if ((ErrorCode 
= RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo
, &SetMessageData
, 
 314                                                        SetMessageData
.SetMessage
.MessageLength
)) != HOST_SENDCONTROL_Successful
) 
 319         if ((ErrorCode 
= RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo
, &SetMessageResponse
, 
 320                                                        sizeof(RNDIS_Set_Complete_t
))) != HOST_SENDCONTROL_Successful
) 
 325         if (SetMessageResponse
.Status 
!= REMOTE_NDIS_STATUS_SUCCESS
) 
 326           return RNDIS_COMMAND_FAILED
; 
 328         return HOST_SENDCONTROL_Successful
; 
 331 uint8_t RNDIS_Host_QueryRNDISProperty(USB_ClassInfo_RNDIS_Host_t
* const RNDISInterfaceInfo
, uint32_t Oid
, void* Buffer
, uint16_t MaxLength
) 
 335         RNDIS_Query_Message_t QueryMessage
; 
 339                 RNDIS_Query_Complete_t QueryMessageResponse
; 
 340                 uint8_t                ContigiousBuffer
[MaxLength
]; 
 341         } QueryMessageResponseData
; 
 343         QueryMessage
.MessageType    
= REMOTE_NDIS_QUERY_MSG
; 
 344         QueryMessage
.MessageLength  
= sizeof(RNDIS_Query_Message_t
); 
 345         QueryMessage
.RequestId      
= RNDISInterfaceInfo
->State
.RequestID
++; 
 347         QueryMessage
.Oid            
= Oid
; 
 348         QueryMessage
.InformationBufferLength 
= 0; 
 349         QueryMessage
.InformationBufferOffset 
= 0; 
 350         QueryMessage
.DeviceVcHandle 
= 0; 
 352         if ((ErrorCode 
= RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo
, &QueryMessage
, 
 353                                                        sizeof(RNDIS_Query_Message_t
))) != HOST_SENDCONTROL_Successful
) 
 358         if ((ErrorCode 
= RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo
, &QueryMessageResponseData
, 
 359                                                        sizeof(QueryMessageResponseData
))) != HOST_SENDCONTROL_Successful
) 
 364         if (QueryMessageResponseData
.QueryMessageResponse
.Status 
!= REMOTE_NDIS_STATUS_SUCCESS
) 
 365           return RNDIS_COMMAND_FAILED
; 
 367         memcpy(Buffer
, &QueryMessageResponseData
.ContigiousBuffer
, MaxLength
); 
 369         return HOST_SENDCONTROL_Successful
; 
 372 bool RNDIS_Host_IsPacketReceived(USB_ClassInfo_RNDIS_Host_t
* const RNDISInterfaceInfo
) 
 376         if ((USB_HostState 
!= HOST_STATE_Configured
) || !(RNDISInterfaceInfo
->State
.IsActive
)) 
 379         Pipe_SelectPipe(RNDISInterfaceInfo
->Config
.DataINPipeNumber
); 
 380         Pipe_SetPipeToken(PIPE_TOKEN_IN
); 
 384         PacketWaiting 
= Pipe_IsINReceived(); 
 388         return PacketWaiting
; 
 391 uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t
* const RNDISInterfaceInfo
, void* Buffer
, uint16_t* PacketLength
) 
 395         if ((USB_HostState 
!= HOST_STATE_Configured
) || !(RNDISInterfaceInfo
->State
.IsActive
)) 
 396           return PIPE_READYWAIT_DeviceDisconnected
; 
 398         Pipe_SelectPipe(RNDISInterfaceInfo
->Config
.DataINPipeNumber
); 
 399         Pipe_SetPipeToken(PIPE_TOKEN_IN
); 
 402         if (!(Pipe_IsReadWriteAllowed())) 
 404                 if (Pipe_IsINReceived()) 
 409                 return PIPE_RWSTREAM_NoError
; 
 412         RNDIS_Packet_Message_t DeviceMessage
; 
 414         if ((ErrorCode 
= Pipe_Read_Stream_LE(&DeviceMessage
, sizeof(RNDIS_Packet_Message_t
), 
 415                                              NO_STREAM_CALLBACK
)) != PIPE_RWSTREAM_NoError
) 
 420         *PacketLength 
= (uint16_t)DeviceMessage
.DataLength
; 
 422         Pipe_Discard_Stream(DeviceMessage
.DataOffset 
- (sizeof(RNDIS_Packet_Message_t
) - sizeof(RNDIS_Message_Header_t
)), 
 425         Pipe_Read_Stream_LE(Buffer
, *PacketLength
, NO_STREAM_CALLBACK
); 
 427         if (!(Pipe_BytesInPipe())) 
 432         return PIPE_RWSTREAM_NoError
; 
 435 uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t
* const RNDISInterfaceInfo
, void* Buffer
, uint16_t PacketLength
) 
 439         if ((USB_HostState 
!= HOST_STATE_Configured
) || !(RNDISInterfaceInfo
->State
.IsActive
)) 
 440           return PIPE_READYWAIT_DeviceDisconnected
; 
 442         RNDIS_Packet_Message_t DeviceMessage
; 
 444         memset(&DeviceMessage
, 0, sizeof(RNDIS_Packet_Message_t
)); 
 445         DeviceMessage
.MessageType   
= REMOTE_NDIS_PACKET_MSG
; 
 446         DeviceMessage
.MessageLength 
= (sizeof(RNDIS_Packet_Message_t
) + PacketLength
); 
 447         DeviceMessage
.DataOffset    
= (sizeof(RNDIS_Packet_Message_t
) - sizeof(RNDIS_Message_Header_t
)); 
 448         DeviceMessage
.DataLength    
= PacketLength
; 
 450         Pipe_SelectPipe(RNDISInterfaceInfo
->Config
.DataOUTPipeNumber
); 
 453         if ((ErrorCode 
= Pipe_Write_Stream_LE(&DeviceMessage
, sizeof(RNDIS_Packet_Message_t
), 
 454                                               NO_STREAM_CALLBACK
)) != PIPE_RWSTREAM_NoError
) 
 459         Pipe_Write_Stream_LE(Buffer
, PacketLength
, NO_STREAM_CALLBACK
); 
 464         return PIPE_RWSTREAM_NoError
;