• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------------
2  * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved.
3  * Description: LiteOS USB Driver HID Protocol
4  * Author: wanghongxu
5  * Create: 2019-10-24
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 "gadget/f_hid.h"
38 #include "gadget/usbd_hid.h"
39 #include "core/usbhid.h"
40 #include "implementation/global_implementation.h"
41 #ifdef LOSCFG_DRIVERS_USB2_DEVICE_CONTROLLER
42 #include "controller/usb_device/dwc_otg_pcd.h"
43 #endif
44 
45 #ifdef __cplusplus
46 #if __cplusplus
47 extern "C" {
48 #endif /* __cplusplus */
49 #endif /* __cplusplus */
50 
51 int usbdev_hid_initialize(struct module *mod, int n, void *arg);
52 
53 /* device driver structure definition */
54 
55 static const driver_t g_fhid_driver =
56 {
57   .name     = "fhid",
58   .methods  = NULL,
59   .size     = sizeof(struct hid_softc)
60 };
61 
62 /* private device class information */
63 
64 static devclass_t g_fhid_devclass;
65 DRIVER_MODULE(fhid, simple, g_fhid_driver, g_fhid_devclass, usbdev_hid_initialize, 0);
66 
67 static int usbclass_hid_bind(struct usbdevclass_driver_s *driver, struct usbdev_s *dev);
68 static int usbclass_hid_unbind(struct usbdevclass_driver_s *driver, struct usbdev_s *dev);
69 static int usbclass_hid_setup(struct usbdevclass_driver_s *driver, struct usbdev_s *dev,
70                               const struct usb_device_request *ctrl, uint8_t *dataout, size_t outlen);
71 static void usbclass_hid_disconnect(struct usbdevclass_driver_s *driver, struct usbdev_s *dev);
72 
73 /* USB driver operations */
74 
75 static const struct usbdevclass_driverops_s g_hid_driverops =
76 {
77   usbclass_hid_bind,
78   usbclass_hid_unbind,
79   usbclass_hid_setup,
80   usbclass_hid_disconnect,
81   NULL,
82   NULL
83 };
84 
85 static struct dev_report_desc g_fhid_report_desc;
86 
87 #define HID_STRING_HEAD_LEN   2
88 #define HID_STRING_DESC_NUM   3
89 #define HID_STRING_LEN_MAX    0xFF
90 
91 #define HID_STR_LANG 4
92 static const char g_fhid_str_lang[HID_STR_LANG] =
93 {
94   HID_STR_LANG,
95   UDESC_STRING,
96   0x09, 0x04
97 };
98 
99 #define HID_STR_IDX_INTERFACE 28
100 static const char g_fhid_str_interface[HID_STR_IDX_INTERFACE] =
101 {
102   HID_STR_IDX_INTERFACE,
103   UDESC_STRING,
104   'H', 0, 'I', 0, 'D', 0, ' ', 0, 'I', 0, 'n', 0, 't', 0,
105   'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0
106 };
107 
108 struct usbd_string g_fhid_device_strings[6] =
109 {
110   { 0, g_fhid_str_lang },
111   { 1, NULL },
112   { 2, NULL },
113   { 3, NULL },
114   { 4, g_fhid_str_interface },
115   USBD_DEVICE_STRINGS_END
116 };
117 
118 static struct usb_device_descriptor g_fhid_device_desc =
119 {
120   .bLength            = sizeof(struct usb_device_descriptor),
121   .bDescriptorType    = UDESC_DEVICE, /* Constant for device descriptor */
122   HSETW(.bcdUSB, UD_BCD_USB),         /* USB version required: 2.0 */
123   .bDeviceClass       = 0x00,         /* Miscellaneous Device Class */
124   .bDeviceSubClass    = 0x00,         /* Common Class */
125   .bDeviceProtocol    = 0x00,         /* Interface Association Descriptor */
126   .bMaxPacketSize     = UD_USB_MPS,   /* Control Endpoint packet size */
127   HSETW(.bcdDevice,   0x0100),        /* Device release code */
128   .iManufacturer      = 1,            /* Manufacturer name, string index */
129   .iProduct           = 2,            /* Product name, string index */
130   .iSerialNumber      = 3,            /* Used */
131   .bNumConfigurations = 1             /* One Configuration */
132 };
133 
134 static struct usb_config_descriptor g_fhid_config_desc =
135 {
136   .bLength              = sizeof(struct usb_config_descriptor),
137   .bDescriptorType      = UDESC_CONFIG,
138   HSETW(.wTotalLength, 0x0029), /* Size of all descriptors, set later */
139   .bNumInterface        = 0x1,  /* Number of Interfaces */
140   .bConfigurationValue  = 0x1,  /* ID of this configuration */
141   .iConfiguration       = 0x0,  /* Index of string descriptor */
142   .bmAttributes         = 0xc0, /* Self-powered */
143   .bMaxPower            = 0x32  /* Maximum power consumption from the bus */
144 };
145 
146 static const struct usb_interface_descriptor g_fhid_intf_desc =
147 {
148   .bLength              = sizeof(struct usb_interface_descriptor),
149   .bDescriptorType      = UDESC_INTERFACE,
150   .bInterfaceNumber     = 0,    /* index number of this interface */
151   .bAlternateSetting    = 0,    /* index of this settings */
152   .bNumEndpoints        = 2,    /* Number of endpoint */
153   .bInterfaceClass      = 0x03, /* bInterfaceClass: HID */
154   .bInterfaceSubClass   = 0,    /* bInterfaceSubClass : 1=BOOT, 0=no boot */
155   .bInterfaceProtocol   = 0,    /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
156   .iInterface           = 4     /* index of string descriptor */
157 };
158 
159 static struct usb_hid_descriptor g_fhid_desc =
160 {
161   .bLength          = sizeof(struct usb_hid_descriptor),
162   .bDescriptorType  = UDESC_HID, /* HID type is 0x21 */
163   HSETW(.bcdHID, 0x0110),   /* bcdHID: HID Class Spec release number HID 1.1 */
164   .bCountryCode     = 0x00, /* bCountryCode: Hardware target country */
165   .bNumDescriptors  = 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
166   {
167     {
168       .bDescriptorType = 0x22, /* bDescriptorType */
169     }
170   }
171 };
172 
173 static const struct hid_endpoint_descriptor g_fhid_in_ep_desc =
174 {
175   .bLength          = sizeof(struct hid_endpoint_descriptor),
176   .bDescriptorType  = UDESC_ENDPOINT,
177   .bEndpointAddress = UE_DIR_IN | 0x01,
178   .bmAttributes     = 0x03,                  /* bmAttributes = 00000011b */
179   HSETW(.wMaxPacketSize,  HID_IN_DATA_SIZE), /* wMaxPacketSize = 64 */
180   .bInterval        = 0x04                   /* bInterval = 4ms */
181 };
182 
183 static const struct hid_endpoint_descriptor g_fhid_out_ep_desc =
184 {
185   .bLength          = sizeof(struct hid_endpoint_descriptor),
186   .bDescriptorType  = UDESC_ENDPOINT,
187   .bEndpointAddress = UE_DIR_OUT | 0x01,
188   .bmAttributes     = 0x03,
189   HSETW(.wMaxPacketSize,  HID_OUT_DATA_SIZE),
190   .bInterval        = 0x04
191 };
192 
193 const uint8_t *g_fhid_desc_array[] =
194 {
195   (const uint8_t *)&g_fhid_config_desc,
196   (const uint8_t *)&g_fhid_intf_desc,
197   (const uint8_t *)&g_fhid_desc,
198   (const uint8_t *)&g_fhid_in_ep_desc,
199   (const uint8_t *)&g_fhid_out_ep_desc,
200   NULL,
201 };
202 
hid_deviceid_info(uint16_t vendorid,uint16_t productid)203 void hid_deviceid_info(uint16_t vendorid, uint16_t productid)
204 {
205   USETW(g_fhid_device_desc.idVendor, vendorid);
206 
207   USETW(g_fhid_device_desc.idProduct, productid);
208 }
209 
hid_device_string_info(const struct dev_string_desc * str_manufacturer,const struct dev_string_desc * str_product,const struct dev_string_desc * str_serial_number)210 int hid_device_string_info(const struct dev_string_desc *str_manufacturer,
211                            const struct dev_string_desc *str_product,
212                            const struct dev_string_desc *str_serial_number)
213 {
214   char *buf[HID_STRING_DESC_NUM] = {NULL};
215   const struct dev_string_desc *str_desc[HID_STRING_DESC_NUM];
216   int i;
217   uint32_t len;
218 
219   if (str_manufacturer == NULL || str_product == NULL || str_serial_number == NULL)
220     {
221       usb_err("%s failed, invalid param!\n", __FUNCTION__);
222       return -1;
223     }
224 
225   if (str_manufacturer->str == NULL || str_manufacturer->len == 0 ||
226       str_serial_number->str == NULL || str_serial_number->len == 0 ||
227       str_product->str == NULL || str_product->len == 0)
228     {
229       usb_err("%s failed, str is NULL or len is 0\n", __FUNCTION__);
230       return -1;
231     }
232 
233   if (str_manufacturer->len > (HID_STRING_LEN_MAX - HID_STRING_HEAD_LEN) ||
234       str_serial_number->len > (HID_STRING_LEN_MAX - HID_STRING_HEAD_LEN) ||
235       str_product->len > (HID_STRING_LEN_MAX - HID_STRING_HEAD_LEN))
236     {
237       usb_err("%s failed, len exceeds maximum limit! str_manufacturer->len = %u"
238               "str_serial_number->len = %u str_product->len = %u\n", __FUNCTION__,
239               str_manufacturer->len, str_serial_number->len, str_product->len);
240       return -1;
241     }
242 
243   str_desc[0] = str_manufacturer;
244   str_desc[1] = str_product;
245   str_desc[2] = str_serial_number;
246 
247   for (i = 0; i < HID_STRING_DESC_NUM; i++)
248     {
249       len = str_desc[i]->len + HID_STRING_HEAD_LEN;
250       buf[i] = (char *)malloc(len);
251       if (buf[i] == NULL)
252         {
253           usb_err("%s malloc failed\n", __FUNCTION__);
254           goto errout;
255         }
256       g_fhid_device_strings[i + 1].s = buf[i];
257 
258       *buf[i] = (char)len;
259       *(buf[i] + 1) = UDESC_STRING;
260 
261       /* len represents the size of the string */
262 
263       (void)memcpy_s(buf[i] + HID_STRING_HEAD_LEN, (size_t)str_desc[i]->len,
264                      str_desc[i]->str, (size_t)str_desc[i]->len);
265     }
266 
267   return 0;
268 
269 errout:
270   for (i = 0; i < HID_STRING_DESC_NUM; i++)
271     {
272       if (buf[i] != NULL)
273         {
274           free(buf[i]);
275         }
276     }
277   return -1;
278 }
279 
hid_report_descriptor_info(const void * buf,size_t len)280 int hid_report_descriptor_info(const void *buf, size_t len)
281 {
282   uint8_t *report_desc;
283 
284   if (buf == NULL || len == 0)
285     {
286       usb_err("%s failed, buf is NULL or len is 0\n", __FUNCTION__);
287       return -1;
288     }
289 
290   report_desc = (uint8_t *)malloc(len);
291   if (report_desc == NULL)
292     {
293       usb_err("%s malloc failed\n", __FUNCTION__);
294       return -1;
295     }
296 
297   g_fhid_report_desc.report_size = len;
298   g_fhid_report_desc.report_desc = report_desc;
299 
300   /* len represents the size of the report */
301 
302   (void)memcpy_s(report_desc, len, buf, len);
303 
304   return 0;
305 }
306 
usbdev_hid_free(void)307 static void usbdev_hid_free(void)
308 {
309   int i;
310 
311   if (g_fhid_report_desc.report_desc != NULL)
312     {
313       free(g_fhid_report_desc.report_desc);
314       g_fhid_report_desc.report_desc = NULL;
315     }
316 
317   for (i = 1; i <= HID_STRING_DESC_NUM; i++)
318     {
319       if (g_fhid_device_strings[i].s != NULL)
320         {
321           free((void *)g_fhid_device_strings[i].s);
322           g_fhid_device_strings[i].s = NULL;
323         }
324     }
325 }
326 
fhid_output_request_complete(struct usbdev_ep_s * ep,struct usbdev_req_s * req)327 static void fhid_output_request_complete(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
328 {
329   struct hid_dev_s *hid;
330   errno_t ret;
331   uint32_t ret_event;
332 
333   if (ep == NULL || ep->priv == NULL || req == NULL)
334     {
335       usb_err("Illegal request or ep!\n");
336       return;
337     }
338 
339   if (req->result != 0)
340     {
341       return;
342     }
343 
344   hid = (struct hid_dev_s *)ep->priv;
345   spin_lock(&hid->hid_lock);
346 
347   /* Save private data of read request */
348 
349   hid->read_len = req->xfrd;
350   ret = memcpy_s(hid->read_buf, HID_OUT_DATA_SIZE, req->buf, req->xfrd);
351   if (ret != EOK)
352     {
353       spin_unlock(&hid->hid_lock);
354       usb_err("memcpy fail!\n");
355       return;
356     }
357   spin_unlock(&hid->hid_lock);
358 
359   ret_event = LOS_EventWrite(&hid->read_event, USB_HID_READ_EVENT);
360   if (ret_event != LOS_OK)
361     {
362       usb_err("write event failed!\r\n");
363     }
364 
365   (void)EP_SUBMIT(hid->out_ep, req);
366 }
367 
fhid_input_req_complete(struct usbdev_ep_s * ep,struct usbdev_req_s * req)368 static void fhid_input_req_complete(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
369 {
370   struct hid_dev_s *hid = (struct hid_dev_s *)ep->priv;
371   struct hid_queue_node *node_temp;
372 
373   spin_lock(&hid->hid_lock);
374   atomic_set(&hid->busy_flag, 0);
375 
376   if (req->result != 0)
377     {
378       hid_queue_free(hid);
379       spin_unlock(&hid->hid_lock);
380       return;
381     }
382 
383   if (hid->cur_node != NULL)
384     {
385       node_temp = hid->cur_node;
386       if (node_temp->buf_len == 0)
387         {
388           hid_queue_node_free(node_temp);
389           hid->cur_node = NULL;
390         }
391       else
392         {
393           hid_send_data_sub(hid);
394           spin_unlock(&hid->hid_lock);
395           return;
396         }
397     }
398 
399   if (!list_empty(&hid->hid_queue))
400     {
401       node_temp = list_first_entry(&hid->hid_queue, struct hid_queue_node, irqqueue);
402       hid->cur_node = node_temp;
403       list_del_init(&node_temp->irqqueue);
404       hid->hid_queue_len--;
405       hid_send_data_sub(hid);
406     }
407   spin_unlock(&hid->hid_lock);
408 }
409 
fhid_source_free(struct hid_dev_s * hid,struct usbdev_s * dev)410 static void fhid_source_free(struct hid_dev_s *hid, struct usbdev_s *dev)
411 {
412   if (hid != NULL)
413     {
414       DEV_FREEEP(dev, hid->out_ep);
415       DEV_FREEEP(dev, hid->in_ep);
416     }
417 }
418 
usbclass_hid_bind(struct usbdevclass_driver_s * driver,struct usbdev_s * dev)419 static int usbclass_hid_bind(struct usbdevclass_driver_s *driver, struct usbdev_s *dev)
420 {
421   struct usbdev_ep_s *ep;
422   struct hid_driver_s *drvr;
423   struct composite_dev_s *cdev;
424   struct hid_dev_s *hid;
425   struct composite_devobj_s *devobj;
426   struct usbdev_devinfo_s *devinfo;
427   int ret;
428 
429   if (driver == NULL || dev == NULL)
430     {
431       return -1;
432     }
433 
434   cdev = dev->ep0->priv;
435   drvr = (struct hid_driver_s *)driver;
436   hid  = drvr->dev;
437   if (hid == NULL)
438     {
439       return -1;
440     }
441 
442   INIT_LIST_HEAD(&hid->hid_queue);
443   hid->busy_flag     = 0;
444   hid->hid_queue_len = 0;
445   hid->cur_node      = NULL;
446 
447   devobj = usbclass_devobj_get(cdev, DEV_HID);
448   if (devobj == NULL)
449     {
450       return -1;
451     }
452   devinfo = &devobj->compdesc.devinfo;
453 
454   /* Initialize the interrupt output endpoint */
455 
456   ep = DEV_ALLOCEP(dev, g_fhid_out_ep_desc.bEndpointAddress, (struct usb_endpoint_descriptor *)&g_fhid_out_ep_desc);
457   if (ep == NULL)
458     {
459       return -1;
460     }
461 
462   (void)memset_s(&(hid->outputreq), sizeof(struct usbdev_req_s), 0, sizeof(struct usbdev_req_s));
463   hid->outputreq.callback = fhid_output_request_complete;
464   hid->outputreq.priv     = (void *)hid;
465   hid->outputreq.buf      = NULL;
466   ep->priv                = (void *)hid;
467   ep->handle_req          = &hid->outputreq;
468   hid->out_ep             = ep;
469   devinfo->epno[0]        = ep->eplog;
470 
471   (VOID)LOS_EventInit(&hid->read_event);
472   spin_lock_init(&hid->hid_lock);
473   hid->read_len = 0;
474   hid->read_buf = memalign(USB_CACHE_ALIGN_SIZE, HID_OUT_DATA_SIZE);
475   if (hid->read_buf == NULL)
476     {
477       usb_err("Malloc failed!\n");
478       goto errout;
479     }
480 
481   /* Initialize the interrupt input endpoint */
482 
483   ep = DEV_ALLOCEP(dev, g_fhid_in_ep_desc.bEndpointAddress, (struct usb_endpoint_descriptor *)&g_fhid_in_ep_desc);
484   if (ep == NULL)
485     {
486       goto errout;
487     }
488 
489   (void)memset_s(&hid->inputreq, sizeof(struct usbdev_req_s), 0, sizeof(struct usbdev_req_s));
490   hid->inputreq.callback = fhid_input_req_complete;
491   hid->inputreq.priv     = (void *)hid;
492   hid->inputreq.buf      = NULL;
493   ep->priv               = (void *)hid;
494   ep->handle_req         = &hid->inputreq;
495   hid->in_ep             = ep;
496   devinfo->epno[1]       = ep->eplog;
497 
498   /* Registered character device */
499 
500   ret = hid_fops_init(hid);
501   if (ret != LOS_OK)
502     {
503       goto errout;
504     }
505 
506   return 0;
507 errout:
508   (void)usbclass_hid_unbind(driver, dev);
509   return -1;
510 }
511 
usbclass_hid_unbind(struct usbdevclass_driver_s * driver,struct usbdev_s * dev)512 static int usbclass_hid_unbind(struct usbdevclass_driver_s *driver, struct usbdev_s *dev)
513 {
514   struct composite_dev_s *cdev;
515   struct composite_devobj_s *devobj;
516   struct usbdev_devinfo_s *devinfo;
517   struct hid_driver_s *drvr;
518   struct hid_dev_s *hid;
519 
520   if (driver == NULL || dev == NULL)
521     {
522       return -1;
523     }
524 
525   drvr = (struct hid_driver_s *)driver;
526   hid  = drvr->dev;
527 
528   if (atomic_read(&hid->open_flag))
529     {
530       usb_err("HID device is busy!\n");
531       return -1;
532     }
533 
534   (void)hid_fops_deinit(hid);
535 
536   usbclass_hid_disconnect(driver, dev);
537 
538   /* Destroy read event */
539 
540   (VOID)LOS_EventDestroy(&hid->read_event);
541   if (hid->read_buf != NULL)
542     {
543       free(hid->read_buf);
544       hid->read_buf = NULL;
545     }
546 
547   fhid_source_free(hid, dev);
548 
549   cdev = dev->ep0->priv;
550   devobj = usbclass_devobj_get(cdev, DEV_HID);
551   if (devobj == NULL)
552     {
553       return -1;
554     }
555   devinfo = &devobj->compdesc.devinfo;
556   (void)memset_s(devinfo, sizeof(struct usbdev_devinfo_s), 0, sizeof(struct usbdev_devinfo_s));
557 
558   return 0;
559 }
560 
usbclass_hid_set_endpoint(struct usbdevclass_driver_s * driver,struct usbdev_s * dev)561 static void usbclass_hid_set_endpoint(struct usbdevclass_driver_s *driver, struct usbdev_s *dev)
562 {
563   struct usbdev_req_s *req;
564   struct hid_driver_s *drvr;
565   struct hid_dev_s *hid;
566   int ret;
567 
568   drvr = (struct hid_driver_s *)driver;
569   hid  = drvr->dev;
570 
571   hid->busy_flag = 0;
572   if (hid->in_ep_enabled == true)
573     {
574       (void)EP_DISABLE(hid->in_ep);
575       hid->in_ep_enabled = false;
576     }
577 
578   ret = EP_CONFIGURE(hid->in_ep, (const usb_endpoint_descriptor_t *)&g_fhid_in_ep_desc, 0);
579   if (ret < 0)
580     {
581       usb_err("Config interrupt in_ep failed!\n");
582       goto errout;
583     }
584   hid->in_ep_enabled = true;
585 
586   if (hid->out_ep_enabled == true)
587     {
588       (void)EP_DISABLE(hid->out_ep);
589       hid->out_ep_enabled = false;
590     }
591 
592   ret = EP_CONFIGURE(hid->out_ep, (const usb_endpoint_descriptor_t *)&g_fhid_out_ep_desc, 0);
593   if (ret < 0)
594     {
595       usb_err("Config interrupt out_ep failed!\n");
596       goto errout;
597     }
598   hid->out_ep_enabled = true;
599 
600   req = hid->out_ep->handle_req;
601   req->buf = (uint8_t *)hid->read_buf;
602   req->len = HID_OUT_DATA_SIZE;
603   ret      = EP_SUBMIT(hid->out_ep, req);
604   if (ret != OK)
605     {
606       usb_err("out_ep submit failed!\n");
607       goto errout;
608     }
609 
610   return;
611 
612 errout:
613   usbclass_hid_disconnect(driver, dev);
614 }
615 
usbclass_hid_get_report(struct usbdev_s * dev,uint32_t len)616 static void usbclass_hid_get_report(struct usbdev_s *dev, uint32_t len)
617 {
618   struct usbdev_req_s *req = dev->ep0->handle_req;
619   errno_t ret;
620 
621   ret = memcpy_s(req->buf, USB_COMP_EP0_BUFSIZ,
622                  g_fhid_report_desc.report_desc, g_fhid_report_desc.report_size);
623   if (ret != EOK)
624     {
625       usb_err("memcpy fail\n");
626       return;
627     }
628 
629   req->len = MIN(len, g_fhid_report_desc.report_size);
630 }
631 
usbclass_hid_setup(struct usbdevclass_driver_s * driver,struct usbdev_s * dev,const struct usb_device_request * ctrl,uint8_t * dataout,size_t outlen)632 static int usbclass_hid_setup(struct usbdevclass_driver_s *driver, struct usbdev_s *dev,
633                               const struct usb_device_request *ctrl, uint8_t *dataout, size_t outlen)
634 {
635   uint8_t req_type;
636   uint16_t w_value;
637   struct hid_dev_s *hid;
638   struct hid_driver_s *drvr;
639   struct usbdev_req_s *req;
640   int ret;
641   int new_req = 0;
642 
643   (void)dataout; (void)outlen;
644 
645   if (dev == NULL || driver == NULL || ctrl == NULL)
646     {
647       return -1;
648     }
649 
650   drvr = (struct hid_driver_s *)driver;
651   hid  = drvr->dev;
652   if (hid == NULL)
653     {
654       return -1;
655     }
656 
657   w_value   = UGETW(ctrl->wValue);
658   req       = dev->ep0->handle_req;
659   req_type  = ctrl->bmRequestType;
660   req->priv = hid;
661 
662   if (UT_GET_TYPE(req_type) == UT_STANDARD)
663     {
664       switch (ctrl->bRequest)
665         {
666         case USB_REQ_SET_CONFIGURATION:
667         case USB_REQ_SET_INTERFACE:
668           usbclass_hid_set_endpoint(driver, dev);
669           break;
670 
671         case UR_GET_HID_DESCRIPTOR:
672           {
673             if ((w_value >> 8) == UDESC_REPORT)
674               {
675                 usbclass_hid_get_report(dev, UGETW(ctrl->wLength));
676                 new_req = 1;
677               }
678           }
679           break;
680 
681         default:
682           break;
683         }
684     }
685   else
686     {
687       switch (ctrl->bRequest)
688         {
689         case UR_SET_IDLE:
690           {
691             req->len = 0;
692             new_req  = 1;
693           }
694           break;
695 
696         case UR_SET_REPORT:
697           {
698             req->len = MIN(UGETW(ctrl->wLength), HID_IN_DATA_SIZE);
699             ret = memset_s(req->buf, req->len, 0, req->len);
700             if (ret != EOK)
701               {
702                 usb_err("memset fail!\n");
703                 return -1;
704               }
705             new_req = 1;
706           }
707           break;
708 
709         case UR_GET_IDLE:
710           {
711             req->len = 0;
712             new_req  = 1;
713           }
714           break;
715 
716         case UR_GET_REPORT:
717           {
718             req->len = MIN(UGETW(ctrl->wLength), HID_IN_DATA_SIZE);
719             ret = memset_s(req->buf, req->len, 0, req->len);
720             if (ret != EOK)
721               {
722                 usb_err("memset fail!\n");
723                 return -1;
724               }
725             new_req = 1;
726           }
727           break;
728 
729         default:
730           break;
731         }
732   }
733 
734   if (new_req)
735     {
736       ret = EP_SUBMIT(dev->ep0, req);
737       if (ret != OK)
738         {
739           usb_err("Endpoint send fail!\n");
740           req->result = 0;
741           return -1;
742         }
743     }
744   return 0;
745 }
746 
usbclass_hid_disconnect(struct usbdevclass_driver_s * driver,struct usbdev_s * dev)747 static void usbclass_hid_disconnect(struct usbdevclass_driver_s *driver, struct usbdev_s *dev)
748 {
749   struct hid_driver_s *hid_drvr;
750   struct hid_dev_s *hid_dev;
751 
752   (void)dev;
753 
754   hid_drvr = (struct hid_driver_s *)driver;
755   hid_dev  = hid_drvr->dev;
756   if (hid_dev == NULL)
757     {
758       return;
759     }
760 
761   if (hid_dev->in_ep_enabled == true)
762     {
763       (void)EP_DISABLE(hid_dev->in_ep);
764       hid_dev->in_ep_enabled = false;
765     }
766 
767   if (hid_dev->out_ep_enabled == true)
768     {
769       (void)EP_DISABLE(hid_dev->out_ep);
770       hid_dev->out_ep_enabled = false;
771     }
772 }
773 
linkg_fhid_descriptors(const uint8_t * prefer,uint16_t ps,uint16_t * total_size)774 static uint8_t *linkg_fhid_descriptors(const uint8_t *prefer, uint16_t ps, uint16_t *total_size)
775 {
776   int i;
777   uint8_t *des;
778   uint8_t *pdes;
779   uint16_t ds = 0;
780   errno_t ret;
781 
782   (void)prefer;
783   (void)ps;
784 
785   /* Add the length of descriptors one by one */
786 
787   for (i = 0; g_fhid_desc_array[i] != NULL; ++i)
788     {
789       ds += (uint16_t)(*g_fhid_desc_array[i]);
790     }
791 
792   if (total_size != NULL)
793     {
794       *total_size = ds;
795     }
796 
797   des = memalign(64, SKB_DATA_ALIGN(ds));
798   if (des == NULL)
799     {
800       usb_err("System out of memory! Descriptors length: %u\n", ds);
801       return NULL;
802     }
803   (void)memset_s((void *)des, SKB_DATA_ALIGN(ds), 0, SKB_DATA_ALIGN(ds));
804 
805   pdes = des;
806 
807   /* configuration descriptor needs to have the full length of rest of descriptors */
808 
809   USETW(g_fhid_config_desc.wTotalLength, ds);
810 
811   for (i = 0; g_fhid_desc_array[i] != NULL; ++i)
812     {
813       const uint8_t *des_src = g_fhid_desc_array[i];
814       uint8_t des_len        = *des_src;
815       ret = memcpy_s(pdes, SKB_DATA_ALIGN(ds), des_src, des_len);
816       if (ret != EOK)
817         {
818           usb_err("memcpy fail!\n");
819           free(des);
820           return NULL;
821         }
822       pdes += des_len;
823     }
824 
825   return des;
826 }
827 
hid_mkdevdesc(uint8_t * buf)828 static void hid_mkdevdesc(uint8_t *buf)
829 {
830   errno_t ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, &g_fhid_device_desc, sizeof(g_fhid_device_desc));
831   if (ret != EOK)
832     {
833       usb_err("memcpy_s fail!, ret:%d\n", ret);
834       return;
835     }
836 }
837 
hid_mkcfgdesc(uint8_t * buf,struct usbdev_devinfo_s * devinfo)838 static int16_t hid_mkcfgdesc(uint8_t *buf, struct usbdev_devinfo_s *devinfo)
839 {
840   uint16_t total_len;
841   uint8_t *des;
842   errno_t ret;
843 
844   (void)devinfo;
845 
846   USETW(g_fhid_desc.descrs[0].wDescriptorLength, g_fhid_report_desc.report_size);
847 
848   des = linkg_fhid_descriptors(NULL, 0, &total_len);
849   if (des != NULL)
850     {
851       ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, des, total_len);
852       if (ret != EOK)
853         {
854           usb_err("memcpy_s fail!, ret:%d\n", ret);
855           free(des);
856           return 0;
857         }
858       free(des);
859     }
860 
861   return (int16_t)total_len;
862 }
863 
hid_mkstrdesc(uint8_t id,uint8_t * buf)864 static int hid_mkstrdesc(uint8_t id, uint8_t *buf)
865 {
866   errno_t ret;
867   const char *str;
868   int i;
869 
870   for (i = 0; g_fhid_device_strings[i].s != NULL; i++)
871     {
872       str = g_fhid_device_strings[i].s;
873       if (g_fhid_device_strings[i].id == id)
874         {
875           ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, (const void *)str, (uint32_t)str[0]);
876           if (ret != EOK)
877             {
878               usb_err("memcpy_s failed, ret = %d\n", ret);
879               return -1;
880             }
881           return str[0];
882         }
883     }
884 
885   usb_err("Can not find the id = %u of string\n", id);
886   return -1;
887 }
888 
889 #define HID_NCONFIGS    1
890 #define HID_CONFIGID    0
891 #define HID_NINTERFACES 1
892 #define HID_NSTRIDS     5
893 #define HID_NUM_EPS     2
hid_get_composite_devdesc(struct composite_devdesc_s * dev)894 static void hid_get_composite_devdesc(struct composite_devdesc_s *dev)
895 {
896   (void)memset_s(dev, sizeof(struct composite_devdesc_s), 0, sizeof(struct composite_devdesc_s));
897 
898   dev->mkdevdesc  = hid_mkdevdesc;
899   dev->mkconfdesc = hid_mkcfgdesc;
900   dev->mkstrdesc  = hid_mkstrdesc;
901 
902   dev->nconfigs = HID_NCONFIGS; /* Number of configurations supported */
903   dev->configid = HID_CONFIGID; /* The only supported configuration ID */
904 
905   /* Interfaces.
906    *
907    * ifnobase must be provided by board-specific logic
908    */
909 
910   dev->devinfo.ninterfaces = HID_NINTERFACES; /* Number of interfaces in the configuration */
911 
912   /* Strings.
913    *
914    * strbase must be provided by board-specific logic
915    */
916 
917   dev->devinfo.nstrings = HID_NSTRIDS; /* Number of Strings */
918 
919   /* Endpoints.
920     *
921     * Endpoint numbers must be provided by board-specific logic.
922     */
923 
924   dev->devinfo.nendpoints = HID_NUM_EPS;
925 }
926 
hid_classobject(int minor,struct usbdev_devinfo_s * devinfo,struct usbdevclass_driver_s ** classdev)927 static int hid_classobject(int minor, struct usbdev_devinfo_s *devinfo,
928                            struct usbdevclass_driver_s **classdev)
929 {
930   struct hid_softc *hid_s;
931   struct hid_dev_s *priv;
932   struct hid_driver_s *drvr;
933 
934   (void)minor;
935   (void)devinfo;
936 
937   /* Allocate the structures needed */
938 
939   hid_s = (struct hid_softc *)malloc(sizeof(struct hid_softc));
940   if (hid_s == NULL)
941     {
942       return -1;
943     }
944 
945   /* Convenience pointers into the allocated blob */
946 
947   priv = &hid_s->dev;
948   drvr = &hid_s->drvr;
949 
950   /* Initialize the USB serial driver structure */
951 
952   (void)memset_s(priv, sizeof(struct hid_dev_s), 0, sizeof(struct hid_dev_s));
953 
954   /* Initialize the USB class driver structure */
955 
956   drvr->drvr.speed = USB_SPEED_HIGH;
957   drvr->drvr.ops   = &g_hid_driverops;
958   drvr->dev        = priv;
959 
960   *classdev = &drvr->drvr;
961   return 0;
962 }
963 
hid_uninitialize(struct usbdevclass_driver_s * classdev)964 static void hid_uninitialize(struct usbdevclass_driver_s *classdev)
965 {
966   struct hid_driver_s *hid_drvr = (struct hid_driver_s *)classdev;
967   struct hid_dev_s *priv;
968   struct hid_softc *hid_s;
969 
970   usbdev_hid_free();
971 
972   if (hid_drvr == NULL)
973     {
974       return;
975     }
976 
977   priv = hid_drvr->dev;
978   if (priv == NULL)
979     {
980       return;
981     }
982 
983   hid_s = container_of(hid_drvr, struct hid_softc, drvr);
984   if (hid_s != NULL)
985     {
986       free(hid_s);
987     }
988 }
989 
usbdev_hid_initialize_sub(struct composite_devdesc_s * dev,int ifnobase,int minor)990 static void usbdev_hid_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor)
991 {
992   /* Ask the HID driver to fill in the constants we didn't
993    * know here.
994    */
995 
996   hid_get_composite_devdesc(dev);
997 
998   /* Overwrite and correct some values. */
999 
1000   /* The callback functions for the HID class */
1001 
1002   dev->classobject = hid_classobject;
1003   dev->uninitialize = hid_uninitialize;
1004 
1005   /* Interfaces */
1006 
1007   dev->devinfo.ifnobase = ifnobase; /* Offset to Interface-IDs */
1008   dev->minor = minor;               /* The minor interface number */
1009 
1010   /* Strings */
1011 
1012   dev->devinfo.strbase = 0;         /* Offset to String Numbers */
1013 }
1014 
usbdev_hid_initialize(struct module * mod,int n,void * arg)1015 int usbdev_hid_initialize(struct module *mod, int n, void *arg)
1016 {
1017   struct composite_softc *com_s = (struct composite_softc *)arg;
1018   struct composite_devdesc_s dev;
1019   int ret;
1020 
1021   (void)mod;
1022   (void)n;
1023   if (com_s == NULL)
1024     {
1025       return -1;
1026     }
1027 
1028   usbdev_hid_initialize_sub(&dev, 0, DEV_HID);
1029 
1030   ret = composite_initialize(com_s, 1, &dev);
1031   if (ret < 0)
1032     {
1033       return -1;
1034     }
1035 
1036   PRINTK("  ** hid device initialized successfully! **\n");
1037   return 0;
1038 }
1039 
1040 #ifdef __cplusplus
1041 #if __cplusplus
1042 }
1043 #endif /* __cplusplus */
1044 #endif /* __cplusplus */