From 355fd7e64867093ee5974056c7735a60dd0f64e7 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Jul 2013 16:22:42 +0700 Subject: [PATCH] adding subclass RNDIS-CDC driver API - implement init - close - xfer_isr - open adding waiting for notification after send rndis_initalize_msg --- .../test/host/cdc/test_cdc_host.c | 2 +- .../test/host/cdc/test_cdc_rndis_host.c | 60 +++++++++++++++++-- tinyusb/class/cdc.h | 2 +- tinyusb/class/cdc_host.c | 28 ++++++++- tinyusb/class/cdc_host.h | 4 +- tinyusb/class/cdc_rndis_host.c | 40 ++++++++++++- tinyusb/class/cdc_rndis_host.h | 15 +++++ 7 files changed, 138 insertions(+), 13 deletions(-) diff --git a/tests/lpc18xx_43xx/test/host/cdc/test_cdc_host.c b/tests/lpc18xx_43xx/test/host/cdc/test_cdc_host.c index 4647f294d..12f29d40b 100644 --- a/tests/lpc18xx_43xx/test/host/cdc/test_cdc_host.c +++ b/tests/lpc18xx_43xx/test/host/cdc/test_cdc_host.c @@ -68,7 +68,7 @@ void setUp(void) length = 0; dev_addr = 1; - cdch_init(); + memclr_(cdch_data, sizeof(cdch_data_t)*TUSB_CFG_HOST_DEVICE_MAX); } void tearDown(void) diff --git a/tests/lpc18xx_43xx/test/host/cdc/test_cdc_rndis_host.c b/tests/lpc18xx_43xx/test/host/cdc/test_cdc_rndis_host.c index be676652a..abc844b05 100644 --- a/tests/lpc18xx_43xx/test/host/cdc/test_cdc_rndis_host.c +++ b/tests/lpc18xx_43xx/test/host/cdc/test_cdc_rndis_host.c @@ -62,10 +62,13 @@ static tusb_descriptor_endpoint_t const * p_endpoint_in = &rndis_config_descript static pipe_handle_t pipe_notification = { .dev_addr = 1, .xfer_type = TUSB_XFER_INTERRUPT }; static pipe_handle_t pipe_out = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 0 }; -static pipe_handle_t pipe_int = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 1 }; +static pipe_handle_t pipe_in = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 1 }; extern cdch_data_t cdch_data[TUSB_CFG_HOST_DEVICE_MAX]; +extern rndish_data_t rndish_data[TUSB_CFG_HOST_DEVICE_MAX]; + static cdch_data_t * p_cdc = &cdch_data[0]; +static rndish_data_t * p_rndis = &rndish_data[0]; void stub_mutex_wait(osal_mutex_handle_t mutex_hdl, uint32_t msec, tusb_error_t *p_error, int num_call) @@ -78,6 +81,11 @@ void setUp(void) length = 0; dev_addr = 1; + for (uint8_t i=0; isem_notification_hdl, sem_hdl); + (*p_error) = TUSB_ERROR_NONE; +} + +void stub_sem_wait_timeout(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call) +{ + (*p_error) = TUSB_ERROR_OSAL_TIMEOUT; +} + +void test_rndis_initialization_notification_timeout(void) { usbh_control_xfer_subtask_ExpectWithArrayAndReturn( dev_addr, 0x21, SEND_ENCAPSULATED_COMMAND, 0, p_comm_interface->bInterfaceNumber, sizeof(rndis_msg_initialize_t), (uint8_t*)&msg_init, sizeof(rndis_msg_initialize_t), TUSB_ERROR_NONE); + hcd_pipe_xfer_IgnoreAndReturn(TUSB_ERROR_NONE); + osal_semaphore_wait_StubWithCallback(stub_sem_wait_timeout); + + tusbh_cdc_mounted_cb_Expect(dev_addr); + + //------------- Code Under Test -------------// + TEST_ASSERT_STATUS( cdch_open_subtask(dev_addr, p_comm_interface, &length) ); + TEST_ASSERT_FALSE(p_cdc->is_rndis); +} + +void test_rndis_initialization_sequence_ok(void) +{ + usbh_control_xfer_subtask_ExpectWithArrayAndReturn( + dev_addr, 0x21, SEND_ENCAPSULATED_COMMAND, 0, p_comm_interface->bInterfaceNumber, + sizeof(rndis_msg_initialize_t), (uint8_t*)&msg_init, sizeof(rndis_msg_initialize_t), TUSB_ERROR_NONE); + + hcd_pipe_xfer_StubWithCallback(stub_pipe_notification_xfer); + osal_semaphore_wait_StubWithCallback(stub_sem_wait_success); + osal_semaphore_post_ExpectAndReturn(p_rndis->sem_notification_hdl, TUSB_ERROR_NONE); tusbh_cdc_rndis_mounted_cb_Expect(dev_addr); //------------- Code Under Test -------------// - TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, cdch_open_subtask(dev_addr, p_comm_interface, &length) ); + TEST_ASSERT_STATUS( cdch_open_subtask(dev_addr, p_comm_interface, &length) ); + TEST_ASSERT(p_cdc->is_rndis); } diff --git a/tinyusb/class/cdc.h b/tinyusb/class/cdc.h index b8a60bee2..faa6310fa 100644 --- a/tinyusb/class/cdc.h +++ b/tinyusb/class/cdc.h @@ -265,7 +265,7 @@ typedef ATTR_PACKED_STRUCT(struct) { uint8_t bDataInterface; }cdc_desc_func_call_management_t; -typedef struct { +typedef ATTR_PACKED_STRUCT(struct) { uint8_t support_comm_request : 1; ///< Device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature. uint8_t support_line_request : 1; ///< Device supports the request combination of Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State. uint8_t support_send_break : 1; ///< Device supports the request Send_Break diff --git a/tinyusb/class/cdc_host.c b/tinyusb/class/cdc_host.c index 2b81b9ab6..ebe108658 100644 --- a/tinyusb/class/cdc_host.c +++ b/tinyusb/class/cdc_host.c @@ -125,6 +125,9 @@ tusb_error_t tusbh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t lengt void cdch_init(void) { memclr_(cdch_data, sizeof(cdch_data_t)*TUSB_CFG_HOST_DEVICE_MAX); +#if TUSB_CFG_HOST_CDC_RNDIS + rndish_init(); +#endif } tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t const *p_interface_desc, uint16_t *p_length) @@ -200,12 +203,19 @@ tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con #if TUSB_CFG_HOST_CDC_RNDIS // TODO move to rndis_host.c //------------- RNDIS -------------// - if ( 0xff == p_cdc->interface_protocol ) + if ( 0xff == p_cdc->interface_protocol && pipehandle_is_valid(p_cdc->pipe_notification) ) { + p_cdc->is_rndis = true; // set as true at first + OSAL_SUBTASK_INVOKED_AND_WAIT( rndish_open_subtask(dev_addr, p_cdc), error ); + + if (TUSB_ERROR_NONE != error) + { + p_cdc->is_rndis = false; + } } - if ( !(0xff == p_cdc->interface_protocol && TUSB_ERROR_NONE == error) ) // device is not an rndis + if ( !p_cdc->is_rndis ) // device is not an rndis #endif // FIXME mounted class flag is not set yet @@ -219,6 +229,14 @@ tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con void cdch_isr(pipe_handle_t pipe_hdl, tusb_event_t event, uint32_t xferred_bytes) { + cdch_data_t *p_cdc = cdch_data + (pipe_hdl.dev_addr - 1); + +#if TUSB_CFG_HOST_CDC_RNDIS + if ( p_cdc->is_rndis ) + { + rndish_xfer_isr(p_cdc, pipe_hdl, event, xferred_bytes); + } else +#endif if (tusbh_cdc_xfer_isr) { tusbh_cdc_xfer_isr( pipe_hdl.dev_addr, event, get_app_pipeid(pipe_hdl), xferred_bytes ); @@ -230,6 +248,12 @@ void cdch_close(uint8_t dev_addr) tusb_error_t err1, err2, err3; cdch_data_t * p_cdc = &cdch_data[dev_addr-1]; +#if TUSB_CFG_HOST_CDC_RNDIS + if (p_cdc->is_rndis) + { + rndish_close(dev_addr); + } +#endif if ( pipehandle_is_valid(p_cdc->pipe_notification) ) { diff --git a/tinyusb/class/cdc_host.h b/tinyusb/class/cdc_host.h index 1d852c4eb..d45b047ab 100644 --- a/tinyusb/class/cdc_host.h +++ b/tinyusb/class/cdc_host.h @@ -71,7 +71,6 @@ tusb_error_t tusbh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t lengt //------------- CDC Application Callback -------------// void tusbh_cdc_mounted_cb(uint8_t dev_addr) ATTR_WEAK; void tusbh_cdc_unmounted_isr(uint8_t dev_addr) ATTR_WEAK; -void tusbh_cdc_isr(uint8_t dev_addr, tusb_event_t event) ATTR_WEAK; void tusbh_cdc_xfer_isr(uint8_t dev_addr, tusb_event_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes) ATTR_WEAK; //------------- RNDIS Application Callback (overshadow CDC callbacks) -------------// @@ -79,7 +78,7 @@ void tusbh_cdc_xfer_isr(uint8_t dev_addr, tusb_event_t event, cdc_pipeid_t pipe_ void tusbh_cdc_rndis_mounted_cb(uint8_t dev_addr) ATTR_WEAK; void tusbh_cdc_rndis_unmounted_isr(uint8_t dev_addr) ATTR_WEAK; - +void tusbh_cdc_rndis_xfer_isr(uint8_t dev_addr, tusb_event_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes) ATTR_WEAK; #endif @@ -91,6 +90,7 @@ void tusbh_cdc_rndis_unmounted_isr(uint8_t dev_addr) ATTR_WEAK; typedef struct { uint8_t interface_number; uint8_t interface_protocol; + bool is_rndis; cdc_acm_capability_t acm_capability; pipe_handle_t pipe_notification, pipe_out, pipe_in; diff --git a/tinyusb/class/cdc_rndis_host.c b/tinyusb/class/cdc_rndis_host.c index 585cf7d42..b01bebc7a 100644 --- a/tinyusb/class/cdc_rndis_host.c +++ b/tinyusb/class/cdc_rndis_host.c @@ -53,6 +53,7 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ static uint8_t msg_notification[TUSB_CFG_HOST_DEVICE_MAX][8] TUSB_CFG_ATTR_USBRAM; +STATIC_ rndish_data_t rndish_data[TUSB_CFG_HOST_DEVICE_MAX]; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION @@ -91,7 +92,26 @@ static tusb_error_t rndis_body_subtask(void) OSAL_SUBTASK_END } +//--------------------------------------------------------------------+ +// RNDIS-CDC Driver API +//--------------------------------------------------------------------+ +void rndish_init(void) +{ + memclr_(rndish_data, sizeof(rndish_data_t)*TUSB_CFG_HOST_DEVICE_MAX); + //------------- Task creation -------------// + + //------------- semaphore creation for notificaiton pipe -------------// + for(uint8_t i=0; iinterface_number, @@ -116,10 +137,15 @@ tusb_error_t rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc) error ); - if ( TUSB_ERROR_NONE != error) - { + if ( TUSB_ERROR_NONE != error ) + SUBTASK_EXIT(error); + + //------------- waiting for Response Available notification -------------// + (void) hcd_pipe_xfer(p_cdc->pipe_notification, msg_notification[dev_addr], 8, true); + osal_semaphore_wait(rndish_data[dev_addr-1].sem_notification_hdl, OSAL_TIMEOUT_NORMAL, &error); + + if ( TUSB_ERROR_NONE != error ) SUBTASK_EXIT(error); - } if ( tusbh_cdc_rndis_mounted_cb ) { @@ -129,4 +155,12 @@ tusb_error_t rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc) OSAL_SUBTASK_END } +void rndish_xfer_isr(cdch_data_t *p_cdc, pipe_handle_t pipe_hdl, tusb_event_t event, uint32_t xferred_bytes) +{ + if ( pipehandle_is_equal(pipe_hdl, p_cdc->pipe_notification) ) + { + osal_semaphore_post( rndish_data[pipe_hdl.dev_addr-1].sem_notification_hdl ); + } +} + #endif diff --git a/tinyusb/class/cdc_rndis_host.h b/tinyusb/class/cdc_rndis_host.h index ce8e4bced..8a2bca397 100644 --- a/tinyusb/class/cdc_rndis_host.h +++ b/tinyusb/class/cdc_rndis_host.h @@ -54,7 +54,22 @@ extern "C" { #endif +//--------------------------------------------------------------------+ +// RNDIS-CDC Driver API +//--------------------------------------------------------------------+ +#ifdef _TINY_USB_SOURCE_FILE_ + +typedef struct { + OSAL_SEM_DEF(semaphore_notification); + osal_semaphore_handle_t sem_notification_hdl; // used to wait on notification pipe +}rndish_data_t; + +void rndish_init(void); tusb_error_t rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc) ATTR_WARN_UNUSED_RESULT; +void rndish_xfer_isr(cdch_data_t *p_cdc, pipe_handle_t pipe_hdl, tusb_event_t event, uint32_t xferred_bytes); +void rndish_close(uint8_t dev_addr); + +#endif #ifdef __cplusplus }