@ -50,7 +50,10 @@ uint8_t ProcessConfigurationDescriptor(void)
uint8_t ConfigDescriptorData [ 512 ] ;
void * CurrConfigLocation = ConfigDescriptorData ;
uint16_t CurrConfigBytesRem ;
uint8_t FoundEndpoints = 0 ;
USB_Descriptor_Endpoint_t * DataINEndpoint = NULL ;
USB_Descriptor_Endpoint_t * DataOUTEndpoint = NULL ;
USB_Descriptor_Endpoint_t * NotificationEndpoint = NULL ;
/* Retrieve the entire configuration descriptor into the allocated buffer */
switch ( USB_Host_GetDeviceConfigDescriptor ( 1 , & CurrConfigBytesRem , ConfigDescriptorData , sizeof ( ConfigDescriptorData ) ) )
@ -65,105 +68,81 @@ uint8_t ProcessConfigurationDescriptor(void)
return ControlError ;
}
/* Get the CDC control interface from the configuration descriptor */
/* Get the first RNDIS control interface from the configuration descriptor */
if ( USB_GetNextDescriptorComp ( & CurrConfigBytesRem , & CurrConfigLocation ,
DComp_NextCDCControlInterface ) ! = DESCRIPTOR_SEARCH_COMP_Found )
{
/* Descriptor not found, error out */
return No RNDIS InterfaceFound;
return No Compatible InterfaceFound;
}
/* Get the IN and OUT data and IN notification endpoints for the RNDIS interface */
while ( FoundEndpoints ! = ( ( 1 < < RNDIS_NOTIFICATIONPIPE ) | ( 1 < < RNDIS_DATAPIPE_IN ) | ( 1 < < RNDIS_DATAPIPE_OUT ) ) )
while ( ! ( DataINEndpoint ) | | ! ( DataOUTEndpoint ) | | ! ( NotificationEndpoint ) )
{
/* Fetch the next bulk or interrupt endpoint from the current RNDIS interface */
/* Get the next RNDIS interface's endpoint descriptor */
if ( USB_GetNextDescriptorComp ( & CurrConfigBytesRem , & CurrConfigLocation ,
DComp_NextCDCDataInterfaceEndpoint ) ! = DESCRIPTOR_SEARCH_COMP_Found )
{
/* Check to see if the control interface's notification pipe has been found, if so search for the data interface */
if ( FoundEndpoints & ( 1 < < RNDIS_NOTIFICATIONPIPE ) )
/* Check if we have already found the control interface's notification endpoint or not */
if ( NotificationEndpoint )
{
/* Get the next CDC data interface from the configuration descriptor (RNDIS class has two CDC interfaces) */
/* Get the next RNDIS data interface from the configuration descriptor */
if ( USB_GetNextDescriptorComp ( & CurrConfigBytesRem , & CurrConfigLocation ,
DComp_NextCDCDataInterface ) ! = DESCRIPTOR_SEARCH_COMP_Found )
{
/* Descriptor not found, error out */
return No RNDIS InterfaceFound;
return No Compatible InterfaceFound;
}
/* Clear any found endpoints */
DataINEndpoint = NULL ;
DataOUTEndpoint = NULL ;
}
else
{
/* Clear the found endpoints mask, since any already processed endpoints aren't in the CDC interface we need */
FoundEndpoints = 0 ;
/* Disable any already configured pipes from the invalid RNDIS interfaces */
Pipe_SelectPipe ( RNDIS_NOTIFICATIONPIPE ) ;
Pipe_DisablePipe ( ) ;
Pipe_SelectPipe ( RNDIS_DATAPIPE_IN ) ;
Pipe_DisablePipe ( ) ;
Pipe_SelectPipe ( RNDIS_DATAPIPE_OUT ) ;
Pipe_DisablePipe ( ) ;
/* Get the next CDC control interface from the configuration descriptor (CDC class has two CDC interfaces) */
/* Get the next RNDIS control interface from the configuration descriptor */
if ( USB_GetNextDescriptorComp ( & CurrConfigBytesRem , & CurrConfigLocation ,
DComp_NextCDCControlInterface ) ! = DESCRIPTOR_SEARCH_COMP_Found )
{
/* Descriptor not found, error out */
return NoRNDISInterfaceFound ;
}
return NoCompatibleInterfaceFound ;
}
/* Fetch the next bulk or interrupt endpoint from the current CDC interface */
if ( USB_GetNextDescriptorComp ( & CurrConfigBytesRem , & CurrConfigLocation ,
DComp_NextCDCDataInterfaceEndpoint ) ! = DESCRIPTOR_SEARCH_COMP_Found )
{
/* Descriptor not found, error out */
return NoEndpointFound ;
/* Clear any found endpoints */
NotificationEndpoint = NULL ;
}
}
/* Retrieve the endpoint address from the endpoint descriptor */
USB_Descriptor_Endpoint_t * EndpointData = DESCRIPTOR_PCAST ( CurrConfigLocation , USB_Descriptor_Endpoint_t ) ;
/* Check if the found endpoint is a interrupt or bulk type descriptor */
if ( ( EndpointData - > Attributes & EP_TYPE_MASK ) = = EP_TYPE_INTERRUPT )
{
/* If the endpoint is a IN type interrupt endpoint */
/* If the endpoint is a IN type endpoint */
if ( EndpointData - > EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN )
{
/* Configure the notification pipe */
Pipe_ConfigurePipe ( RNDIS_NOTIFICATIONPIPE , EP_TYPE_INTERRUPT , PIPE_TOKEN_IN ,
EndpointData - > EndpointAddress , EndpointData - > EndpointSize , PIPE_BANK_SINGLE ) ;
Pipe_SetInterruptPeriod ( EndpointData - > PollingIntervalMS ) ;
/* Set the flag indicating that the notification pipe has been found */
FoundEndpoints | = ( 1 < < RNDIS_NOTIFICATIONPIPE ) ;
}
}
/* Check if the found endpoint is a interrupt or bulk type descriptor */
if ( ( EndpointData - > Attributes & EP_TYPE_MASK ) = = EP_TYPE_INTERRUPT )
NotificationEndpoint = EndpointData ;
else
{
/* Check if the endpoint is a bulk IN or bulk OUT endpoint */
if ( EndpointData - > EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN )
{
/* Configure the data IN pipe */
Pipe_ConfigurePipe ( RNDIS_DATAPIPE_IN , EP_TYPE_BULK , PIPE_TOKEN_IN ,
EndpointData - > EndpointAddress , EndpointData - > EndpointSize , PIPE_BANK_SINGLE ) ;
/* Set the flag indicating that the data IN pipe has been found */
FoundEndpoints | = ( 1 < < RNDIS_DATAPIPE_IN ) ;
DataINEndpoint = EndpointData ;
}
else
{
/* Configure the data OUT pipe */
Pipe_ConfigurePipe ( RNDIS_DATAPIPE_OUT , EP_TYPE_BULK , PIPE_TOKEN_OUT ,
EndpointData - > EndpointAddress , EndpointData - > EndpointSize , PIPE_BANK_SINGLE ) ;
/* Set the flag indicating that the data OUT pipe has been found */
FoundEndpoints | = ( 1 < < RNDIS_DATAPIPE_OUT ) ;
}
DataOUTEndpoint = EndpointData ;
}
}
/* Configure the RNDIS data IN pipe */
Pipe_ConfigurePipe ( RNDIS_DATA_IN_PIPE , EP_TYPE_BULK , PIPE_TOKEN_IN ,
DataINEndpoint - > EndpointAddress , DataINEndpoint - > EndpointSize , PIPE_BANK_SINGLE ) ;
/* Configure the RNDIS data OUT pipe */
Pipe_ConfigurePipe ( RNDIS_DATA_OUT_PIPE , EP_TYPE_BULK , PIPE_TOKEN_OUT ,
DataOUTEndpoint - > EndpointAddress , DataOUTEndpoint - > EndpointSize , PIPE_BANK_SINGLE ) ;
/* Configure the RNDIS notification pipe */
Pipe_ConfigurePipe ( RNDIS_NOTIFICATION_PIPE , EP_TYPE_INTERRUPT , PIPE_TOKEN_IN ,
NotificationEndpoint - > EndpointAddress , NotificationEndpoint - > EndpointSize , PIPE_BANK_SINGLE ) ;
Pipe_SetInterruptPeriod ( NotificationEndpoint - > PollingIntervalMS ) ;
/* Valid data found, return success */
return SuccessfulConfigRead ;
}