Implement a secure ICS protocol targeting LoRa Node151 microcontroller for controlling irrigation.
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

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