• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------------
2  * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved.
3  * Description: LiteOS USB Driver DFU Protocol
4  * Author: huangjieliang
5  * Create: 2017-12-25
6  * Redistribution and use in source and binary forms, with or without modification,
7  * are permitted provided that the following conditions are met:
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  * conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  * of conditions and the following disclaimer in the documentation and/or other materials
12  * provided with the distribution.
13  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
14  * to endorse or promote products derived from this software without specific prior written
15  * permission.
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  * --------------------------------------------------------------------------- */
28 /* ----------------------------------------------------------------------------
29  * Notice of Export Control Law
30  * ===============================================
31  * Huawei LiteOS may be subject to applicable export control laws and regulations, which might
32  * include those applicable to Huawei LiteOS of U.S. and the country in which you are located.
33  * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such
34  * applicable export control laws and regulations.
35  * --------------------------------------------------------------------------- */
36 
37 #include <hisoc/uart.h>
38 #include "gadget/f_dfu.h"
39 #include "gadget/composite.h"
40 
41 #ifdef __cplusplus
42 #if __cplusplus
43 extern "C" {
44 #endif /* __cplusplus */
45 #endif /* __cplusplus */
46 
47 int usbdev_dfu_initialize(struct module *mod, int n, void *arg);
48 
49 /* device driver structure definition */
50 
51 static const driver_t g_dfu_driver =
52 {
53   .name     = "fdfu",
54   .methods  = NULL,
55   .size     = 0
56 };
57 
58 /* private device class information */
59 
60 static devclass_t g_dfu_devclass;
61 DRIVER_MODULE(fdfu, simple, g_dfu_driver, g_dfu_devclass, usbdev_dfu_initialize, 0);
62 
63 static struct usb_dfu_dev *g_dfu_dev       = NULL;
64 static struct usb_dfu_entity *g_dfu_entity = NULL;
65 static struct pthread_mutex g_dfu_mtx      = PTHREAD_MUTEX_INITIALIZER;
66 
67 static struct string_des g_manufacturer_str;
68 static struct string_des g_serial_number_str;
69 static struct string_des g_product_str;
70 
71 volatile uint8_t g_flash_upgrade_state = DFU_FLASH_STATE_UPGRADING;
72 
73 /* define descriptor */
74 
75 #define DEVICE_VENDOR_ID        0x0955
76 #define DEVICE_PRODUCT_ID       0x701A
77 #define DEVICE_VERSION          0x0110
78 
79 #define DFU_STRING_LEN_BYTE     0
80 #define DFU_STRING_DATA_BYTE    2
81 #define DFU_STRING_HEAD_LEN     2
82 #define DFU_MANU_STRING_LEN     28
83 #define DFU_PRODUCT_STRING_LEN  48
84 #define DFU_SERIAL_STRING_LEN   22
85 #define DFU_STRING_ID_LEN       4
86 
87 static const struct usb_device_descriptor g_dfu_device_desc =
88 {
89   .bLength            = sizeof(struct usb_device_descriptor),
90   .bDescriptorType    = UDESC_DEVICE,
91   HSETW(.bcdUSB, 0x0200),
92   .bDeviceClass       = 0x02,
93   .bDeviceSubClass    = 0x02, /* CDC-modem */
94   .bDeviceProtocol    = 0x01, /* Interface Association Descriptor */
95   .bMaxPacketSize     = 64,   /* Control Endpoint packet size */
96   HSETW(.idVendor, DEVICE_VENDOR_ID),
97   HSETW(.idProduct, DEVICE_PRODUCT_ID),
98   HSETW(.bcdDevice, DEVICE_VERSION),
99   .iManufacturer      = 1,    /* Manufacturer name, string index */
100   .iProduct           = 2,
101   .iSerialNumber      = 3,
102   .bNumConfigurations = 1,
103 };
104 
105 struct usb_config_descriptor g_dfu_config_desc =
106 {
107   .bLength             = USB_CONFIG_DESC_SIZE,
108   .bDescriptorType     = UDESC_CONFIG,
109 
110   /* HSETW(.wTotalLength, USB_CONFIG_DESC_SIZE + sizeof(usb_dfu_func) + sizeof(usb_dfu_intf_desc)), */
111 
112   HSETW(.wTotalLength, 0),  /* Modify according to the actual length */
113   .bNumInterface       = 1,
114   .bConfigurationValue = 1,
115   .iConfiguration      = 0,
116   .bmAttributes        = UC_SELF_POWERED | UC_BUS_POWERED,   /* 0xc0 */
117   .bMaxPower           = 1                                   /* max power */
118 };
119 
120 /* HUAWEI LiteOS */
121 
122 static char g_dfu_manufacturer[DFU_MANU_STRING_LEN] =
123 {
124   DFU_MANU_STRING_LEN,
125   UDESC_STRING,
126   'H', 0, 'U', 0, 'A', 0, 'W', 0, 'E', 0, 'I', 0, ' ', 0,
127   'L', 0, 'i', 0, 't', 0, 'e', 0, 'O', 0, 'S', 0
128 };
129 
130 /* USB download gadget */
131 
132 static char g_dfu_product[DFU_PRODUCT_STRING_LEN] =
133 {
134   DFU_PRODUCT_STRING_LEN,
135   UDESC_STRING,
136   'U', 0, 'S', 0, 'B', 0, ' ', 0, 'd', 0, 'o', 0, 'w', 0, 'n', 0, 'l', 0, 'o', 0,
137   'w', 0, 'n', 0, 'l', 0, 'o', 0, 'a', 0, 'd', 0, ' ', 0, 'g', 0, 'a', 0, 'd', 0,
138   'g', 0, 'e', 0, 't', 0
139 };
140 
141 static char g_dfu_serial[DFU_SERIAL_STRING_LEN] =
142 {
143   DFU_SERIAL_STRING_LEN,
144   UDESC_STRING,
145   '1', 0, '2', 0, '3', 0, '4', 0, '5', 0,
146   '6', 0, '7', 0, '8', 0, '9', 0, '0', 0
147 };
148 
149 static const char g_dfu_string_id[DFU_STRING_ID_LEN] =
150 {
151   DFU_STRING_ID_LEN,
152   UDESC_STRING,
153   0x09, 0x04
154 };
155 
156 static struct usbd_string g_dfu_string_defs[] =
157 {
158   { 0, g_dfu_string_id },
159   { 1, g_dfu_manufacturer },
160   { 2, g_dfu_product },
161   { 3, g_dfu_serial },
162   { 4, g_dfu_product },
163   USBD_DEVICE_STRINGS_END /* end of list */
164 };
165 
set_manufacturer_string(struct string_des * des)166 void set_manufacturer_string(struct string_des *des)
167 {
168   char *buf;
169   struct string_des *str_des;
170   int len;
171 
172   if (des == NULL)
173     {
174       usb_err("%s failed\n", __FUNCTION__);
175       return;
176     }
177 
178   if (des->str == NULL || des->len <= 0)
179     {
180       usb_err("%s failed, des->str is NULL or des->len is 0\n", __FUNCTION__);
181       return;
182     }
183 
184   str_des = des;
185   len     = str_des->len + DFU_STRING_HEAD_LEN;
186 
187   buf = (char *)malloc(len);
188   if (buf == NULL)
189     {
190       usb_err("%s malloc failed\n", __FUNCTION__);
191       return;
192     }
193 
194   g_manufacturer_str.str = buf;
195   g_manufacturer_str.len = len;
196 
197   *buf = len;
198   *(buf + 1) = UDESC_STRING;
199   (void)memcpy_s(buf + DFU_STRING_HEAD_LEN, (size_t)str_des->len, str_des->str, (size_t)str_des->len);
200 }
201 
set_serial_number_string(struct string_des * des)202 void set_serial_number_string(struct string_des *des)
203 {
204   char *buf;
205   struct string_des *str_des;
206   int len;
207 
208   if (des == NULL)
209     {
210       usb_err("%s failed\n", __FUNCTION__);
211       return;
212     }
213 
214   if (des->str == NULL || des->len <= 0)
215     {
216       usb_err("%s failed, des->str is NULL or des->len is 0\n", __FUNCTION__);
217       return;
218     }
219 
220   str_des = des;
221   len     = str_des->len + DFU_STRING_HEAD_LEN;
222 
223   buf = (char *)malloc(len);
224   if (buf == NULL)
225     {
226       usb_err("%s malloc failed\n", __FUNCTION__);
227       return;
228     }
229 
230   g_serial_number_str.str = buf;
231   g_serial_number_str.len = len;
232 
233   *buf = len;
234   *(buf + 1) = UDESC_STRING;
235   (void)memcpy_s(buf + DFU_STRING_HEAD_LEN, (size_t)str_des->len, str_des->str, (size_t)str_des->len);
236 }
237 
set_product_string(struct string_des * des)238 void set_product_string(struct string_des *des)
239 {
240   char *buf;
241   struct string_des *str_des;
242   int len;
243 
244   if (des == NULL)
245     {
246       usb_err("%s failed\n", __FUNCTION__);
247       return;
248     }
249 
250   if (des->str == NULL || des->len <= 0)
251     {
252       usb_err("%s failed, des->str is NULL or des->len is 0\n", __FUNCTION__);
253       return;
254     }
255 
256   str_des = des;
257   len     = str_des->len + DFU_STRING_HEAD_LEN;
258 
259   buf = (char *)malloc(len);
260   if (buf == NULL)
261     {
262       usb_err("%s malloc failed\n", __FUNCTION__);
263       return;
264     }
265 
266   g_product_str.str = buf;
267   g_product_str.len = len;
268 
269   *buf = len;
270   *(buf + 1) = UDESC_STRING;
271   (void)memcpy_s(buf + DFU_STRING_HEAD_LEN, (size_t)str_des->len, str_des->str, (size_t)str_des->len);
272 }
273 
set_flash_state(volatile uint8_t flash_state)274 void set_flash_state(volatile uint8_t flash_state)
275 {
276   if (flash_state != DFU_FLASH_STATE_UPGRADING &&
277       flash_state != DFU_FLASH_STATE_UPGRADED &&
278       flash_state != DFU_FLASH_STATE_ERROR)
279     {
280       PRINT_ERR("The state of flash upgrade is set failed!\n");
281       return;
282     }
283 
284   g_flash_upgrade_state = flash_state;
285 }
286 
get_flash_state(struct usbdev_req_s * req)287 void get_flash_state(struct usbdev_req_s *req)
288 {
289   uint8_t *buf = req->buf;
290 
291   buf[0] = g_flash_upgrade_state; /* The 0 bit is valid */
292 }
293 
usb_dfu_running(void)294 bool usb_dfu_running(void)
295 {
296   struct usb_dfu_entity *entity = usb_dfu_get_entity(0);
297 
298   if (entity == NULL)
299     {
300       return false;
301     }
302 
303   return (entity->trans_complete || entity->trans_size) ? true: false;
304 }
305 
usb_dfu_update_status(void)306 uint32_t usb_dfu_update_status(void)
307 {
308   struct usb_dfu_entity *entity = usb_dfu_get_entity(0);
309 
310   if (entity == NULL)
311     {
312       return 0;
313     }
314 
315   return entity->trans_complete;
316 }
317 
usb_dfu_update_size_get(void)318 uint64_t *usb_dfu_update_size_get(void)
319 {
320   struct usb_dfu_entity *entity = usb_dfu_get_entity(0);
321 
322   if (entity == NULL)
323     {
324       return NULL;
325     }
326 
327   return &entity->trans_size;
328 }
329 
dfu_ram_read(uint8_t * buf,uint32_t len)330 static int dfu_ram_read(uint8_t *buf, uint32_t len)
331 {
332   struct usb_dfu_entity *entity = usb_dfu_get_entity(0);
333   uint32_t offset;
334   errno_t ret;
335 
336   if (buf == NULL || entity == NULL)
337     {
338       return -1;
339     }
340 
341   offset = entity->offset;
342   if (offset > entity->ram_size)
343     {
344       return -1;
345     }
346 
347   len = min(len, (entity->ram_size - offset));
348 
349   ret = memcpy_s(buf, len, (const void *)((uint8_t *)entity->ram_addr + offset), len);
350   if (ret != EOK)
351     {
352       usb_err("memcpy failed!\n");
353       return -1;
354     }
355   entity->offset += len;
356 
357   (void)uart_putc('#');
358 
359   return (int)len;
360 }
361 
dfu_ram_write(const uint8_t * buf,uint32_t len)362 static int dfu_ram_write(const uint8_t *buf, uint32_t len)
363 {
364   struct usb_dfu_entity *entity = usb_dfu_get_entity(0);
365   uint32_t offset;
366   errno_t ret;
367 
368   if (buf == NULL || entity == NULL)
369     {
370       return -1;
371     }
372 
373   offset = entity->offset;
374   if (offset > entity->ram_size)
375     {
376       return -1;
377     }
378 
379   len = min(len, (entity->ram_size - offset));
380 
381   ret = memcpy_s((void *)((uint8_t *)entity->ram_addr + offset), entity->ram_size - offset, buf, len);
382   if (ret != EOK)
383     {
384       usb_err("memcpy failed!\n");
385       return -1;
386     }
387   entity->offset     += len;
388   entity->trans_size += len;
389 
390   (void)uart_putc('#');
391 
392   return 0;
393 }
394 
usbdev_dfu_dev_init(void)395 void usbdev_dfu_dev_init(void)
396 {
397   struct usb_dfu_dev *dev;
398   struct string_des str;
399 
400   dev = malloc(sizeof(struct usb_dfu_dev));
401   if (dev == NULL)
402     {
403       return;
404     }
405   (void)memset_s(dev, sizeof(struct usb_dfu_dev), 0, sizeof(struct usb_dfu_dev));
406 
407   g_dfu_dev = dev;
408 
409   str.str = &g_dfu_manufacturer[DFU_STRING_DATA_BYTE];
410   str.len = g_dfu_manufacturer[DFU_STRING_LEN_BYTE] - DFU_STRING_HEAD_LEN;
411   set_manufacturer_string(&str);
412   str.str = &g_dfu_serial[DFU_STRING_DATA_BYTE];
413   str.len = g_dfu_serial[DFU_STRING_LEN_BYTE] - DFU_STRING_HEAD_LEN;
414   set_serial_number_string(&str);
415   str.str = &g_dfu_product[DFU_STRING_DATA_BYTE];
416   str.len = g_dfu_product[DFU_STRING_LEN_BYTE] - DFU_STRING_HEAD_LEN;
417   set_product_string(&str);
418 }
419 
usbdev_dfu_dev_deinit(void)420 void usbdev_dfu_dev_deinit(void)
421 {
422   if (g_dfu_dev != NULL)
423     {
424       free(g_dfu_dev);
425       g_dfu_dev = NULL;
426     }
427 
428   if (g_manufacturer_str.str != NULL)
429     {
430       free((void *)g_manufacturer_str.str);
431       g_manufacturer_str.str = NULL;
432     }
433 
434   if (g_product_str.str != NULL)
435     {
436       free((void *)g_product_str.str);
437       g_product_str.str = NULL;
438     }
439 
440   if (g_serial_number_str.str != NULL)
441     {
442       free((void *)g_serial_number_str.str);
443       g_serial_number_str.str = NULL;
444     }
445 }
446 
usb_dfu_get_dev(void)447 static struct usb_dfu_dev *usb_dfu_get_dev(void)
448 {
449   return g_dfu_dev;
450 }
451 
dfu_set_state(int new_state)452 static inline void dfu_set_state(int new_state)
453 {
454   struct usb_dfu_dev *dev = usb_dfu_get_dev();
455   dev->dfu_state = new_state;
456 }
457 
dfu_get_state(void)458 static inline int dfu_get_state(void)
459 {
460   struct usb_dfu_dev *dev = usb_dfu_get_dev();
461   return dev->dfu_state;
462 }
463 
dfu_dnload_complete(struct usbdev_ep_s * ep,struct usbdev_req_s * req)464 static void dfu_dnload_complete(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
465 {
466   struct usb_dfu_dev *dev = usb_dfu_get_dev();
467   int ret;
468 
469   (void)ep;
470 
471   ret = usb_dfu_write(usb_dfu_get_entity(0), req->buf, (int)req->len, dev->seq_num);
472   if (ret < 0)
473     {
474       dev->dfu_status.status = USB_DFU_ERR_UNKNOWN;
475       dev->dfu_state = USB_DFU_ERROR;
476     }
477 }
478 
usbdev_dfu_set_config(void)479 void usbdev_dfu_set_config(void)
480 {
481   struct usb_dfu_dev *dev = usb_dfu_get_dev();
482 
483   if (dev->dfu_state == USB_DFU_APP_DETACH)
484     {
485       dev->dfu_state = USB_DFU_IDLE;
486     }
487 
488   dev->dfu_status.status = USB_DFU_STATUS_OK;
489 }
490 
usbdev_dfu_transaction_cleanup(void)491 void usbdev_dfu_transaction_cleanup(void)
492 {
493   struct usb_dfu_entity *entity = usb_dfu_get_entity(0);
494 
495   if (entity == NULL)
496     {
497       return;
498     }
499 
500   entity->trans_size     = 0;
501   entity->trans_complete = 0;
502   entity->seq_num        = 0;
503   entity->offset         = 0;
504 }
505 
usbdev_dfu_init(void)506 void usbdev_dfu_init(void)
507 {
508   struct usb_dfu_dev *dev = usb_dfu_get_dev();
509 
510   if (dev == NULL)
511     {
512       return;
513     }
514 
515   /* When the host confirm that the dfu "bInterfaceProtocol" is the "Runtime mode"
516    * it will send a "DFU_DETACH" request to the device. When unload device, the device
517    * mode should change from "DFU mode" to "Runtime mode", so that next upgrade action
518    * can be performed smoothly.
519    *
520    * bInterfaceProtocol value: 0x1 --- Runtime protocol.
521    * bInterfaceProtocol value: 0x2 --- DFU mode protocol.
522    *
523    * More information, please refer to DFU_1.1.pdf
524    */
525 
526   to_runtime_mode();
527   dev->dfu_state = USB_DFU_APP_IDLE;
528   (void)memset_s(&dev->dfu_status, sizeof(struct dfu_getstatus_response_s),
529                  0, sizeof(struct dfu_getstatus_response_s));
530   dev->dfu_status.poll_timeout[0] = USB_DFU_POLLTIMEOUT;
531 
532   usbdev_dfu_transaction_cleanup();
533 }
534 
dfu_get_status_for_req(struct usbdev_req_s * ctrlreq)535 static int dfu_get_status_for_req(struct usbdev_req_s *ctrlreq)
536 {
537   struct dfu_getstatus_response_s *status = (struct dfu_getstatus_response_s *)ctrlreq->buf;
538   struct usb_dfu_dev *dev = usb_dfu_get_dev();
539   int dfu_state = dev->dfu_state;
540 
541   if (dfu_state == USB_DFU_DNLOAD_SYNC)
542     {
543       dev->dfu_state = USB_DFU_DNLOAD_IDLE;
544     }
545   else if (dfu_state == USB_DFU_DNBUSY)
546     {
547       dev->dfu_state = USB_DFU_DNLOAD_SYNC;
548     }
549   else if (dfu_state == USB_DFU_MANIFEST_SYNC)
550     {
551       dev->dfu_state = USB_DFU_MANIFEST;
552     }
553   else if (dfu_state == USB_DFU_MANIFEST)
554     {
555       dev->dfu_state = USB_DFU_IDLE;
556     }
557 
558   *status = dev->dfu_status;
559   status->state = (uint8_t)dev->dfu_state;
560 
561   return USB_DFU_RET_STATUS_LEN;
562 }
563 
dfu_get_state_for_req(struct usbdev_req_s * ctrlreq)564 static int dfu_get_state_for_req(struct usbdev_req_s *ctrlreq)
565 {
566   uint8_t *state = ctrlreq->buf;
567 
568   *state = (uint8_t)dfu_get_state();
569 
570   return USB_DFU_RET_STATE_LEN;
571 }
572 
dfu_dnload(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)573 static int dfu_dnload(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
574 {
575   struct usb_dfu_dev *dev = usb_dfu_get_dev();
576   int len                 = UGETW(ctrl->wLength);
577   uint16_t value          = UGETW(ctrl->wValue);
578 
579   dev->dfu_state = USB_DFU_DNLOAD_SYNC;
580   dev->seq_num   = value;
581 
582   if (len == 0)
583     {
584       if (dev->dfu_state == USB_DFU_IDLE)
585         {
586           dev->dfu_state = USB_DFU_ERROR;
587           return USB_DFU_RET_ERR;
588         }
589       else
590         {
591           dev->dfu_state = USB_DFU_MANIFEST_SYNC;
592         }
593     }
594 
595   ctrlreq->callback = dfu_dnload_complete;
596 
597   return len;
598 }
599 
dfu_upload(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)600 static int dfu_upload(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
601 {
602   struct usb_dfu_dev *dev = usb_dfu_get_dev();
603   uint16_t value          = UGETW(ctrl->wValue);
604 
605   if (dev->dfu_state == USB_DFU_IDLE)
606     {
607       dev->dfu_state = USB_DFU_UPLOAD_IDLE;
608       dev->seq_num   = 0;
609       usbdev_dfu_transaction_cleanup();
610     }
611   else if (dev->dfu_state == USB_DFU_UPLOAD_IDLE)
612     {
613       dev->seq_num = value;
614     }
615 
616   return usb_dfu_read(usb_dfu_get_entity(0), ctrlreq->buf, (int)ctrlreq->len, dev->seq_num);
617 }
618 
dfu_app_idle_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)619 static int dfu_app_idle_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
620 {
621   int ret = USB_DFU_RET_OK;
622 
623   switch (ctrl->bRequest)
624     {
625     case USB_DFU_DETACH:
626       {
627         to_dfu_mode();
628         dfu_set_state(USB_DFU_APP_DETACH);
629       }
630       break;
631 
632     case USB_DFU_GET_STATUS:
633       ret = dfu_get_status_for_req(ctrlreq);
634       break;
635 
636     case USB_DFU_GET_STATE:
637       ret = dfu_get_state_for_req(ctrlreq);
638       break;
639 
640     default:
641       {
642         ret = USB_DFU_RET_ERR;
643         dfu_set_state(USB_DFU_APP_IDLE);
644       }
645       break;
646     }
647 
648   return ret;
649 }
650 
dfu_app_detach_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)651 static int dfu_app_detach_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
652 {
653   int ret;
654 
655   switch (ctrl->bRequest)
656     {
657     case USB_DFU_GET_STATUS:
658       ret = dfu_get_status_for_req(ctrlreq);
659       break;
660 
661     case USB_DFU_GET_STATE:
662       ret = dfu_get_state_for_req(ctrlreq);
663       break;
664 
665     default:
666       {
667         ret = USB_DFU_RET_ERR;
668         dfu_set_state(USB_DFU_APP_IDLE);
669       }
670       break;
671     }
672 
673   return ret;
674 }
675 
dfu_idle_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)676 static int dfu_idle_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
677 {
678   int ret = USB_DFU_RET_OK;
679 
680   switch (ctrl->bRequest)
681     {
682     case USB_DFU_GET_STATUS:
683       ret = dfu_get_status_for_req(ctrlreq);
684       break;
685 
686     case USB_DFU_GET_STATE:
687       ret = dfu_get_state_for_req(ctrlreq);
688       break;
689 
690     case USB_DFU_DNLOAD:
691       ret = dfu_dnload(ctrl, ctrlreq);
692       break;
693 
694     case USB_DFU_UPLOAD:
695       ret = dfu_upload(ctrl, ctrlreq);
696       break;
697 
698     case USB_DFU_ABORT:
699       dfu_set_state(USB_DFU_IDLE);
700       break;
701 
702     case USB_DFU_FLASH_STATE:
703       {
704         get_flash_state(ctrlreq);
705         ret = 1;
706       }
707       break;
708 
709     default:
710       {
711         ret = USB_DFU_RET_ERR;
712         dfu_set_state(USB_DFU_ERROR);
713       }
714       break;
715     }
716 
717   return ret;
718 }
719 
dfu_dnload_sync_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)720 static int dfu_dnload_sync_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
721 {
722   int ret;
723 
724   switch (ctrl->bRequest)
725     {
726     case USB_DFU_GET_STATUS:
727       ret = dfu_get_status_for_req(ctrlreq);
728       break;
729 
730     case USB_DFU_GET_STATE:
731       ret = dfu_get_state_for_req(ctrlreq);
732       break;
733 
734     default:
735       {
736         ret = USB_DFU_RET_ERR;
737         dfu_set_state(USB_DFU_ERROR);
738       }
739       break;
740     }
741 
742   return ret;
743 }
744 
dfu_dnbusy_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)745 static int dfu_dnbusy_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
746 {
747   int ret;
748 
749   switch (ctrl->bRequest)
750     {
751     case USB_DFU_GET_STATUS:
752       ret = dfu_get_status_for_req(ctrlreq);
753       break;
754 
755     default:
756       {
757         ret = USB_DFU_RET_ERR;
758         dfu_set_state(USB_DFU_ERROR);
759       }
760       break;
761     }
762 
763   return ret;
764 }
765 
dfu_dnload_idle_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)766 static int dfu_dnload_idle_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
767 {
768   int ret = USB_DFU_RET_OK;
769 
770   switch (ctrl->bRequest)
771     {
772     case USB_DFU_GET_STATUS:
773       ret = dfu_get_status_for_req(ctrlreq);
774       break;
775 
776     case USB_DFU_GET_STATE:
777       ret = dfu_get_state_for_req(ctrlreq);
778       break;
779 
780     case USB_DFU_DNLOAD:
781       ret = dfu_dnload(ctrl, ctrlreq);
782       break;
783 
784     case USB_DFU_ABORT:
785       dfu_set_state(USB_DFU_IDLE);
786       break;
787 
788     default:
789       {
790         ret = USB_DFU_RET_ERR;
791         dfu_set_state(USB_DFU_ERROR);
792       }
793       break;
794     }
795 
796   return ret;
797 }
798 
dfu_manifest_sync_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)799 static int dfu_manifest_sync_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
800 {
801   struct usb_dfu_dev *dev = usb_dfu_get_dev();
802   struct usb_dfu_entity *entity = usb_dfu_get_entity(0);
803   int ret;
804 
805   switch (ctrl->bRequest)
806     {
807     case USB_DFU_GET_STATUS:
808       {
809         dev->seq_num = 0;
810         ret          = dfu_get_status_for_req(ctrlreq);
811         if (entity != NULL)
812           {
813             entity->seq_num = 0;
814             entity->offset  = 0;
815           }
816       }
817       break;
818 
819     case USB_DFU_GET_STATE:
820       ret = dfu_get_state_for_req(ctrlreq);
821       break;
822 
823     default:
824       {
825         ret = USB_DFU_RET_ERR;
826         dfu_set_state(USB_DFU_ERROR);
827       }
828       break;
829     }
830 
831   return ret;
832 }
833 
dfu_manifest_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)834 static int dfu_manifest_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
835 {
836   struct usb_dfu_dev *dev = usb_dfu_get_dev();
837   struct usb_dfu_entity *entity = usb_dfu_get_entity(0);
838   int ret;
839 
840   switch (ctrl->bRequest)
841     {
842     case USB_DFU_GET_STATUS:
843       {
844         ret = dfu_get_status_for_req(ctrlreq);
845         dev->seq_num = 0;
846         if (entity != NULL)
847           {
848             entity->trans_complete = 1;
849           }
850         dprintf("\nDOWNLOAD ... OK\n");
851       }
852       break;
853 
854     case USB_DFU_GET_STATE:
855       ret = dfu_get_state_for_req(ctrlreq);
856       break;
857 
858     default:
859       {
860         ret = USB_DFU_RET_ERR;
861         dfu_set_state(USB_DFU_ERROR);
862       }
863       break;
864     }
865 
866   return ret;
867 }
868 
dfu_manifest_wait_reset(const struct usb_device_request * ctrl,const struct usbdev_req_s * ctrlreq)869 static int dfu_manifest_wait_reset(const struct usb_device_request *ctrl, const struct usbdev_req_s *ctrlreq)
870 {
871   (void)ctrl;
872   (void)ctrlreq;
873   dprintf("Do nothing!\n");
874   return 0;
875 }
876 
dfu_upload_idle_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)877 static int dfu_upload_idle_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
878 {
879   int ret = USB_DFU_RET_OK;
880   int len = UGETW(ctrl->wLength);
881 
882   switch (ctrl->bRequest)
883     {
884     case USB_DFU_GET_STATUS:
885       ret = dfu_get_status_for_req(ctrlreq);
886       break;
887 
888     case USB_DFU_GET_STATE:
889       ret = dfu_get_state_for_req(ctrlreq);
890       break;
891 
892     case USB_DFU_UPLOAD:
893       {
894         ret = dfu_upload(ctrl, ctrlreq);
895         if (ret >= 0 && ret < len)
896           {
897             dfu_set_state(USB_DFU_IDLE);
898           }
899       }
900       break;
901 
902     case USB_DFU_ABORT:
903       dfu_set_state(USB_DFU_IDLE);
904       break;
905 
906     default:
907       {
908         ret = USB_DFU_RET_ERR;
909         dfu_set_state(USB_DFU_ERROR);
910       }
911       break;
912     }
913 
914   return ret;
915 }
916 
dfu_error_request(const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)917 static int dfu_error_request(const struct usb_device_request *ctrl, struct usbdev_req_s *ctrlreq)
918 {
919   struct usb_dfu_dev *dev = usb_dfu_get_dev();
920   int ret                 = USB_DFU_RET_OK;
921 
922   switch (ctrl->bRequest)
923     {
924     case USB_DFU_GET_STATUS:
925       ret = dfu_get_status_for_req(ctrlreq);
926       break;
927 
928     case USB_DFU_GET_STATE:
929       ret = dfu_get_state_for_req(ctrlreq);
930       break;
931 
932     case USB_DFU_CLR_STATUS:
933       {
934         dev->dfu_status.status = USB_DFU_STATUS_OK;
935         dfu_set_state(USB_DFU_IDLE);
936       }
937       break;
938 
939     default:
940       {
941         ret = USB_DFU_RET_ERR;
942         dfu_set_state(USB_DFU_ERROR);
943       }
944       break;
945     }
946 
947   return ret;
948 }
949 
usbdev_dfu_class_requests(const struct usbdev_s * dev,const struct usb_device_request * ctrl,struct usbdev_req_s * ctrlreq)950 int usbdev_dfu_class_requests(const struct usbdev_s *dev,
951                               const struct usb_device_request *ctrl,
952                               struct usbdev_req_s *ctrlreq)
953 {
954   int ret = -EOPNOTSUPP;
955 
956   (void)dev;
957 
958   switch (dfu_get_state())
959     {
960     case USB_DFU_APP_IDLE:
961       ret = dfu_app_idle_request(ctrl, ctrlreq);
962       break;
963 
964     case USB_DFU_APP_DETACH:
965       ret = dfu_app_detach_request(ctrl, ctrlreq);
966       break;
967 
968     case USB_DFU_IDLE:
969       ret = dfu_idle_request(ctrl, ctrlreq);
970       break;
971 
972     case USB_DFU_DNLOAD_SYNC:
973       ret = dfu_dnload_sync_request(ctrl, ctrlreq);
974       break;
975 
976     case USB_DFU_DNBUSY:
977       ret = dfu_dnbusy_request(ctrl, ctrlreq);
978       break;
979 
980     case USB_DFU_DNLOAD_IDLE:
981       ret = dfu_dnload_idle_request(ctrl, ctrlreq);
982       break;
983 
984     case USB_DFU_MANIFEST_SYNC:
985       ret = dfu_manifest_sync_request(ctrl, ctrlreq);
986       break;
987 
988     case USB_DFU_MANIFEST:
989       ret = dfu_manifest_request(ctrl, ctrlreq);
990       break;
991 
992     case USB_DFU_MANIFEST_WAIT_RESET:
993       ret = dfu_manifest_wait_reset(ctrl, ctrlreq);
994       break;
995 
996     case USB_DFU_UPLOAD_IDLE:
997       ret = dfu_upload_idle_request(ctrl, ctrlreq);
998       break;
999 
1000     case USB_DFU_ERROR:
1001       ret = dfu_error_request(ctrl, ctrlreq);
1002       break;
1003 
1004     default:
1005       usb_err("The state = %d of dfu is not support!\n", dfu_get_state());
1006       break;
1007     }
1008 
1009   return ret;
1010 }
1011 
dfu_ram_init_env(struct usb_dfu_entity * entity,char * envstr)1012 static int dfu_ram_init_env(struct usb_dfu_entity *entity, char *envstr)
1013 {
1014   char *st;
1015   int ret;
1016 
1017   st = strsep(&envstr, " ");
1018   if (st == NULL)
1019     {
1020       return -1;
1021     }
1022   ret = strncpy_s(entity->dfu_name, DFU_NAME_MAX_LEN, st, strlen(st) + 1);
1023   if (ret != EOK)
1024     {
1025       return -1;
1026     }
1027 
1028   st = strsep(&envstr, " ");
1029   if (strcmp(st, "ram"))
1030     {
1031       return -1;
1032     }
1033 
1034   st = strsep(&envstr, " ");
1035   if (st == NULL)
1036     {
1037       return -1;
1038     }
1039   entity->ram_addr = (void *)strtoul(st, &st, 16);
1040 
1041   st = strsep(&envstr, " ");
1042   if (st == NULL)
1043     {
1044       return -1;
1045     }
1046   entity->ram_size = strtoul(st, &st, 16);
1047 
1048   entity->dfu_write = dfu_ram_write;
1049   entity->dfu_read  = dfu_ram_read;
1050 
1051   return 0;
1052 }
1053 
usb_dfu_init_env_entities(char * type,char * envstr,char * devstr)1054 int usb_dfu_init_env_entities(char *type, char *envstr, char *devstr)
1055 {
1056   struct usb_dfu_entity *entity;
1057   int ret;
1058 
1059   (void)devstr;
1060 
1061   if (type == NULL || envstr == NULL)
1062     {
1063       return -1;
1064     }
1065 
1066   mtx_lock(&g_dfu_mtx);
1067   if (g_dfu_entity != NULL)
1068     {
1069       goto err;
1070     }
1071 
1072   entity = malloc(sizeof(struct usb_dfu_entity));
1073   if (entity == NULL)
1074     {
1075       goto err;
1076     }
1077   (void)memset_s(entity, sizeof(struct usb_dfu_entity), 0, sizeof(struct usb_dfu_entity));
1078 
1079   if (!strcmp(type, "ram"))
1080     {
1081       ret = dfu_ram_init_env(entity, envstr);
1082       if (ret < 0)
1083         {
1084           free(entity);
1085           goto err;
1086         }
1087     }
1088   else
1089     {
1090       free(entity);
1091       usb_err("Device %s not (yet) supported!\n", type);
1092       goto err;
1093     }
1094 
1095   g_dfu_entity = entity;
1096   usbdev_dfu_transaction_cleanup();
1097   mtx_unlock(&g_dfu_mtx);
1098 
1099   return 0;
1100 err:
1101   mtx_unlock(&g_dfu_mtx);
1102   return -1;
1103 }
1104 
usb_dfu_free_entities(void)1105 void usb_dfu_free_entities(void)
1106 {
1107   mtx_lock(&g_dfu_mtx);
1108   if (g_dfu_entity == NULL)
1109     {
1110       mtx_unlock(&g_dfu_mtx);
1111       return;
1112     }
1113   free(g_dfu_entity);
1114   g_dfu_entity = NULL;
1115   mtx_unlock(&g_dfu_mtx);
1116 }
1117 
usb_dfu_get_entity(int alter)1118 struct usb_dfu_entity *usb_dfu_get_entity(int alter)
1119 {
1120   (void)alter;
1121   return g_dfu_entity;
1122 }
1123 
usb_dfu_read(struct usb_dfu_entity * dfu,void * buf,int size,uint32_t blk_seq_num)1124 int usb_dfu_read(struct usb_dfu_entity *dfu, void *buf, int size, uint32_t blk_seq_num)
1125 {
1126   int ret;
1127 
1128   if (dfu == NULL || buf == NULL)
1129     {
1130       return -1;
1131     }
1132 
1133   if (dfu->seq_num != blk_seq_num)
1134     {
1135       return -1;
1136     }
1137   dfu->seq_num++;
1138 
1139   ret = dfu->dfu_read(buf, size);
1140   if (ret < 0)
1141     {
1142       return -1;
1143     }
1144 
1145   if (dfu->offset >= dfu->trans_size)
1146     {
1147       dprintf("\nUPLOAD ... done\n");
1148       usbdev_dfu_transaction_cleanup();
1149     }
1150 
1151   return ret;
1152 }
1153 
usb_dfu_write(struct usb_dfu_entity * dfu,void * buf,int size,uint32_t blk_seq_num)1154 int usb_dfu_write(struct usb_dfu_entity *dfu, void *buf, int size, uint32_t blk_seq_num)
1155 {
1156   int ret;
1157 
1158   if (dfu == NULL || buf == NULL)
1159     {
1160       return -1;
1161     }
1162 
1163   if (dfu->seq_num != blk_seq_num)
1164     {
1165       usbdev_dfu_transaction_cleanup();
1166       return -1;
1167     }
1168   dfu->seq_num++;
1169 
1170   ret = dfu->dfu_write(buf, size);
1171   if (ret < 0)
1172     {
1173       usbdev_dfu_transaction_cleanup();
1174       return -1;
1175     }
1176 
1177   return 0;
1178 }
1179 
usbdev_dfu_mkdevdesc(uint8_t * buf)1180 void usbdev_dfu_mkdevdesc(uint8_t *buf)
1181 {
1182   errno_t ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, &g_dfu_device_desc, sizeof(g_dfu_device_desc));
1183   if (ret != EOK)
1184     {
1185       usb_err("memcpy_s fail!, ret:%d\n", ret);
1186       return;
1187     }
1188 }
1189 
usbdev_dfu_mkstrdesc(uint8_t id,uint8_t * buf)1190 int usbdev_dfu_mkstrdesc(uint8_t id, uint8_t *buf)
1191 {
1192   errno_t ret;
1193   const char *str;
1194   int i;
1195 
1196   for (i = 0; g_dfu_string_defs[i].s != NULL; i++)
1197     {
1198       str = g_dfu_string_defs[i].s;
1199       if (g_dfu_string_defs[i].id == id)
1200         {
1201           ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, str, str[0]);
1202           if (ret != EOK)
1203             {
1204               usb_err("memcpy_s failed, ret = %d\n", ret);
1205               return -1;
1206             }
1207           return str[0];
1208         }
1209     }
1210   usb_err("Can not find the id = %u of string\n", id);
1211 
1212   return -1;
1213 }
1214 
usbdev_dfu_initialize_sub(struct composite_devdesc_s * dev,int ifnobase,int minor)1215 static void usbdev_dfu_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor)
1216 {
1217   usbdev_dfu_get_composite_devdesc(dev);
1218 
1219   /* Interfaces */
1220 
1221   dev->devinfo.ifnobase = ifnobase; /* Offset to Interface-IDs */
1222   dev->minor = minor;               /* The minor interface number */
1223 
1224   /* Strings */
1225 
1226   dev->devinfo.strbase = 0;         /* Offset to String Numbers */
1227 }
1228 
usbdev_dfu_initialize(struct module * mod,int n,void * arg)1229 int usbdev_dfu_initialize(struct module *mod, int n, void *arg)
1230 {
1231   struct composite_softc *com_s = (struct composite_softc *)arg;
1232   struct composite_devdesc_s dev;
1233   int ret;
1234 
1235   /* ignore compilation warnings */
1236 
1237   (void)mod;
1238   (void)n;
1239 
1240   if (com_s == NULL)
1241     {
1242       return -1;
1243     }
1244 
1245   usbdev_dfu_initialize_sub(&dev, 0, DEV_DFU);
1246 
1247   ret = composite_initialize(com_s, 1, &dev);
1248   if (ret < 0)
1249     {
1250       return -1;
1251     }
1252 
1253   PRINTK("** DFU device initialized successfully! **\n");
1254   return 0;
1255 }
1256 
1257 #ifdef __cplusplus
1258 #if __cplusplus
1259 }
1260 #endif /* __cplusplus */
1261 #endif /* __cplusplus */