diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 2d8f986ae..a24f348f4 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -222,14 +222,16 @@ void cdcd_reset(uint8_t rhport) } } -bool cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length) +uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { // Only support ACM subclass TU_VERIFY ( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && - CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass); + CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass, 0); // Note: 0xFF can be used with RNDIS - TU_VERIFY(tu_within(CDC_COMM_PROTOCOL_NONE, itf_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA)); + TU_VERIFY(tu_within(CDC_COMM_PROTOCOL_NONE, itf_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA), 0); + + uint16_t len = 0; // Find available interface cdcd_interface_t * p_cdc = NULL; @@ -242,29 +244,29 @@ bool cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t break; } } - TU_ASSERT(p_cdc); + TU_ASSERT(p_cdc, 0); //------------- Control Interface -------------// p_cdc->itf_num = itf_desc->bInterfaceNumber; uint8_t const * p_desc = tu_desc_next( itf_desc ); - (*p_length) = sizeof(tusb_desc_interface_t); + len = sizeof(tusb_desc_interface_t); // Communication Functional Descriptors - while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) ) + while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && len <= max_len ) { - (*p_length) += tu_desc_len(p_desc); + len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) { // notification endpoint if any - TU_ASSERT( usbd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc) ); + TU_ASSERT( usbd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), 0 ); p_cdc->ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress; - (*p_length) += tu_desc_len(p_desc); + len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } @@ -276,15 +278,15 @@ bool cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t p_desc = tu_desc_next(p_desc); // Open endpoint pair - TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in) ); + TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in), 0 ); - (*p_length) += sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t); + len += sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t); } // Prepare for incoming data _prep_out_transaction(cdc_id); - return true; + return len; } // Invoked when class request DATA stage is finished. diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 69542a3b3..a2523d8d0 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -229,12 +229,12 @@ static inline uint32_t tud_cdc_write_available(void) //--------------------------------------------------------------------+ // INTERNAL USBD-CLASS DRIVER API //--------------------------------------------------------------------+ -void cdcd_init (void); -void cdcd_reset (uint8_t rhport); -bool cdcd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length); -bool cdcd_control_request (uint8_t rhport, tusb_control_request_t const * request); -bool cdcd_control_complete (uint8_t rhport, tusb_control_request_t const * request); -bool cdcd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); +void cdcd_init (void); +void cdcd_reset (uint8_t rhport); +uint16_t cdcd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +bool cdcd_control_request (uint8_t rhport, tusb_control_request_t const * request); +bool cdcd_control_complete (uint8_t rhport, tusb_control_request_t const * request); +bool cdcd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); #ifdef __cplusplus } diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 70ba956aa..9955f2f05 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -154,25 +154,29 @@ void mscd_reset(uint8_t rhport) tu_memclr(&_mscd_itf, sizeof(mscd_interface_t)); } -bool mscd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_len) +uint16_t mscd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { // only support SCSI's BOT protocol TU_VERIFY(TUSB_CLASS_MSC == itf_desc->bInterfaceClass && MSC_SUBCLASS_SCSI == itf_desc->bInterfaceSubClass && - MSC_PROTOCOL_BOT == itf_desc->bInterfaceProtocol); + MSC_PROTOCOL_BOT == itf_desc->bInterfaceProtocol, 0); + // Max length mus be at least 1 interface + 2 endpoints + TU_VERIFY(max_len >= sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t), 0); + + uint16_t len = 0; mscd_interface_t * p_msc = &_mscd_itf; // Open endpoint pair - TU_ASSERT( usbd_open_edpt_pair(rhport, tu_desc_next(itf_desc), 2, TUSB_XFER_BULK, &p_msc->ep_out, &p_msc->ep_in) ); + TU_ASSERT( usbd_open_edpt_pair(rhport, tu_desc_next(itf_desc), 2, TUSB_XFER_BULK, &p_msc->ep_out, &p_msc->ep_in), 0 ); p_msc->itf_num = itf_desc->bInterfaceNumber; - (*p_len) = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t); + len = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t); // Prepare for Command Block Wrapper - TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)) ); + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)), 0 ); - return true; + return len; } // Handle class control request diff --git a/src/class/msc/msc_device.h b/src/class/msc/msc_device.h index 66180777e..30ffd02e1 100644 --- a/src/class/msc/msc_device.h +++ b/src/class/msc/msc_device.h @@ -151,12 +151,12 @@ TU_ATTR_WEAK bool tud_msc_is_writable_cb(uint8_t lun); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void mscd_init (void); -void mscd_reset (uint8_t rhport); -bool mscd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length); -bool mscd_control_request (uint8_t rhport, tusb_control_request_t const * p_request); -bool mscd_control_complete (uint8_t rhport, tusb_control_request_t const * p_request); -bool mscd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); +void mscd_init (void); +void mscd_reset (uint8_t rhport); +uint16_t mscd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); +bool mscd_control_request (uint8_t rhport, tusb_control_request_t const * p_request); +bool mscd_control_complete (uint8_t rhport, tusb_control_request_t const * p_request); +bool mscd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); #ifdef __cplusplus } diff --git a/src/device/usbd.c b/src/device/usbd.c index f7918c07e..971417a35 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -85,13 +85,13 @@ typedef struct char const* name; #endif - void (* init ) (void); - void (* reset ) (uint8_t rhport); - bool (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t* p_length); - bool (* control_request ) (uint8_t rhport, tusb_control_request_t const * request); - bool (* control_complete ) (uint8_t rhport, tusb_control_request_t const * request); - bool (* xfer_cb ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); - void (* sof ) (uint8_t rhport); /* optional */ + void (* init ) (void); + void (* reset ) (uint8_t rhport); + uint16_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t max_len); + bool (* control_request ) (uint8_t rhport, tusb_control_request_t const * request); + bool (* control_complete ) (uint8_t rhport, tusb_control_request_t const * request); + bool (* xfer_cb ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); + void (* sof ) (uint8_t rhport); /* optional */ } usbd_class_driver_t; static usbd_class_driver_t const _usbd_driver[] = @@ -713,6 +713,8 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) ); tusb_desc_interface_t const * desc_itf = (tusb_desc_interface_t const*) p_desc; + uint16_t const remaining_len = desc_end-p_desc; + uint8_t drv_id; uint16_t drv_len; @@ -720,13 +722,17 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) { usbd_class_driver_t const *driver = &_usbd_driver[drv_id]; - drv_len = 0; - if ( driver->open(rhport, desc_itf, &drv_len) ) + drv_len = driver->open(rhport, desc_itf, remaining_len); + + if ( drv_len > 0 ) { + // Open successfully, check if length is correct + TU_ASSERT( sizeof(tusb_desc_interface_t) <= drv_len && drv_len <= remaining_len); + // Interface number must not be used already TU_ASSERT( DRVID_INVALID == _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] ); - TU_LOG2(" %s opened\r\n", _usbd_driver[drv_id].name); + TU_LOG2(" %s opened\r\n", driver->name); _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] = drv_id; // If IAD exist, assign all interfaces to the same driver @@ -748,8 +754,8 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) } } - // Assert if cannot find supported driver - TU_ASSERT( drv_id < USBD_CLASS_DRIVER_COUNT && drv_len >= sizeof(tusb_desc_interface_t) ); + // Failed if cannot find supported driver + TU_ASSERT(drv_id < USBD_CLASS_DRIVER_COUNT); mark_interface_endpoint(_usbd_dev.ep2drv, p_desc, drv_len, drv_id); // TODO refactor