Implement a secure ICS protocol targeting LoRa Node151 microcontroller for controlling irrigation.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

854 lines
18 KiB

  1. /**
  2. ******************************************************************************
  3. * @file usbd_req.c
  4. * @author MCD Application Team
  5. * @brief This file provides the standard USB requests following chapter 9.
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
  10. * All rights reserved.</center></h2>
  11. *
  12. * This software component is licensed by ST under Ultimate Liberty license
  13. * SLA0044, the "License"; You may not use this file except in compliance with
  14. * the License. You may obtain a copy of the License at:
  15. * http://www.st.com/SLA0044
  16. *
  17. ******************************************************************************
  18. */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "usbd_ctlreq.h"
  21. #include "usbd_ioreq.h"
  22. /** @addtogroup STM32_USBD_STATE_DEVICE_LIBRARY
  23. * @{
  24. */
  25. /** @defgroup USBD_REQ
  26. * @brief USB standard requests module
  27. * @{
  28. */
  29. /** @defgroup USBD_REQ_Private_TypesDefinitions
  30. * @{
  31. */
  32. /**
  33. * @}
  34. */
  35. /** @defgroup USBD_REQ_Private_Defines
  36. * @{
  37. */
  38. /**
  39. * @}
  40. */
  41. /** @defgroup USBD_REQ_Private_Macros
  42. * @{
  43. */
  44. /**
  45. * @}
  46. */
  47. /** @defgroup USBD_REQ_Private_Variables
  48. * @{
  49. */
  50. /**
  51. * @}
  52. */
  53. /** @defgroup USBD_REQ_Private_FunctionPrototypes
  54. * @{
  55. */
  56. #if 0
  57. static
  58. #endif
  59. void USBD_GetDescriptor(USBD_HandleTypeDef *pdev ,
  60. USBD_SetupReqTypedef *req);
  61. static void USBD_SetAddress(USBD_HandleTypeDef *pdev ,
  62. USBD_SetupReqTypedef *req);
  63. static void USBD_SetConfig(USBD_HandleTypeDef *pdev ,
  64. USBD_SetupReqTypedef *req);
  65. static void USBD_GetConfig(USBD_HandleTypeDef *pdev ,
  66. USBD_SetupReqTypedef *req);
  67. static void USBD_GetStatus(USBD_HandleTypeDef *pdev ,
  68. USBD_SetupReqTypedef *req);
  69. static void USBD_SetFeature(USBD_HandleTypeDef *pdev ,
  70. USBD_SetupReqTypedef *req);
  71. static void USBD_ClrFeature(USBD_HandleTypeDef *pdev ,
  72. USBD_SetupReqTypedef *req);
  73. static uint8_t USBD_GetLen(uint8_t *buf);
  74. /**
  75. * @}
  76. */
  77. /** @defgroup USBD_REQ_Private_Functions
  78. * @{
  79. */
  80. /**
  81. * @brief USBD_StdDevReq
  82. * Handle standard usb device requests
  83. * @param pdev: device instance
  84. * @param req: usb request
  85. * @retval status
  86. */
  87. USBD_StatusTypeDef USBD_StdDevReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req)
  88. {
  89. USBD_StatusTypeDef ret = USBD_OK;
  90. switch (req->bmRequest & USB_REQ_TYPE_MASK)
  91. {
  92. case USB_REQ_TYPE_CLASS:
  93. case USB_REQ_TYPE_VENDOR:
  94. pdev->pClass->Setup(pdev, req);
  95. break;
  96. case USB_REQ_TYPE_STANDARD:
  97. switch (req->bRequest)
  98. {
  99. case USB_REQ_GET_DESCRIPTOR:
  100. USBD_GetDescriptor (pdev, req);
  101. break;
  102. case USB_REQ_SET_ADDRESS:
  103. USBD_SetAddress (pdev, req);
  104. break;
  105. case USB_REQ_SET_CONFIGURATION:
  106. USBD_SetConfig (pdev, req);
  107. break;
  108. case USB_REQ_GET_CONFIGURATION:
  109. USBD_GetConfig (pdev, req);
  110. break;
  111. case USB_REQ_GET_STATUS:
  112. USBD_GetStatus (pdev, req);
  113. break;
  114. case USB_REQ_SET_FEATURE:
  115. USBD_SetFeature (pdev, req);
  116. break;
  117. case USB_REQ_CLEAR_FEATURE:
  118. USBD_ClrFeature (pdev, req);
  119. break;
  120. default:
  121. USBD_CtlError(pdev, req);
  122. break;
  123. }
  124. break;
  125. default:
  126. USBD_CtlError(pdev, req);
  127. break;
  128. }
  129. return ret;
  130. }
  131. /**
  132. * @brief USBD_StdItfReq
  133. * Handle standard usb interface requests
  134. * @param pdev: device instance
  135. * @param req: usb request
  136. * @retval status
  137. */
  138. USBD_StatusTypeDef USBD_StdItfReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req)
  139. {
  140. USBD_StatusTypeDef ret = USBD_OK;
  141. switch (req->bmRequest & USB_REQ_TYPE_MASK)
  142. {
  143. case USB_REQ_TYPE_CLASS:
  144. case USB_REQ_TYPE_VENDOR:
  145. case USB_REQ_TYPE_STANDARD:
  146. switch (pdev->dev_state)
  147. {
  148. case USBD_STATE_DEFAULT:
  149. case USBD_STATE_ADDRESSED:
  150. case USBD_STATE_CONFIGURED:
  151. if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES)
  152. {
  153. ret = (USBD_StatusTypeDef)pdev->pClass->Setup (pdev, req);
  154. if ((req->wLength == 0U) && (ret == USBD_OK))
  155. {
  156. USBD_CtlSendStatus(pdev);
  157. }
  158. }
  159. else
  160. {
  161. USBD_CtlError(pdev, req);
  162. }
  163. break;
  164. default:
  165. USBD_CtlError(pdev, req);
  166. break;
  167. }
  168. break;
  169. default:
  170. USBD_CtlError(pdev, req);
  171. break;
  172. }
  173. return USBD_OK;
  174. }
  175. /**
  176. * @brief USBD_StdEPReq
  177. * Handle standard usb endpoint requests
  178. * @param pdev: device instance
  179. * @param req: usb request
  180. * @retval status
  181. */
  182. USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req)
  183. {
  184. uint8_t ep_addr;
  185. USBD_StatusTypeDef ret = USBD_OK;
  186. USBD_EndpointTypeDef *pep;
  187. ep_addr = LOBYTE(req->wIndex);
  188. switch (req->bmRequest & USB_REQ_TYPE_MASK)
  189. {
  190. case USB_REQ_TYPE_CLASS:
  191. case USB_REQ_TYPE_VENDOR:
  192. pdev->pClass->Setup (pdev, req);
  193. break;
  194. case USB_REQ_TYPE_STANDARD:
  195. /* Check if it is a class request */
  196. if ((req->bmRequest & 0x60U) == 0x20U)
  197. {
  198. ret = (USBD_StatusTypeDef)pdev->pClass->Setup (pdev, req);
  199. return ret;
  200. }
  201. switch (req->bRequest)
  202. {
  203. case USB_REQ_SET_FEATURE :
  204. switch (pdev->dev_state)
  205. {
  206. case USBD_STATE_ADDRESSED:
  207. if ((ep_addr != 0x00U) && (ep_addr != 0x80U))
  208. {
  209. USBD_LL_StallEP(pdev, ep_addr);
  210. USBD_LL_StallEP(pdev, 0x80U);
  211. }
  212. else
  213. {
  214. USBD_CtlError(pdev, req);
  215. }
  216. break;
  217. case USBD_STATE_CONFIGURED:
  218. if (req->wValue == USB_FEATURE_EP_HALT)
  219. {
  220. if ((ep_addr != 0x00U) && (ep_addr != 0x80U) && (req->wLength == 0x00U))
  221. {
  222. USBD_LL_StallEP(pdev, ep_addr);
  223. }
  224. }
  225. USBD_CtlSendStatus(pdev);
  226. break;
  227. default:
  228. USBD_CtlError(pdev, req);
  229. break;
  230. }
  231. break;
  232. case USB_REQ_CLEAR_FEATURE :
  233. switch (pdev->dev_state)
  234. {
  235. case USBD_STATE_ADDRESSED:
  236. if ((ep_addr != 0x00U) && (ep_addr != 0x80U))
  237. {
  238. USBD_LL_StallEP(pdev, ep_addr);
  239. USBD_LL_StallEP(pdev, 0x80U);
  240. }
  241. else
  242. {
  243. USBD_CtlError(pdev, req);
  244. }
  245. break;
  246. case USBD_STATE_CONFIGURED:
  247. if (req->wValue == USB_FEATURE_EP_HALT)
  248. {
  249. if ((ep_addr & 0x7FU) != 0x00U)
  250. {
  251. USBD_LL_ClearStallEP(pdev, ep_addr);
  252. }
  253. USBD_CtlSendStatus(pdev);
  254. }
  255. break;
  256. default:
  257. USBD_CtlError(pdev, req);
  258. break;
  259. }
  260. break;
  261. case USB_REQ_GET_STATUS:
  262. switch (pdev->dev_state)
  263. {
  264. case USBD_STATE_ADDRESSED:
  265. if ((ep_addr != 0x00U) && (ep_addr != 0x80U))
  266. {
  267. USBD_CtlError(pdev, req);
  268. break;
  269. }
  270. pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU]:\
  271. &pdev->ep_out[ep_addr & 0x7FU];
  272. pep->status = 0x0000U;
  273. USBD_CtlSendData (pdev, (uint8_t *)(void *)&pep->status, 2U);
  274. break;
  275. case USBD_STATE_CONFIGURED:
  276. if((ep_addr & 0x80U) == 0x80U)
  277. {
  278. if (pdev->ep_in[ep_addr & 0xFU].is_used == 0U)
  279. {
  280. USBD_CtlError(pdev, req);
  281. break;
  282. }
  283. }
  284. else
  285. {
  286. if (pdev->ep_out[ep_addr & 0xFU].is_used == 0U)
  287. {
  288. USBD_CtlError(pdev, req);
  289. break;
  290. }
  291. }
  292. pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU]:\
  293. &pdev->ep_out[ep_addr & 0x7FU];
  294. if ((ep_addr == 0x00U) || (ep_addr == 0x80U))
  295. {
  296. pep->status = 0x0000U;
  297. }
  298. else if(USBD_LL_IsStallEP(pdev, ep_addr))
  299. {
  300. pep->status = 0x0001U;
  301. }
  302. else
  303. {
  304. pep->status = 0x0000U;
  305. }
  306. USBD_CtlSendData (pdev, (uint8_t *)(void *)&pep->status, 2U);
  307. break;
  308. default:
  309. USBD_CtlError(pdev, req);
  310. break;
  311. }
  312. break;
  313. default:
  314. USBD_CtlError(pdev, req);
  315. break;
  316. }
  317. break;
  318. default:
  319. USBD_CtlError(pdev, req);
  320. break;
  321. }
  322. return ret;
  323. }
  324. #if 0
  325. /**
  326. * @brief USBD_GetDescriptor
  327. * Handle Get Descriptor requests
  328. * @param pdev: device instance
  329. * @param req: usb request
  330. * @retval status
  331. */
  332. static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev ,
  333. USBD_SetupReqTypedef *req)
  334. {
  335. uint16_t len;
  336. uint8_t *pbuf;
  337. switch (req->wValue >> 8)
  338. {
  339. #if (USBD_LPM_ENABLED == 1U)
  340. case USB_DESC_TYPE_BOS:
  341. pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len);
  342. break;
  343. #endif
  344. case USB_DESC_TYPE_DEVICE:
  345. pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len);
  346. break;
  347. case USB_DESC_TYPE_CONFIGURATION:
  348. if(pdev->dev_speed == USBD_SPEED_HIGH )
  349. {
  350. pbuf = (uint8_t *)pdev->pClass->GetHSConfigDescriptor(&len);
  351. pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
  352. }
  353. else
  354. {
  355. pbuf = (uint8_t *)pdev->pClass->GetFSConfigDescriptor(&len);
  356. pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
  357. }
  358. break;
  359. case USB_DESC_TYPE_STRING:
  360. switch ((uint8_t)(req->wValue))
  361. {
  362. case USBD_IDX_LANGID_STR:
  363. pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len);
  364. break;
  365. case USBD_IDX_MFC_STR:
  366. pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len);
  367. break;
  368. case USBD_IDX_PRODUCT_STR:
  369. pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len);
  370. break;
  371. case USBD_IDX_SERIAL_STR:
  372. pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len);
  373. break;
  374. case USBD_IDX_CONFIG_STR:
  375. pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len);
  376. break;
  377. case USBD_IDX_INTERFACE_STR:
  378. pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len);
  379. break;
  380. default:
  381. #if (USBD_SUPPORT_USER_STRING == 1U)
  382. pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue) , &len);
  383. break;
  384. #else
  385. USBD_CtlError(pdev , req);
  386. return;
  387. #endif
  388. }
  389. break;
  390. case USB_DESC_TYPE_DEVICE_QUALIFIER:
  391. if(pdev->dev_speed == USBD_SPEED_HIGH)
  392. {
  393. pbuf = (uint8_t *)pdev->pClass->GetDeviceQualifierDescriptor(&len);
  394. break;
  395. }
  396. else
  397. {
  398. USBD_CtlError(pdev , req);
  399. return;
  400. }
  401. case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
  402. if(pdev->dev_speed == USBD_SPEED_HIGH )
  403. {
  404. pbuf = (uint8_t *)pdev->pClass->GetOtherSpeedConfigDescriptor(&len);
  405. pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION;
  406. break;
  407. }
  408. else
  409. {
  410. USBD_CtlError(pdev , req);
  411. return;
  412. }
  413. default:
  414. USBD_CtlError(pdev , req);
  415. return;
  416. }
  417. if((len != 0U) && (req->wLength != 0U))
  418. {
  419. len = MIN(len, req->wLength);
  420. USBD_CtlSendData (pdev, pbuf, len);
  421. }
  422. if(req->wLength == 0U)
  423. {
  424. USBD_CtlSendStatus(pdev);
  425. }
  426. }
  427. #endif
  428. /**
  429. * @brief USBD_SetAddress
  430. * Set device address
  431. * @param pdev: device instance
  432. * @param req: usb request
  433. * @retval status
  434. */
  435. static void USBD_SetAddress(USBD_HandleTypeDef *pdev ,
  436. USBD_SetupReqTypedef *req)
  437. {
  438. uint8_t dev_addr;
  439. if ((req->wIndex == 0U) && (req->wLength == 0U) && (req->wValue < 128U))
  440. {
  441. dev_addr = (uint8_t)(req->wValue) & 0x7FU;
  442. if (pdev->dev_state == USBD_STATE_CONFIGURED)
  443. {
  444. USBD_CtlError(pdev , req);
  445. }
  446. else
  447. {
  448. pdev->dev_address = dev_addr;
  449. USBD_LL_SetUSBAddress(pdev, dev_addr);
  450. USBD_CtlSendStatus(pdev);
  451. if (dev_addr != 0U)
  452. {
  453. pdev->dev_state = USBD_STATE_ADDRESSED;
  454. }
  455. else
  456. {
  457. pdev->dev_state = USBD_STATE_DEFAULT;
  458. }
  459. }
  460. }
  461. else
  462. {
  463. USBD_CtlError(pdev, req);
  464. }
  465. }
  466. /**
  467. * @brief USBD_SetConfig
  468. * Handle Set device configuration request
  469. * @param pdev: device instance
  470. * @param req: usb request
  471. * @retval status
  472. */
  473. static void USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
  474. {
  475. static uint8_t cfgidx;
  476. cfgidx = (uint8_t)(req->wValue);
  477. if (cfgidx > USBD_MAX_NUM_CONFIGURATION)
  478. {
  479. USBD_CtlError(pdev, req);
  480. }
  481. else
  482. {
  483. switch (pdev->dev_state)
  484. {
  485. case USBD_STATE_ADDRESSED:
  486. if (cfgidx)
  487. {
  488. pdev->dev_config = cfgidx;
  489. pdev->dev_state = USBD_STATE_CONFIGURED;
  490. if(USBD_SetClassConfig(pdev, cfgidx) == USBD_FAIL)
  491. {
  492. USBD_CtlError(pdev, req);
  493. return;
  494. }
  495. USBD_CtlSendStatus(pdev);
  496. }
  497. else
  498. {
  499. USBD_CtlSendStatus(pdev);
  500. }
  501. break;
  502. case USBD_STATE_CONFIGURED:
  503. if (cfgidx == 0U)
  504. {
  505. pdev->dev_state = USBD_STATE_ADDRESSED;
  506. pdev->dev_config = cfgidx;
  507. USBD_ClrClassConfig(pdev, cfgidx);
  508. USBD_CtlSendStatus(pdev);
  509. }
  510. else if (cfgidx != pdev->dev_config)
  511. {
  512. /* Clear old configuration */
  513. USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config);
  514. /* set new configuration */
  515. pdev->dev_config = cfgidx;
  516. if(USBD_SetClassConfig(pdev, cfgidx) == USBD_FAIL)
  517. {
  518. USBD_CtlError(pdev, req);
  519. return;
  520. }
  521. USBD_CtlSendStatus(pdev);
  522. }
  523. else
  524. {
  525. USBD_CtlSendStatus(pdev);
  526. }
  527. break;
  528. default:
  529. USBD_CtlError(pdev, req);
  530. USBD_ClrClassConfig(pdev, cfgidx);
  531. break;
  532. }
  533. }
  534. }
  535. /**
  536. * @brief USBD_GetConfig
  537. * Handle Get device configuration request
  538. * @param pdev: device instance
  539. * @param req: usb request
  540. * @retval status
  541. */
  542. static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
  543. {
  544. if (req->wLength != 1U)
  545. {
  546. USBD_CtlError(pdev , req);
  547. }
  548. else
  549. {
  550. switch (pdev->dev_state)
  551. {
  552. case USBD_STATE_DEFAULT:
  553. case USBD_STATE_ADDRESSED:
  554. pdev->dev_default_config = 0U;
  555. USBD_CtlSendData (pdev, (uint8_t *)(void *)&pdev->dev_default_config, 1U);
  556. break;
  557. case USBD_STATE_CONFIGURED:
  558. USBD_CtlSendData (pdev, (uint8_t *)(void *)&pdev->dev_config, 1U);
  559. break;
  560. default:
  561. USBD_CtlError(pdev , req);
  562. break;
  563. }
  564. }
  565. }
  566. /**
  567. * @brief USBD_GetStatus
  568. * Handle Get Status request
  569. * @param pdev: device instance
  570. * @param req: usb request
  571. * @retval status
  572. */
  573. static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
  574. {
  575. switch (pdev->dev_state)
  576. {
  577. case USBD_STATE_DEFAULT:
  578. case USBD_STATE_ADDRESSED:
  579. case USBD_STATE_CONFIGURED:
  580. if(req->wLength != 0x2U)
  581. {
  582. USBD_CtlError(pdev, req);
  583. break;
  584. }
  585. #if ( USBD_SELF_POWERED == 1U)
  586. pdev->dev_config_status = USB_CONFIG_SELF_POWERED;
  587. #else
  588. pdev->dev_config_status = 0U;
  589. #endif
  590. if (pdev->dev_remote_wakeup)
  591. {
  592. pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP;
  593. }
  594. USBD_CtlSendData (pdev, (uint8_t *)(void *)&pdev->dev_config_status, 2U);
  595. break;
  596. default :
  597. USBD_CtlError(pdev , req);
  598. break;
  599. }
  600. }
  601. /**
  602. * @brief USBD_SetFeature
  603. * Handle Set device feature request
  604. * @param pdev: device instance
  605. * @param req: usb request
  606. * @retval status
  607. */
  608. static void USBD_SetFeature(USBD_HandleTypeDef *pdev ,
  609. USBD_SetupReqTypedef *req)
  610. {
  611. if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
  612. {
  613. pdev->dev_remote_wakeup = 1U;
  614. USBD_CtlSendStatus(pdev);
  615. }
  616. }
  617. /**
  618. * @brief USBD_ClrFeature
  619. * Handle clear device feature request
  620. * @param pdev: device instance
  621. * @param req: usb request
  622. * @retval status
  623. */
  624. static void USBD_ClrFeature(USBD_HandleTypeDef *pdev ,
  625. USBD_SetupReqTypedef *req)
  626. {
  627. switch (pdev->dev_state)
  628. {
  629. case USBD_STATE_DEFAULT:
  630. case USBD_STATE_ADDRESSED:
  631. case USBD_STATE_CONFIGURED:
  632. if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
  633. {
  634. pdev->dev_remote_wakeup = 0U;
  635. USBD_CtlSendStatus(pdev);
  636. }
  637. break;
  638. default :
  639. USBD_CtlError(pdev , req);
  640. break;
  641. }
  642. }
  643. /**
  644. * @brief USBD_ParseSetupRequest
  645. * Copy buffer into setup structure
  646. * @param pdev: device instance
  647. * @param req: usb request
  648. * @retval None
  649. */
  650. void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata)
  651. {
  652. req->bmRequest = *(uint8_t *) (pdata);
  653. req->bRequest = *(uint8_t *) (pdata + 1);
  654. req->wValue = SWAPBYTE (pdata + 2);
  655. req->wIndex = SWAPBYTE (pdata + 4);
  656. req->wLength = SWAPBYTE (pdata + 6);
  657. }
  658. /**
  659. * @brief USBD_CtlError
  660. * Handle USB low level Error
  661. * @param pdev: device instance
  662. * @param req: usb request
  663. * @retval None
  664. */
  665. void USBD_CtlError( USBD_HandleTypeDef *pdev ,
  666. USBD_SetupReqTypedef *req)
  667. {
  668. USBD_LL_StallEP(pdev , 0x80U);
  669. USBD_LL_StallEP(pdev , 0U);
  670. }
  671. /**
  672. * @brief USBD_GetString
  673. * Convert Ascii string into unicode one
  674. * @param desc : descriptor buffer
  675. * @param unicode : Formatted string buffer (unicode)
  676. * @param len : descriptor length
  677. * @retval None
  678. */
  679. void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
  680. {
  681. uint8_t idx = 0U;
  682. if (desc != NULL)
  683. {
  684. *len = (uint16_t)USBD_GetLen(desc) * 2U + 2U;
  685. unicode[idx++] = *(uint8_t *)(void *)len;
  686. unicode[idx++] = USB_DESC_TYPE_STRING;
  687. while (*desc != '\0')
  688. {
  689. unicode[idx++] = *desc++;
  690. unicode[idx++] = 0U;
  691. }
  692. }
  693. }
  694. /**
  695. * @brief USBD_GetLen
  696. * return the string length
  697. * @param buf : pointer to the ascii string buffer
  698. * @retval string length
  699. */
  700. static uint8_t USBD_GetLen(uint8_t *buf)
  701. {
  702. uint8_t len = 0U;
  703. while (*buf != '\0')
  704. {
  705. len++;
  706. buf++;
  707. }
  708. return len;
  709. }
  710. /**
  711. * @}
  712. */
  713. /**
  714. * @}
  715. */
  716. /**
  717. * @}
  718. */
  719. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/