summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2025-05-16 21:10:02 +0700
committerGitHub <[email protected]>2025-05-16 21:10:02 +0700
commit3024bff12f584302ec2aaa77bcbbb2faf17b183f (patch)
tree652923263998d67a42e026295ee40b12217a825f
parent531fb695312b0e1cdade446b68d7049053897405 (diff)
parent67389f37f2a9dabc33b9f180d49c827e9616572c (diff)
Merge pull request #3123 from hathach/follow-up-pr3118
follow up to pr3118, interface also end with IAD. Add more checks
-rw-r--r--src/class/vendor/vendor_device.c22
-rw-r--r--src/common/tusb_types.h6
2 files changed, 21 insertions, 7 deletions
diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c
index 0f0b0cbb2..7f1fd8c41 100644
--- a/src/class/vendor/vendor_device.c
+++ b/src/class/vendor/vendor_device.c
@@ -196,8 +196,8 @@ void vendord_reset(uint8_t rhport) {
uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uint16_t max_len) {
TU_VERIFY(TUSB_CLASS_VENDOR_SPECIFIC == desc_itf->bInterfaceClass, 0);
- const uint8_t* p_desc = tu_desc_next(desc_itf);
const uint8_t* desc_end = (const uint8_t*)desc_itf + max_len;
+ const uint8_t* p_desc = tu_desc_next(desc_itf);
// Find available interface
vendord_interface_t* p_vendor = NULL;
@@ -210,17 +210,25 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uin
TU_VERIFY(p_vendor, 0);
p_vendor->itf_num = desc_itf->bInterfaceNumber;
- while (TUSB_DESC_INTERFACE != tu_desc_type(p_desc) && (desc_end - p_desc > 0)) {
- if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) {
+ while (tu_desc_is_valid(p_desc, desc_end)) {
+ const uint8_t desc_type = tu_desc_type(p_desc);
+ if (desc_type == TUSB_DESC_INTERFACE || desc_type == TUSB_DESC_INTERFACE_ASSOCIATION) {
+ break; // end of this interface
+ } else if (desc_type == TUSB_DESC_ENDPOINT) {
const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc;
TU_ASSERT(usbd_edpt_open(rhport, desc_ep));
+ // open endpoint stream, skip if already opened
if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) {
- tu_edpt_stream_open(&p_vendor->tx.stream, desc_ep);
- tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf));
+ if (p_vendor->tx.stream.ep_addr == 0) {
+ tu_edpt_stream_open(&p_vendor->tx.stream, desc_ep);
+ tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf));
+ }
} else {
- tu_edpt_stream_open(&p_vendor->rx.stream, desc_ep);
- TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_vendor->rx.stream) > 0, 0); // prepare for incoming data
+ if (p_vendor->rx.stream.ep_addr == 0) {
+ tu_edpt_stream_open(&p_vendor->rx.stream, desc_ep);
+ TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_vendor->rx.stream) > 0, 0); // prepare for incoming data
+ }
}
}
diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h
index e000a4bd3..fd7f01b67 100644
--- a/src/common/tusb_types.h
+++ b/src/common/tusb_types.h
@@ -586,6 +586,12 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_subtype(void const* desc) {
return ((uint8_t const*) desc)[DESC_OFFSET_SUBTYPE];
}
+TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_is_valid(void const* desc, uint8_t const* desc_end) {
+ const uint8_t* desc8 = (uint8_t const*) desc;
+ return (desc8 < desc_end) && (tu_desc_next(desc) <= desc_end);
+}
+
+
// find descriptor that match byte1 (type)
uint8_t const * tu_desc_find(uint8_t const* desc, uint8_t const* end, uint8_t byte1);