Просмотр исходного кода

Merge pull request #344 from hathach/enhance-itf-assoc

Enhance Interface Associate descriptor handling
Ha Thach 5 лет назад
Родитель
Сommit
eb2aaa5de8
5 измененных файлов с 56 добавлено и 92 удалено
  1. 2 2
      src/class/cdc/cdc_device.c
  2. 8 22
      src/class/net/net_device.c
  3. 0 2
      src/class/net/net_device.h
  4. 43 49
      src/device/usbd.c
  5. 3 17
      src/device/usbd.h

+ 2 - 2
src/class/cdc/cdc_device.c

@@ -262,12 +262,12 @@ bool cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t
 
     p_cdc->ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress;
 
-    (*p_length) += p_desc[DESC_OFFSET_LEN];
+    (*p_length) += tu_desc_len(p_desc);
     p_desc = tu_desc_next(p_desc);
   }
 
   //------------- Data Interface (if any) -------------//
-  if ( (TUSB_DESC_INTERFACE == p_desc[DESC_OFFSET_TYPE]) &&
+  if ( (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) &&
        (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
   {
     // next to endpoint descriptor

+ 8 - 22
src/class/net/net_device.c

@@ -117,10 +117,6 @@ void netd_init(void)
   tu_memclr(&_netd_itf, sizeof(_netd_itf));
 }
 
-void netd_init_data(void)
-{
-}
-
 void netd_reset(uint8_t rhport)
 {
   (void) rhport;
@@ -166,32 +162,21 @@ bool netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t
 
     _netd_itf.ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress;
 
-    (*p_length) += p_desc[DESC_OFFSET_LEN];
+    (*p_length) += tu_desc_len(p_desc);
+    p_desc = tu_desc_next(p_desc);
   }
 
-  return true;
-}
-
-bool netd_open_data(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length)
-{
-  TU_VERIFY(TUSB_CLASS_CDC_DATA == itf_desc->bInterfaceClass);
-
-  // confirm interface hasn't already been allocated
-  TU_ASSERT(0 == _netd_itf.ep_in);
-
-  uint8_t const * p_desc = tu_desc_next( itf_desc );
-  (*p_length) = sizeof(tusb_desc_interface_t);
-
   //------------- Data Interface -------------//
-  while ( (TUSB_DESC_INTERFACE == p_desc[DESC_OFFSET_TYPE]) &&
-       (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
+  // TODO extract Alt Interface 0 & 1
+  while ((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) &&
+         (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
   {
     // next to endpoint descriptor
+    (*p_length) += tu_desc_len(p_desc);
     p_desc = tu_desc_next(p_desc);
-    (*p_length) += sizeof(tusb_desc_interface_t);
   }
 
-  if (TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE])
+  if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc))
   {
     // Open endpoint pair
     TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &_netd_itf.ep_out, &_netd_itf.ep_in) );
@@ -207,6 +192,7 @@ bool netd_open_data(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint
   // prepare for incoming packets
   tud_network_recv_renew();
 
+
   return true;
 }
 

+ 0 - 2
src/class/net/net_device.h

@@ -73,10 +73,8 @@ void tud_network_xmit(struct pbuf *p);
 // INTERNAL USBD-CLASS DRIVER API
 //--------------------------------------------------------------------+
 void netd_init             (void);
-void netd_init_data        (void);
 void netd_reset            (uint8_t rhport);
 bool netd_open             (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length);
-bool netd_open_data        (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length);
 bool netd_control_request  (uint8_t rhport, tusb_control_request_t const * request);
 bool netd_control_complete (uint8_t rhport, tusb_control_request_t const * request);
 bool netd_xfer_cb          (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);

+ 43 - 49
src/device/usbd.c

@@ -188,9 +188,8 @@ static usbd_class_driver_t const _usbd_driver[] =
   #endif
 
   #if CFG_TUD_NET
-  /* RNDIS management interface */
   {
-      DRIVER_NAME("RNDIS")
+      DRIVER_NAME("NET")
       .init             = netd_init,
       .reset            = netd_reset,
       .open             = netd_open,
@@ -199,30 +198,6 @@ static usbd_class_driver_t const _usbd_driver[] =
       .xfer_cb          = netd_xfer_cb,
       .sof              = NULL,
   },
-
-  /* CDC-ECM management interface */
-  {
-      DRIVER_NAME("CDC-ECM")
-      .init             = netd_init,
-      .reset            = netd_reset,
-      .open             = netd_open,
-      .control_request  = netd_control_request,
-      .control_complete = netd_control_complete,
-      .xfer_cb          = netd_xfer_cb,
-      .sof              = NULL,
-  },
-
-  /* RNDIS/CDC-ECM data interface */
-  {
-      DRIVER_NAME("CDC-DATA")
-      .init             = netd_init_data,
-      .reset            = NULL,
-      .open             = netd_open_data,
-      .control_request  = NULL,
-      .control_complete = NULL,
-      .xfer_cb          = netd_xfer_cb,
-      .sof              = NULL,
-  },
   #endif
 };
 
@@ -611,9 +586,10 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
           case TUSB_REQ_SET_INTERFACE:
           {
             uint8_t const alternate = (uint8_t) p_request->wValue;
+            (void) alternate;
 
             // TODO not support alternate interface yet
-            TU_ASSERT(alternate == 0);
+//            TU_ASSERT(alternate == 0);
             tud_control_status(rhport, p_request);
           }
           break;
@@ -727,41 +703,59 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num)
 
   while( p_desc < desc_end )
   {
-    // Each interface always starts with Interface or Association descriptor
+    tusb_desc_interface_assoc_t const * desc_itf_assoc = NULL;
+
+    // Class will always starts with Interface Association (if any) and then Interface descriptor
     if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) )
     {
-      p_desc = tu_desc_next(p_desc); // ignore Interface Association
-    }else
-    {
-      TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) );
+      desc_itf_assoc = (tusb_desc_interface_assoc_t const *) p_desc;
+      p_desc = tu_desc_next(p_desc); // next to Interface
+    }
 
-      tusb_desc_interface_t const * desc_itf = (tusb_desc_interface_t const*) p_desc;
+    TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) );
 
-      uint8_t drv_id;
-      uint16_t drv_len;
+    tusb_desc_interface_t const * desc_itf = (tusb_desc_interface_t const*) p_desc;
+    uint8_t drv_id;
+    uint16_t drv_len;
 
-      for (drv_id = 0; drv_id < USBD_CLASS_DRIVER_COUNT; drv_id++)
+    for (drv_id = 0; drv_id < USBD_CLASS_DRIVER_COUNT; drv_id++)
+    {
+      usbd_class_driver_t const *driver = &_usbd_driver[drv_id];
+
+      drv_len = 0;
+      if ( driver->open(rhport, desc_itf, &drv_len) )
       {
-        usbd_class_driver_t const *driver = &_usbd_driver[drv_id];
+        // Interface number must not be used already
+        TU_ASSERT( DRVID_INVALID == _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] );
 
-        drv_len = 0;
-        if ( driver->open(rhport, desc_itf, &drv_len) )
+        TU_LOG2("  %s open\r\n", _usbd_driver[drv_id].name);
+        _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] = drv_id;
+
+        // If IAD exist, assign all interfaces to the same driver
+        if (desc_itf_assoc)
         {
-          // Interface number must not be used already TODO alternate interface
-          TU_ASSERT( DRVID_INVALID == _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] );
-          TU_LOG2("  %s open\r\n", _usbd_driver[drv_id].name);
-          _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] = drv_id;
-          break;
+          // IAD's first interface number and class/subclass/protocol should match with opened interface
+          TU_ASSERT(desc_itf_assoc->bFirstInterface   == desc_itf->bInterfaceNumber   &&
+                    desc_itf_assoc->bFunctionClass    == desc_itf->bInterfaceClass    &&
+                    desc_itf_assoc->bFunctionSubClass == desc_itf->bInterfaceSubClass &&
+                    desc_itf_assoc->bFunctionProtocol == desc_itf->bInterfaceProtocol);
+
+          for(uint8_t i=1; i<desc_itf_assoc->bInterfaceCount; i++)
+          {
+            _usbd_dev.itf2drv[desc_itf->bInterfaceNumber+i] = drv_id;
+          }
         }
+
+        break;
       }
+    }
 
-      // Assert if cannot find supported driver
-      TU_ASSERT( drv_id < USBD_CLASS_DRIVER_COUNT && drv_len >= sizeof(tusb_desc_interface_t) );
+    // Assert if cannot find supported driver
+    TU_ASSERT( drv_id < USBD_CLASS_DRIVER_COUNT && drv_len >= sizeof(tusb_desc_interface_t) );
 
-      mark_interface_endpoint(_usbd_dev.ep2drv, p_desc, drv_len, drv_id); // TODO refactor
+    mark_interface_endpoint(_usbd_dev.ep2drv, p_desc, drv_len, drv_id); // TODO refactor
 
-      p_desc += drv_len; // next interface
-    }
+    p_desc += drv_len; // next interface
   }
 
   // invoke callback

+ 3 - 17
src/device/usbd.h

@@ -343,11 +343,13 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re
 //------------- CDC-ECM -------------//
 
 // Length of template descriptor: 71 bytes
-#define TUD_CDC_ECM_DESC_LEN  (9+5+5+13+7+9+9+7+7)
+#define TUD_CDC_ECM_DESC_LEN  (8+9+5+5+13+7+9+9+7+7)
 
 // CDC-ECM Descriptor Template
 // Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size.
 #define TUD_CDC_ECM_DESCRIPTOR(_itfnum, _desc_stridx, _mac_stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize, _maxsegmentsize) \
+  /* Interface Association */\
+  8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0, 0,\
   /* CDC Control Interface */\
   9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0, _desc_stridx,\
   /* CDC-ECM Header */\
@@ -410,22 +412,6 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re
   7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
 
 
-//------------- CDC-EEM -------------//
-
-// Length of template descriptor: 23 bytes
-#define TUD_CDC_EEM_DESC_LEN  (9+7+7)
-
-// CDC-EEM Descriptor Template
-// Interface number, description string index, EP data address (out, in) and size.
-#define TUD_CDC_EEM_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \
-  /* EEM Interface */\
-  9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ETHERNET_EMULATION_MODEL, CDC_COMM_PROTOCOL_ETHERNET_EMULATION_MODEL, _stridx,\
-  /* Endpoint In */\
-  7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
-  /* Endpoint Out */\
-  7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
-
-
 #ifdef __cplusplus
  }
 #endif