Skip to content

Commit 67389f3

Browse files
committed
follow up to pr3118, interface also end with IAD. Add more checks
1 parent 531fb69 commit 67389f3

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

src/class/vendor/vendor_device.c

+15-7
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ void vendord_reset(uint8_t rhport) {
196196

197197
uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uint16_t max_len) {
198198
TU_VERIFY(TUSB_CLASS_VENDOR_SPECIFIC == desc_itf->bInterfaceClass, 0);
199-
const uint8_t* p_desc = tu_desc_next(desc_itf);
200199
const uint8_t* desc_end = (const uint8_t*)desc_itf + max_len;
200+
const uint8_t* p_desc = tu_desc_next(desc_itf);
201201

202202
// Find available interface
203203
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
210210
TU_VERIFY(p_vendor, 0);
211211

212212
p_vendor->itf_num = desc_itf->bInterfaceNumber;
213-
while (TUSB_DESC_INTERFACE != tu_desc_type(p_desc) && (desc_end - p_desc > 0)) {
214-
if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) {
213+
while (tu_desc_is_valid(p_desc, desc_end)) {
214+
const uint8_t desc_type = tu_desc_type(p_desc);
215+
if (desc_type == TUSB_DESC_INTERFACE || desc_type == TUSB_DESC_INTERFACE_ASSOCIATION) {
216+
break; // end of this interface
217+
} else if (desc_type == TUSB_DESC_ENDPOINT) {
215218
const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc;
216219
TU_ASSERT(usbd_edpt_open(rhport, desc_ep));
217220

221+
// open endpoint stream, skip if already opened
218222
if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) {
219-
tu_edpt_stream_open(&p_vendor->tx.stream, desc_ep);
220-
tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf));
223+
if (p_vendor->tx.stream.ep_addr == 0) {
224+
tu_edpt_stream_open(&p_vendor->tx.stream, desc_ep);
225+
tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf));
226+
}
221227
} else {
222-
tu_edpt_stream_open(&p_vendor->rx.stream, desc_ep);
223-
TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_vendor->rx.stream) > 0, 0); // prepare for incoming data
228+
if (p_vendor->rx.stream.ep_addr == 0) {
229+
tu_edpt_stream_open(&p_vendor->rx.stream, desc_ep);
230+
TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_vendor->rx.stream) > 0, 0); // prepare for incoming data
231+
}
224232
}
225233
}
226234

src/common/tusb_types.h

+6
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,12 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_subtype(void const* desc) {
586586
return ((uint8_t const*) desc)[DESC_OFFSET_SUBTYPE];
587587
}
588588

589+
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_is_valid(void const* desc, uint8_t const* desc_end) {
590+
const uint8_t* desc8 = (uint8_t const*) desc;
591+
return (desc8 < desc_end) && (tu_desc_next(desc) <= desc_end);
592+
}
593+
594+
589595
// find descriptor that match byte1 (type)
590596
uint8_t const * tu_desc_find(uint8_t const* desc, uint8_t const* end, uint8_t byte1);
591597

0 commit comments

Comments
 (0)