diff --git a/demos/host/src/cdc_serial_app.c b/demos/host/src/cdc_serial_app.c index cb07b0501..16a130c85 100644 --- a/demos/host/src/cdc_serial_app.c +++ b/demos/host/src/cdc_serial_app.c @@ -61,6 +61,9 @@ static uint8_t buffer_in[64] TUSB_CFG_ATTR_USBRAM; void tusbh_cdc_mounted_cb(uint8_t dev_addr) { // application set-up + + printf("a CDC device is mounted\n"); + osal_queue_flush(queue_hdl); tusbh_cdc_receive(dev_addr, buffer_in, sizeof(buffer_in), true); // first report } diff --git a/demos/host/src/keyboard_app.c b/demos/host/src/keyboard_app.c index c80ad6bc2..4e027a163 100644 --- a/demos/host/src/keyboard_app.c +++ b/demos/host/src/keyboard_app.c @@ -70,6 +70,9 @@ static inline void process_kbd_report(tusb_keyboard_report_t const * report); void tusbh_hid_keyboard_mounted_cb(uint8_t dev_addr) { // application set-up + + printf("a keyboard device is mounted\n"); + osal_queue_flush(queue_kbd_hdl); tusbh_hid_keyboard_get_report(dev_addr, (uint8_t*) &usb_keyboard_report); // first report } diff --git a/demos/host/src/mouse_app.c b/demos/host/src/mouse_app.c index b7eba887f..6845dacbb 100644 --- a/demos/host/src/mouse_app.c +++ b/demos/host/src/mouse_app.c @@ -70,6 +70,9 @@ static inline void process_mouse_report(tusb_mouse_report_t const * p_report); void tusbh_hid_mouse_mounted_cb(uint8_t dev_addr) { // application set-up + + printf("a mouse device is mounted\n"); + osal_queue_flush(queue_mouse_hdl); tusbh_hid_mouse_get_report(dev_addr, (uint8_t*) &usb_mouse_report); // first report } diff --git a/tests/lpc18xx_43xx/test/host/cdc/descriptor_cdc.c b/tests/lpc18xx_43xx/test/host/cdc/descriptor_cdc.c index 16af1db27..d6b36c92b 100644 --- a/tests/lpc18xx_43xx/test/host/cdc/descriptor_cdc.c +++ b/tests/lpc18xx_43xx/test/host/cdc/descriptor_cdc.c @@ -39,6 +39,9 @@ #include "tusb_option.h" #include "descriptor_cdc.h" +//--------------------------------------------------------------------+ +// CDC Serials +//--------------------------------------------------------------------+ TUSB_CFG_ATTR_USBRAM const cdc_configuration_desc_t cdc_config_descriptor = { @@ -160,3 +163,126 @@ const cdc_configuration_desc_t cdc_config_descriptor = .bInterval = 0 }, }; + +//--------------------------------------------------------------------+ +// CDC RNSID +//--------------------------------------------------------------------+ + +TUSB_CFG_ATTR_USBRAM +const cdc_configuration_desc_t rndis_config_descriptor = +{ + .configuration = + { + .bLength = sizeof(tusb_descriptor_configuration_t), + .bDescriptorType = TUSB_DESC_TYPE_CONFIGURATION, + + .wTotalLength = sizeof(cdc_configuration_desc_t), + .bNumInterfaces = 2, + + .bConfigurationValue = 1, + .iConfiguration = 0x00, + .bmAttributes = TUSB_DESC_CONFIG_ATT_BUS_POWER, + .bMaxPower = TUSB_DESC_CONFIG_POWER_MA(100) + }, + + // IAD points to CDC Interfaces + .cdc_iad = + { + .bLength = sizeof(tusb_descriptor_interface_association_t), + .bDescriptorType = TUSB_DESC_TYPE_INTERFACE_ASSOCIATION, + + .bFirstInterface = 1, + .bInterfaceCount = 2, + + .bFunctionClass = TUSB_CLASS_CDC, + .bFunctionSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, + .bFunctionProtocol = 0, + + .iFunction = 0 + }, + + + // USB CDC Serial Interface + //------------- CDC Communication Interface -------------// + .cdc_comm_interface = + { + .bLength = sizeof(tusb_descriptor_interface_t), + .bDescriptorType = TUSB_DESC_TYPE_INTERFACE, + .bInterfaceNumber = 1, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = TUSB_CLASS_CDC, + .bInterfaceSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, + .bInterfaceProtocol = 0xff, // RNDIS is vendor specific protocol + .iInterface = 0x00 + }, + + .cdc_header = + { + .bLength = sizeof(cdc_desc_func_header_t), + .bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC, + .bDescriptorSubType = CDC_FUNC_DESC_HEADER, + .bcdCDC = 0x0120 + }, + + .cdc_acm = + { + .bLength = sizeof(cdc_desc_func_abstract_control_management_t), + .bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC, + .bDescriptorSubType = CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, + .bmCapabilities = { 0 } + }, + + .cdc_union = + { + .bLength = sizeof(cdc_desc_func_union_t), // plus number of + .bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC, + .bDescriptorSubType = CDC_FUNC_DESC_UNION, + .bControlInterface = 1, + .bSubordinateInterface = 2, + }, + + .cdc_endpoint_notification = + { + .bLength = sizeof(tusb_descriptor_endpoint_t), + .bDescriptorType = TUSB_DESC_TYPE_ENDPOINT, + .bEndpointAddress = 0x81, + .bmAttributes = { .xfer = TUSB_XFER_INTERRUPT }, + .wMaxPacketSize = 8, + .bInterval = 0x0a // lowest polling rate + }, + + //------------- CDC Data Interface -------------// + .cdc_data_interface = + { + .bLength = sizeof(tusb_descriptor_interface_t), + .bDescriptorType = TUSB_DESC_TYPE_INTERFACE, + .bInterfaceNumber = 2, + .bAlternateSetting = 0x00, + .bNumEndpoints = 2, + .bInterfaceClass = TUSB_CLASS_CDC_DATA, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = 0x00 + }, + + .cdc_endpoint_out = + { + .bLength = sizeof(tusb_descriptor_endpoint_t), + .bDescriptorType = TUSB_DESC_TYPE_ENDPOINT, + .bEndpointAddress = 2, + .bmAttributes = { .xfer = TUSB_XFER_BULK }, + .wMaxPacketSize = 512, + .bInterval = 0 + }, + + .cdc_endpoint_in = + { + .bLength = sizeof(tusb_descriptor_endpoint_t), + .bDescriptorType = TUSB_DESC_TYPE_ENDPOINT, + .bEndpointAddress = 0x82, + .bmAttributes = { .xfer = TUSB_XFER_BULK }, + .wMaxPacketSize = 512, + .bInterval = 0 + }, +}; diff --git a/tests/lpc18xx_43xx/test/host/cdc/descriptor_cdc.h b/tests/lpc18xx_43xx/test/host/cdc/descriptor_cdc.h index 618896e1d..2b7774fb2 100644 --- a/tests/lpc18xx_43xx/test/host/cdc/descriptor_cdc.h +++ b/tests/lpc18xx_43xx/test/host/cdc/descriptor_cdc.h @@ -74,6 +74,7 @@ typedef struct } cdc_configuration_desc_t; extern const cdc_configuration_desc_t cdc_config_descriptor; +extern const cdc_configuration_desc_t rndis_config_descriptor; #ifdef __cplusplus } 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 e803137d4..51d3d2ce2 100644 --- a/tests/lpc18xx_43xx/test/host/cdc/test_cdc_host.c +++ b/tests/lpc18xx_43xx/test/host/cdc/test_cdc_host.c @@ -51,16 +51,16 @@ #include "descriptor_cdc.h" #include "cdc_host.h" -uint8_t dev_addr; -uint16_t length; +static uint8_t dev_addr; +static uint16_t length; -tusb_descriptor_interface_t const * p_comm_interface = &cdc_config_descriptor.cdc_comm_interface; -tusb_descriptor_endpoint_t const * p_endpoint_notification = &cdc_config_descriptor.cdc_endpoint_notification; -tusb_descriptor_endpoint_t const * p_endpoint_out = &cdc_config_descriptor.cdc_endpoint_out; -tusb_descriptor_endpoint_t const * p_endpoint_in = &cdc_config_descriptor.cdc_endpoint_in; +static tusb_descriptor_interface_t const * p_comm_interface = &cdc_config_descriptor.cdc_comm_interface; +static tusb_descriptor_endpoint_t const * p_endpoint_notification = &cdc_config_descriptor.cdc_endpoint_notification; +static tusb_descriptor_endpoint_t const * p_endpoint_out = &cdc_config_descriptor.cdc_endpoint_out; +static tusb_descriptor_endpoint_t const * p_endpoint_in = &cdc_config_descriptor.cdc_endpoint_in; extern cdch_data_t cdch_data[TUSB_CFG_HOST_DEVICE_MAX]; -cdch_data_t * p_cdc = &cdch_data[0]; +static cdch_data_t * p_cdc = &cdch_data[0]; void setUp(void) { @@ -149,6 +149,19 @@ void test_cdch_open_interface_number_check(void) } +void test_cdch_open_protocol_check(void) +{ + pipe_handle_t dummy_hld = { .dev_addr = 1 }; + hcd_pipe_open_IgnoreAndReturn(dummy_hld); + tusbh_cdc_mounted_cb_Expect(dev_addr); + + //------------- CUT -------------// + TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, cdch_open_subtask(dev_addr, p_comm_interface, &length) ); + + TEST_ASSERT_EQUAL(p_comm_interface->bInterfaceProtocol, p_cdc->interface_protocol); + +} + void test_cdch_open_acm_capacity_check(void) { pipe_handle_t dummy_hld = { .dev_addr = 1 }; 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 new file mode 100644 index 000000000..0e661073a --- /dev/null +++ b/tests/lpc18xx_43xx/test/host/cdc/test_cdc_rndis_host.c @@ -0,0 +1,93 @@ +/**************************************************************************/ +/*! + @file test_cdc_rndis_host.c + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2013, hathach (tinyusb.org) + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + This file is part of the tinyusb stack. +*/ +/**************************************************************************/ + +#include "stdlib.h" +#include "unity.h" +#include "tusb_option.h" +#include "errors.h" +#include "binary.h" +#include "type_helper.h" + +#include "mock_osal.h" +#include "mock_hcd.h" +#include "mock_usbh.h" +#include "mock_cdc_callback.h" + +#include "descriptor_cdc.h" +#include "cdc_host.h" + +static uint8_t dev_addr; +static uint16_t length; + +static tusb_descriptor_interface_t const * p_comm_interface = &rndis_config_descriptor.cdc_comm_interface; +static tusb_descriptor_endpoint_t const * p_endpoint_notification = &rndis_config_descriptor.cdc_endpoint_notification; +static tusb_descriptor_endpoint_t const * p_endpoint_out = &rndis_config_descriptor.cdc_endpoint_out; +static tusb_descriptor_endpoint_t const * p_endpoint_in = &rndis_config_descriptor.cdc_endpoint_in; + +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 }; + +extern cdch_data_t cdch_data[TUSB_CFG_HOST_DEVICE_MAX]; +static cdch_data_t * p_cdc = &cdch_data[0]; + + +void setUp(void) +{ + length = 0; + dev_addr = 1; + + cdch_init(); + + hcd_pipe_open_ExpectAndReturn(dev_addr, p_endpoint_notification, TUSB_CLASS_CDC, pipe_notification); + hcd_pipe_open_ExpectAndReturn(dev_addr, p_endpoint_out, TUSB_CLASS_CDC, pipe_out); + hcd_pipe_open_ExpectAndReturn(dev_addr, p_endpoint_in, TUSB_CLASS_CDC, pipe_int); + tusbh_cdc_mounted_cb_Expect(dev_addr); + + TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, cdch_open_subtask(dev_addr, p_comm_interface, &length) ); +} + +void tearDown(void) +{ + +} + +void test_(void) +{ + +} diff --git a/tinyusb/class/cdc_host.c b/tinyusb/class/cdc_host.c index 3831fc243..ac4338853 100644 --- a/tinyusb/class/cdc_host.c +++ b/tinyusb/class/cdc_host.c @@ -134,7 +134,8 @@ tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con return TUSB_ERROR_CDCH_UNSUPPORTED_SUBCLASS; } - if (CDC_COMM_PROTOCOL_ATCOMMAND != p_interface_desc->bInterfaceProtocol) + if ( !(is_in_range(CDC_COMM_PROTOCOL_ATCOMMAND, p_interface_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) || + 0xff == p_interface_desc->bInterfaceProtocol) ) { return TUSB_ERROR_CDCH_UNSUPPORTED_PROTOCOL; } diff --git a/tinyusb/common/common.h b/tinyusb/common/common.h index ed543de00..3a43f123c 100644 --- a/tinyusb/common/common.h +++ b/tinyusb/common/common.h @@ -192,6 +192,21 @@ static inline uint32_t offset4k(uint32_t value) } //------------- Mathematics -------------// +/// inclusive range checking +static inline bool is_in_range(uint32_t lower, uint32_t value, uint32_t upper) ATTR_ALWAYS_INLINE ATTR_CONST; +static inline bool is_in_range(uint32_t lower, uint32_t value, uint32_t upper) +{ + return (lower <= value) && (value <= upper); +} + +/// exclusive range checking +static inline bool is_in_range_exclusive(uint32_t lower, uint32_t value, uint32_t upper) ATTR_ALWAYS_INLINE ATTR_CONST; +static inline bool is_in_range_exclusive(uint32_t lower, uint32_t value, uint32_t upper) +{ + return (lower < value) && (value < upper); +} + + static inline uint8_t log2_of(uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST; static inline uint8_t log2_of(uint32_t value) {