tinyusb/src/device/usbd.c
static bool process_set_config(uint8_t rhport)
{
  uint8_t const * desc_cfg = (uint8_t const *) usbd_desc_set->config;
  TU_ASSERT(desc_cfg != NULL);

  uint8_t const * p_desc = desc_cfg + sizeof(tusb_desc_configuration_t);
  uint16_t const cfg_len = ((tusb_desc_configuration_t*)desc_cfg)->wTotalLength;

  while( p_desc < desc_cfg + cfg_len )
  {
    // Each interface always starts with Interface or Association descriptor
    if ( TUSB_DESC_INTERFACE_ASSOCIATION == descriptor_type(p_desc) )
    {
      p_desc = descriptor_next(p_desc); // ignore Interface Association
    }else
    {
      TU_ASSERT( TUSB_DESC_INTERFACE == descriptor_type(p_desc) );

      tusb_desc_interface_t* desc_itf = (tusb_desc_interface_t*) p_desc;

      // Check if class is supported
      uint8_t drv_id;
      for (drv_id = 0; drv_id < USBD_CLASS_DRIVER_COUNT; drv_id++)
      {
        if ( usbd_class_drivers[drv_id].class_code == desc_itf->bInterfaceClass ) break;
      }
      TU_ASSERT( drv_id < USBD_CLASS_DRIVER_COUNT ); // unsupported class

      // Interface number must not be used already TODO alternate interface
      TU_ASSERT( 0xff == _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] );
      _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] = drv_id;

      uint16_t len=0;
      TU_ASSERT_ERR( usbd_class_drivers[drv_id].open( rhport, desc_itf, &len ), false );
      TU_ASSERT( len >= sizeof(tusb_desc_interface_t) );

      mark_interface_endpoint(p_desc, len, drv_id);

      p_desc += len; // next interface
    }
  }

  // invoke callback
  tud_mount_cb();

  return TUSB_ERROR_NONE;
}
// Process Set Configure Request
// This function parse configuration descriptor & open drivers accordingly

Process Set Configure Request
This function parse configuration descriptor & open drivers accordingly
Process Set Configure Request This function parse configuration descriptor & open drivers accordingly
static bool process_set_config(uint8_t rhport)
{
  uint8_t const * desc_cfg = (uint8_t const *) usbd_desc_set->config;
  TU_ASSERT(desc_cfg != NULL);
  uint8_t const * p_desc = desc_cfg + sizeof(tusb_desc_configuration_t);
  uint16_t const cfg_len = ((tusb_desc_configuration_t*)desc_cfg)->wTotalLength;
  while( p_desc < desc_cfg + cfg_len )
  {
    if ( TUSB_DESC_INTERFACE_ASSOCIATION == descriptor_type(p_desc) )
    {
      p_desc = descriptor_next(p_desc); 
    }else
    {
      TU_ASSERT( TUSB_DESC_INTERFACE == descriptor_type(p_desc) );
      tusb_desc_interface_t* desc_itf = (tusb_desc_interface_t*) p_desc;
      uint8_t drv_id;
      for (drv_id = 0; drv_id < USBD_CLASS_DRIVER_COUNT; drv_id++)
      {
        if ( usbd_class_drivers[drv_id].class_code == desc_itf->bInterfaceClass ) break;
      }
      TU_ASSERT( drv_id < USBD_CLASS_DRIVER_COUNT ); 
      TU_ASSERT( 0xff == _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] );
      _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] = drv_id;
      uint16_t len=0;
      TU_ASSERT_ERR( usbd_class_drivers[drv_id].open( rhport, desc_itf, &len ), false );
      TU_ASSERT( len >= sizeof(tusb_desc_interface_t) );
      mark_interface_endpoint(p_desc, len, drv_id);
      p_desc += len; 
    }
  }
  tud_mount_cb();
  return TUSB_ERROR_NONE;
}
static bool process_set_config ( uint8_t rhport ) { uint8_t const * desc_cfg = ( uint8_t const * ) usbd_desc_set -> config ; TU_ASSERT ( desc_cfg != NULL ) ; uint8_t const * p_desc = desc_cfg + sizeof ( tusb_desc_configuration_t ) ; uint16_t const cfg_len = ( ( tusb_desc_configuration_t * ) desc_cfg ) -> wTotalLength ; while ( p_desc < desc_cfg + cfg_len ) { if ( TUSB_DESC_INTERFACE_ASSOCIATION == descriptor_type ( p_desc ) ) { p_desc = descriptor_next ( p_desc ) ; } else { TU_ASSERT ( TUSB_DESC_INTERFACE == descriptor_type ( p_desc ) ) ; tusb_desc_interface_t * desc_itf = ( tusb_desc_interface_t * ) p_desc ; uint8_t drv_id ; for ( drv_id = 0 ; drv_id < USBD_CLASS_DRIVER_COUNT ; drv_id ++ ) { if ( usbd_class_drivers [ drv_id ] . class_code == desc_itf -> bInterfaceClass ) break ; } TU_ASSERT ( drv_id < USBD_CLASS_DRIVER_COUNT ) ; TU_ASSERT ( 0xff == _usbd_dev . itf2drv [ desc_itf -> bInterfaceNumber ] ) ; _usbd_dev . itf2drv [ desc_itf -> bInterfaceNumber ] = drv_id ; uint16_t len = 0 ; TU_ASSERT_ERR ( usbd_class_drivers [ drv_id ] . open ( rhport , desc_itf , & len ) , false ) ; TU_ASSERT ( len >= sizeof ( tusb_desc_interface_t ) ) ; mark_interface_endpoint ( p_desc , len , drv_id ) ; p_desc += len ; } } tud_mount_cb ( ) ; return TUSB_ERROR_NONE ; }
Process Set Configure Request
This function parse configuration descriptor & open drivers accordingly
Process Set Configure Request This function parse configuration descriptor & open drivers accordingly
// Each interface always starts with Interface or Association descriptor
 // ignore Interface Association
 // Check if class is supported
 // unsupported class
 // Interface number must not be used already TODO alternate interface
 // next interface
 // invoke callback
