@@ -1372,9 +1372,13 @@ enum {
1372
1372
ENUM_HUB_CLEAR_RESET_2 ,
1373
1373
ENUM_SET_ADDR ,
1374
1374
ENUM_GET_DEVICE_DESC ,
1375
+ ENUM_GET_STRING_LANGUAGE_ID_LEN ,
1375
1376
ENUM_GET_STRING_LANGUAGE_ID ,
1377
+ ENUM_GET_STRING_MANUFACTURER_LEN ,
1376
1378
ENUM_GET_STRING_MANUFACTURER ,
1379
+ ENUM_GET_STRING_PRODUCT_LEN ,
1377
1380
ENUM_GET_STRING_PRODUCT ,
1381
+ ENUM_GET_STRING_SERIAL_LEN ,
1378
1382
ENUM_GET_STRING_SERIAL ,
1379
1383
ENUM_GET_9BYTE_CONFIG_DESC ,
1380
1384
ENUM_GET_FULL_CONFIG_DESC ,
@@ -1416,6 +1420,9 @@ static void process_enumeration(tuh_xfer_t* xfer) {
1416
1420
uint8_t const daddr = xfer -> daddr ;
1417
1421
uintptr_t const state = xfer -> user_data ;
1418
1422
usbh_device_t * dev = get_device (daddr );
1423
+ if (daddr > 0 ) {
1424
+ TU_ASSERT (dev ,);
1425
+ }
1419
1426
uint16_t langid = 0x0409 ; // default is English
1420
1427
1421
1428
switch (state ) {
@@ -1474,30 +1481,6 @@ static void process_enumeration(tuh_xfer_t* xfer) {
1474
1481
break ;
1475
1482
}
1476
1483
1477
- #if 0
1478
- case ENUM_RESET_2 :
1479
- // TODO not used by now, but may be needed for some devices !?
1480
- // Reset device again before Set Address
1481
- TU_LOG_USBH ("Port reset2 \r\n" );
1482
- if (_dev0 .hub_addr == 0 ) {
1483
- // connected directly to roothub
1484
- hcd_port_reset ( _dev0 .rhport );
1485
- tusb_time_delay_ms_api (RESET_DELAY ); // TODO may not work for no-OS on MCU that require reset_end() since
1486
- // sof of controller may not running while resetting
1487
- hcd_port_reset_end (_dev0 .rhport );
1488
- // TODO: fall through to SET ADDRESS, refactor later
1489
- }
1490
- #if CFG_TUH_HUB
1491
- else {
1492
- // after RESET_DELAY the hub_port_reset() already complete
1493
- TU_ASSERT ( hub_port_reset (_dev0 .hub_addr , _dev0 .hub_port ,
1494
- process_enumeration , ENUM_HUB_GET_STATUS_2 ), );
1495
- break ;
1496
- }
1497
- #endif
1498
- TU_ATTR_FALLTHROUGH ;
1499
- #endif
1500
-
1501
1484
case ENUM_SET_ADDR :
1502
1485
enum_request_set_addr ((tusb_desc_device_t * ) _usbh_epbuf .ctrl );
1503
1486
break ;
@@ -1520,65 +1503,104 @@ static void process_enumeration(tuh_xfer_t* xfer) {
1520
1503
// Get full device descriptor
1521
1504
TU_LOG_USBH ("Get Device Descriptor\r\n" );
1522
1505
TU_ASSERT (tuh_descriptor_get_device (new_addr , _usbh_epbuf .ctrl , sizeof (tusb_desc_device_t ),
1523
- process_enumeration , ENUM_GET_STRING_LANGUAGE_ID ),);
1506
+ process_enumeration , ENUM_GET_STRING_LANGUAGE_ID_LEN ),);
1524
1507
break ;
1525
1508
}
1526
1509
1527
- case ENUM_GET_STRING_LANGUAGE_ID : {
1510
+ // For string descriptor (langid, manufacturer, product, serila): always get the first 2 bytes
1511
+ // to determine the length first. otherwise, some device may have buffer overflow.
1512
+ case ENUM_GET_STRING_LANGUAGE_ID_LEN : {
1528
1513
// save the received device descriptor
1529
- TU_ASSERT (dev ,);
1530
- tusb_desc_device_t const * desc_device = (tusb_desc_device_t const * ) _usbh_epbuf .ctrl ;
1514
+ tusb_desc_device_t const * desc_device = (tusb_desc_device_t const * ) _usbh_epbuf .ctrl ;
1531
1515
dev -> vid = desc_device -> idVendor ;
1532
1516
dev -> pid = desc_device -> idProduct ;
1533
1517
dev -> i_manufacturer = desc_device -> iManufacturer ;
1534
1518
dev -> i_product = desc_device -> iProduct ;
1535
1519
dev -> i_serial = desc_device -> iSerialNumber ;
1536
1520
dev -> bNumConfigurations = desc_device -> bNumConfigurations ;
1537
1521
1538
- tuh_enum_descriptor_device_cb (daddr , desc_device ); // callback
1522
+ tuh_enum_descriptor_device_cb (daddr , desc_device );// callback
1539
1523
1540
- tuh_descriptor_get_string_langid (daddr , _usbh_epbuf .ctrl , CFG_TUH_ENUMERATION_BUFSIZE ,
1541
- process_enumeration , ENUM_GET_STRING_MANUFACTURER );
1524
+ tuh_descriptor_get_string_langid (daddr , _usbh_epbuf .ctrl , 2 ,
1525
+ process_enumeration , ENUM_GET_STRING_LANGUAGE_ID );
1542
1526
break ;
1543
1527
}
1544
1528
1545
- case ENUM_GET_STRING_MANUFACTURER : {
1546
- TU_ASSERT (dev ,);
1547
- const tusb_desc_string_t * desc_langid = (tusb_desc_string_t const * ) _usbh_epbuf .ctrl ;
1529
+ case ENUM_GET_STRING_LANGUAGE_ID : {
1530
+ const uint8_t str_len = xfer -> buffer [0 ];
1531
+ tuh_descriptor_get_string_langid (daddr , _usbh_epbuf .ctrl , str_len ,
1532
+ process_enumeration , ENUM_GET_STRING_MANUFACTURER_LEN );
1533
+ break ;
1534
+ }
1535
+
1536
+ case ENUM_GET_STRING_MANUFACTURER_LEN : {
1537
+ const tusb_desc_string_t * desc_langid = (const tusb_desc_string_t * ) _usbh_epbuf .ctrl ;
1548
1538
if (desc_langid -> bLength >= 4 ) {
1549
- langid = tu_le16toh (desc_langid -> utf16le [0 ]);
1539
+ langid = tu_le16toh (desc_langid -> utf16le [0 ]); // previous request is langid
1550
1540
}
1551
1541
if (dev -> i_manufacturer != 0 ) {
1552
- tuh_descriptor_get_string (daddr , dev -> i_manufacturer , langid , _usbh_epbuf .ctrl , CFG_TUH_ENUMERATION_BUFSIZE ,
1553
- process_enumeration , ENUM_GET_STRING_PRODUCT );
1542
+ tuh_descriptor_get_string (daddr , dev -> i_manufacturer , langid , _usbh_epbuf .ctrl , 2 ,
1543
+ process_enumeration , ENUM_GET_STRING_MANUFACTURER );
1544
+ break ;
1545
+ }else {
1546
+ TU_ATTR_FALLTHROUGH ;
1547
+ }
1548
+ }
1549
+
1550
+ case ENUM_GET_STRING_MANUFACTURER : {
1551
+ if (dev -> i_manufacturer != 0 ) {
1552
+ langid = tu_le16toh (xfer -> setup -> wIndex ); // langid from length's request
1553
+ const uint8_t str_len = xfer -> buffer [0 ];
1554
+ tuh_descriptor_get_string (daddr , dev -> i_manufacturer , langid , _usbh_epbuf .ctrl , str_len ,
1555
+ process_enumeration , ENUM_GET_STRING_PRODUCT_LEN );
1554
1556
break ;
1555
1557
} else {
1556
1558
TU_ATTR_FALLTHROUGH ;
1557
1559
}
1558
1560
}
1559
1561
1560
- case ENUM_GET_STRING_PRODUCT : {
1561
- TU_ASSERT (dev ,);
1562
- if (state == ENUM_GET_STRING_PRODUCT ) {
1563
- langid = tu_le16toh (xfer -> setup -> wIndex ); // if not fall through, get langid from previous setup packet
1562
+ case ENUM_GET_STRING_PRODUCT_LEN :
1563
+ if (dev -> i_product != 0 ) {
1564
+ if (state == ENUM_GET_STRING_PRODUCT_LEN ) {
1565
+ langid = tu_le16toh (xfer -> setup -> wIndex ); // get langid from previous setup packet if not fall through
1566
+ }
1567
+ tuh_descriptor_get_string (daddr , dev -> i_product , langid , _usbh_epbuf .ctrl , 2 ,
1568
+ process_enumeration , ENUM_GET_STRING_PRODUCT );
1569
+ break ;
1570
+ } else {
1571
+ TU_ATTR_FALLTHROUGH ;
1564
1572
}
1573
+
1574
+ case ENUM_GET_STRING_PRODUCT : {
1565
1575
if (dev -> i_product != 0 ) {
1566
- tuh_descriptor_get_string (daddr , dev -> i_product , 0x0409 , _usbh_epbuf .ctrl , CFG_TUH_ENUMERATION_BUFSIZE ,
1567
- process_enumeration , ENUM_GET_STRING_SERIAL );
1576
+ langid = tu_le16toh (xfer -> setup -> wIndex ); // langid from length's request
1577
+ const uint8_t str_len = xfer -> buffer [0 ];
1578
+ tuh_descriptor_get_string (daddr , dev -> i_product , langid , _usbh_epbuf .ctrl , str_len ,
1579
+ process_enumeration , ENUM_GET_STRING_SERIAL_LEN );
1568
1580
break ;
1569
1581
} else {
1570
1582
TU_ATTR_FALLTHROUGH ;
1571
1583
}
1572
1584
}
1573
1585
1574
- case ENUM_GET_STRING_SERIAL : {
1575
- TU_ASSERT (dev ,);
1576
- if (state == ENUM_GET_STRING_SERIAL ) {
1577
- langid = tu_le16toh (xfer -> setup -> wIndex ); // if not fall through, get langid from previous setup packet
1586
+ case ENUM_GET_STRING_SERIAL_LEN :
1587
+ if (dev -> i_serial != 0 ) {
1588
+ if (state == ENUM_GET_STRING_SERIAL_LEN ) {
1589
+ langid = tu_le16toh (xfer -> setup -> wIndex ); // get langid from previous setup packet if not fall through
1590
+ }
1591
+ tuh_descriptor_get_string (daddr , dev -> i_serial , langid , _usbh_epbuf .ctrl , 2 ,
1592
+ process_enumeration , ENUM_GET_STRING_SERIAL );
1593
+ break ;
1594
+ } else {
1595
+ TU_ATTR_FALLTHROUGH ;
1578
1596
}
1597
+
1598
+ case ENUM_GET_STRING_SERIAL : {
1579
1599
if (dev -> i_serial != 0 ) {
1580
- tuh_descriptor_get_string (daddr , dev -> i_serial , langid , _usbh_epbuf .ctrl , CFG_TUH_ENUMERATION_BUFSIZE ,
1581
- process_enumeration , ENUM_GET_9BYTE_CONFIG_DESC );
1600
+ langid = tu_le16toh (xfer -> setup -> wIndex ); // langid from length's request
1601
+ const uint8_t str_len = xfer -> buffer [0 ];
1602
+ tuh_descriptor_get_string (daddr , dev -> i_serial , langid , _usbh_epbuf .ctrl , str_len ,
1603
+ process_enumeration , ENUM_GET_9BYTE_CONFIG_DESC );
1582
1604
break ;
1583
1605
} else {
1584
1606
TU_ATTR_FALLTHROUGH ;
@@ -1627,8 +1649,6 @@ static void process_enumeration(tuh_xfer_t* xfer) {
1627
1649
1628
1650
case ENUM_CONFIG_DRIVER : {
1629
1651
TU_LOG_USBH ("Device configured\r\n" );
1630
- TU_ASSERT (dev ,);
1631
-
1632
1652
dev -> configured = 1 ;
1633
1653
1634
1654
// Parse configuration & set up drivers
0 commit comments