• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------------
2  * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
3  * Description: LiteOS USB Driver Config Data Stream
4  * Author: Yannik Li
5  * Create: 2021-02-21
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 <poll.h>
38 #include "implementation/global_implementation.h"
39 #include "gadget/composite.h"
40 #include "f_common.h"
41 #include "devsvc_manager_clnt.h"
42 #include "hdf_device_desc.h"
43 
44 #ifdef __cplusplus
45 #if __cplusplus
46 //extern "C" {
47 #endif /* __cplusplus */
48 #endif /* __cplusplus */
49 
50 struct func_info {
51   uint8_t ndevices;
52   int ifnobase;
53   int strbase;
54   struct composite_devdesc_s *devs;
55 };
56 
57 extern void usbdev_generic_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor);
58 extern void usbdev_cdcacm_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor);
59 extern void usbdev_rndis_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor);
60 extern void usbdev_mass_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor);
61 extern void usbdev_uac_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor);
62 extern void usbdev_uvc_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor);
63 extern int gadget_strings_match(struct usb_obj *obj, void *match_data);
64 
65 struct usbdev_info g_generic_usbdev_info =
66 {
67   "generic", DEV_GENERIC, 0, usbdev_generic_initialize_sub
68 };
69 
70 struct usbdev_info *g_fconfig_usbdev_info[] =
71 {
72   &g_generic_usbdev_info,
73   NULL,
74 };
75 
fconfig_find_usbdev_info(char * name)76 static struct usbdev_info *fconfig_find_usbdev_info(char *name)
77 {
78   struct usbdev_info **dev_info = g_fconfig_usbdev_info;
79   int i;
80 
81   for (i = 0; dev_info[i] != NULL; i++)
82     {
83       if (strcmp(dev_info[i]->name, name) == 0)
84         {
85           return dev_info[i];
86         }
87     }
88 
89   return NULL;
90 }
91 
fconfig_get_string(struct usb_obj * obj,struct fconfig_string * str)92 static char *fconfig_get_string(struct usb_obj *obj, struct fconfig_string *str)
93 {
94   size_t size = str->len;
95   char *buf = NULL;
96   int ret;
97   buf = (char *)usbm_malloc(obj, (size + 1));
98   if (buf == NULL)
99     {
100       usb_err("%s: malloc name buffer failed\n", __FUNCTION__);
101       return NULL;
102     }
103   memset_s(buf, size, 0, size);
104 
105   ret = memcpy_s((void *)buf, (size + 1), (void *)str->s, size);
106   if (ret != EOK)
107     {
108       usb_err("%s: copy string from user failed\n", __FUNCTION__);
109       usbm_free(obj, buf);
110       return NULL;
111     }
112   *(buf + str->len) = '\0';
113   return buf;
114 }
115 
gadget_match(struct usb_obj * obj,void * match_data)116 static int gadget_match(struct usb_obj *obj, void *match_data)
117 {
118   struct gadget_info *gi = container_of(obj, struct gadget_info, obj);
119   return !strcmp(gi->name, (char *)match_data);
120 }
121 
gadget_find_by_name(struct fconfig_softc * cdev,struct fconfig_string * name)122 static struct gadget_info *gadget_find_by_name(struct fconfig_softc *cdev,
123                                                struct fconfig_string *name)
124 {
125   struct gadget_info *gi = NULL;
126   struct usb_obj *obj = NULL;
127   char *gadget_name = NULL;
128 
129   gadget_name = fconfig_get_string(&cdev->obj, name);
130   if (gadget_name == NULL)
131     {
132       usb_err("%s: get gadget name failed\n", __FUNCTION__);
133       return NULL;
134     }
135 
136   obj = usbobj_find(&cdev->obj, gadget_match, (void *)gadget_name);
137   if (obj)
138     {
139       gi = container_of(obj, struct gadget_info, obj);
140     }
141 
142   usbm_free(&cdev->obj, gadget_name);
143   return gi;
144 }
145 
gadget_make(struct fconfig_softc * cdev,char * name)146 static int gadget_make(struct fconfig_softc *cdev, char *name)
147 {
148   struct gadget_info *gi = NULL;
149   unsigned long flags;
150 
151   spin_lock_irqsave(&cdev->obj.lock, flags);
152   if (!list_empty(&cdev->obj.children))
153     {
154       usb_err("%s, %d: gadget had make\n", __FUNCTION__, __LINE__);
155       spin_unlock_irqrestore(&cdev->obj.lock, flags);
156       return -1;
157   }
158   spin_unlock_irqrestore(&cdev->obj.lock, flags);
159 
160   gi = usbm_malloc(&cdev->obj, sizeof(*gi));
161   if (gi == NULL)
162     {
163       usb_err("%s: malloc gadget failed\n", __FUNCTION__);
164       return -1;
165     }
166 
167   memset_s(gi, sizeof(*gi), 0, sizeof(*gi));
168   usbobj_init(&gi->obj, name, usbobj_default_release);
169   usbobj_init(&gi->strings, "strings", usbobj_default_release);
170   gi->name = name;
171   gi->cdev = cdev;
172   gi->com_s = cdev->com_s;
173   usbobj_add(&gi->obj, &cdev->obj);
174   return 0;
175 }
176 
gadget_drop(struct fconfig_softc * cdev,struct fconfig_string * name)177 static int gadget_drop(struct fconfig_softc *cdev, struct fconfig_string *name)
178 {
179   struct gadget_info *gi = NULL;
180 
181   gi = gadget_find_by_name(cdev, name);
182   if (gi == NULL)
183     {
184       usb_err("%s: can not find gadget\n", __FUNCTION__);
185       return -1;
186     }
187 
188   usbm_free(&cdev->obj, (void *)gi->name);
189   usbobj_put(&gi->strings);
190   usbobj_put(&gi->obj);
191   usbm_free(&cdev->obj, gi);
192   return 0;
193 }
194 
fconfig_make_gadget(struct fconfig_softc * cdev,void * user_data)195 static int fconfig_make_gadget(struct fconfig_softc *cdev, void *user_data)
196 {
197   struct fconfig_string str;
198   char *name = NULL;
199   int ret;
200 
201   ret = memcpy_s(&str, sizeof(str), user_data, sizeof(str));
202   if (ret != EOK)
203     {
204       return -1;
205     }
206 
207   name = fconfig_get_string(&cdev->obj, &str);
208   if (name == NULL)
209     {
210       usb_err("%s: get gadget name failed\n", __FUNCTION__);
211       return -1;
212     }
213 
214   return gadget_make(cdev, name);
215 }
216 
fconfig_drop_gadget(struct fconfig_softc * cdev,void * user_data)217 static int fconfig_drop_gadget(struct fconfig_softc *cdev, void *user_data)
218 {
219   struct fconfig_string str;
220   int ret;
221 
222   ret = memcpy_s(&str, sizeof(str), user_data, sizeof(str));
223   if (ret != EOK)
224     {
225       return -1;
226     }
227 
228   return gadget_drop(cdev, &str);
229 }
230 
fconfig_write_dev_desc(struct fconfig_softc * cdev,void * user_data)231 static int fconfig_write_dev_desc(struct fconfig_softc *cdev, void *user_data)
232 {
233   struct gadget_info *gi = NULL;
234   struct fconfig_dev_desc desc;
235   struct usb_device_descriptor *dev_desc = NULL;
236   int ret;
237 
238   ret = memcpy_s(&desc, sizeof(desc), user_data, sizeof(desc));
239   if (ret != EOK)
240     {
241       return -1;
242     }
243 
244   gi = gadget_find_by_name(cdev, &desc.gadget_name);
245   if (gi == NULL)
246     {
247       usb_err("%s: can not find the gadget\n", __FUNCTION__);
248        return -1;
249     }
250 
251   dev_desc = (struct usb_device_descriptor *)usbm_malloc(&gi->obj, sizeof(*dev_desc));
252   if (dev_desc == NULL)
253     {
254       usb_err("%s: malloc device descriptor failed\n", __FUNCTION__);
255       goto err;
256     }
257 
258   ret = memcpy_s(dev_desc, sizeof(*dev_desc), &desc.dev_desc, sizeof(*dev_desc));
259   if (ret != EOK)
260     {
261       goto err;
262     }
263 
264   gi->dev_desc = dev_desc;
265   return 0;
266 
267 err:
268   usbm_free(&gi->obj, dev_desc);
269   return -1;
270 }
271 
fconfig_alloc_gadget_cfg(struct gadget_info * gi,char * cfg_name,struct usb_config_descriptor * cfg_desc)272 static struct gadget_config *fconfig_alloc_gadget_cfg(struct gadget_info *gi, char *cfg_name,
273                                                       struct usb_config_descriptor *cfg_desc)
274 {
275   struct gadget_config *cfg = NULL;
276 
277   cfg = (struct gadget_config *)usbm_malloc(&gi->obj, sizeof(*cfg));
278   if (cfg == NULL)
279     {
280       usb_err("%s: malloc usb cfg failed\n", __FUNCTION__);
281       return NULL;
282     }
283   memset_s(cfg, sizeof(*cfg), 0, sizeof(*cfg));
284   usbobj_init(&cfg->obj, cfg_name, usbobj_default_release);
285 
286   cfg->gi       = gi;
287   cfg->name     = cfg_name;
288   cfg->cfg_desc = cfg_desc;
289   cfg->cfg_num  = cfg_desc->bConfigurationValue;
290 
291   return cfg;
292 }
293 
fconfig_add_gadget_cfg(struct fconfig_softc * cdev,void * user_data)294 static int fconfig_add_gadget_cfg(struct fconfig_softc *cdev, void *user_data)
295 {
296   struct usb_config_descriptor *cfg_desc = NULL;
297   struct fconfig_cfg_desc desc;
298   struct gadget_config *cfg = NULL;
299   struct gadget_info *gi = NULL;
300   struct usb_obj *obj = NULL;
301   char *cfg_name = NULL;
302   int ret;
303 
304   ret = memcpy_s(&desc, sizeof(desc), user_data, sizeof(desc));
305   if (ret != EOK)
306     {
307       return -1;
308     }
309 
310   gi = gadget_find_by_name(cdev, &desc.gadget_name);
311   if (gi == NULL)
312     {
313       usb_err("%s: can't find the gadget\n", __FUNCTION__);
314       goto err;
315     }
316 
317   cfg_name = fconfig_get_string(&gi->obj, &desc.config_name);
318   if (cfg_name == NULL)
319     {
320       usb_err("%s: get config name failed\n", __FUNCTION__);
321       goto err;
322     }
323 
324   obj = usbobj_find(&gi->obj, usbobj_default_match, cfg_name);
325    if (obj)
326     {
327       usb_err("%s: the config %s has been existed\n",
328               __FUNCTION__, cfg_name);
329       goto err;
330     }
331 
332   cfg_desc = (struct usb_config_descriptor *)usbm_malloc(&gi->obj, sizeof(*cfg_desc));
333   if (cfg_desc == NULL)
334     {
335       usb_err("%s: malloc config descriptor failed\n", __FUNCTION__);
336       goto err;
337     }
338 
339   ret = memcpy_s(cfg_desc, sizeof(*cfg_desc), &desc.cfg_desc, sizeof(*cfg_desc));
340   if (ret != EOK)
341     {
342       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
343       goto err;
344     }
345   cfg_desc->bLength = USB_CONFIG_DESC_SIZE;
346   cfg_desc->bDescriptorType = UDESC_CONFIG;
347   cfg = fconfig_alloc_gadget_cfg(gi, cfg_name, cfg_desc);
348   if (cfg == NULL)
349     {
350       usb_err("%s: alloc usb cfg failed\n", __FUNCTION__);
351       goto err;
352     }
353   usbobj_add(&cfg->obj, &gi->obj);
354   return 0;
355 
356 err:
357   usbm_free(&gi->obj, cfg_desc);
358   usbm_free(&gi->obj, cfg_name);
359   return -1;
360 }
361 
fconfig_remove_gadget_cfg(struct fconfig_softc * cdev,void * user_data)362 static int fconfig_remove_gadget_cfg(struct fconfig_softc *cdev, void *user_data)
363 {
364   struct fconfig_cfg_desc desc;
365   struct gadget_info *gi = NULL;
366   struct gadget_config *cfg = NULL;
367   struct usb_obj *obj = NULL;
368   char *config_name = NULL;
369   int ret;
370 
371   ret = memcpy_s(&desc, sizeof(desc), (void *)user_data, sizeof(desc));
372   if (ret != EOK)
373     {
374       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
375       return -1;
376     }
377 
378   gi = gadget_find_by_name(cdev, &desc.gadget_name);
379   if (gi == NULL)
380     {
381       usb_err("%s: can't find the gadget\n", __FUNCTION__);
382       goto err;
383     }
384 
385   config_name = fconfig_get_string(&gi->obj, &desc.config_name);
386   if (config_name == NULL)
387     {
388       usb_err("%s: get config name failed\n", __FUNCTION__);
389       goto err;
390     }
391 
392   obj = usbobj_find(&gi->obj, usbobj_default_match, config_name);
393   if (!obj)
394     {
395       usb_err("%s: can't find the config %s\n", __FUNCTION__, config_name);
396       goto err;
397     }
398   cfg = container_of(obj, struct gadget_config, obj);
399   usbobj_put(&cfg->obj);
400 
401   usbm_free(&gi->obj, cfg->name);
402   usbm_free(&gi->obj, cfg->cfg_desc);
403   return 0;
404 
405 err:
406   usbm_free(&gi->obj, config_name);
407   return -1;
408 }
409 
fconfig_fill_strings(struct gadget_info * gi,struct fconfig_dev_strings * str_data)410 static int fconfig_fill_strings(struct gadget_info *gi,
411                                 struct fconfig_dev_strings *str_data)
412 {
413   struct fconfig_usb_string *strings = NULL;
414   struct gadget_strings *dev_strings = NULL;
415   uint32_t size;
416   int i;
417   int ret;
418 
419   size = sizeof(*dev_strings);
420   dev_strings = (struct gadget_strings *)usbm_malloc(&gi->obj, size);
421   if (dev_strings == NULL)
422     {
423       usb_err("%s: malloc strings failed\n", __FUNCTION__);
424       return -1;
425     }
426   memset_s(dev_strings, size, 0, size);
427   size = sizeof(struct usbd_string) * (str_data->str_count + 1);
428   dev_strings->strings = usbm_malloc(&gi->obj, size);
429   if (dev_strings == NULL)
430     {
431       usb_err("%s: malloc strings failed\n", __FUNCTION__);
432       return -1;
433     }
434 
435   usbobj_init(&dev_strings->obj, "dev_strings", usbobj_default_release);
436   size = sizeof(*strings) * str_data->str_count;
437   strings = (struct fconfig_usb_string *)usbm_malloc(&dev_strings->obj, size);
438   if (strings == NULL)
439     {
440       usb_err("%s: malloc config usb strings failed\n", __FUNCTION__);
441       goto err;
442     }
443   ret = memcpy_s(strings, size, (void *)str_data->strings, size);
444   if (ret != EOK)
445     {
446       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
447       goto err;
448     }
449   for (i = 0; i < str_data->str_count; i++)
450     {
451       char *str = fconfig_get_string(&dev_strings->obj, &strings[i].str);
452       if (str == NULL)
453         {
454           usb_err("%s: get string failed\n", __FUNCTION__);
455           goto err;
456         }
457       dev_strings->strings[i].id = strings[i].id + 1;
458       dev_strings->strings[i].s  = str;
459     }
460   dev_strings->strings[i].id = 0;
461   dev_strings->strings[i].s  = NULL;
462   dev_strings->language = str_data->language;
463 
464   usbm_free(&dev_strings->obj, strings);
465   usbobj_add(&dev_strings->obj, &gi->strings);
466   return 0;
467 
468 err:
469   usbobj_put(&dev_strings->obj);
470   return -1;
471 }
472 
fconfig_write_strings(struct fconfig_softc * cdev,void * user_data)473 static int fconfig_write_strings(struct fconfig_softc *cdev, void *user_data)
474 {
475   struct gadget_info *gi = NULL;
476   struct fconfig_dev_strings str_data;
477   int ret;
478 
479   ret = memcpy_s(&str_data, sizeof(str_data), (void *)user_data, sizeof(str_data));
480   if (ret != EOK)
481     {
482       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
483       return -1;
484     }
485 
486   gi = gadget_find_by_name(cdev, &str_data.gadget_name);
487   if (gi == NULL)
488     {
489       usb_err("%s: can't find the gadget\n", __FUNCTION__);
490       return -1;
491     }
492 
493   /* set the string count for first time */
494   if (!gi->str_count)
495     {
496       gi->str_count = str_data.str_count + 1;
497     }
498   else if (gi->str_count != (str_data.str_count + 1))
499     {
500       usb_err("%s: str_count %u is not equeal to %u\n",
501               __FUNCTION__, str_data.str_count, gi->str_count);
502       return -1;
503     }
504   return fconfig_fill_strings(gi, &str_data);
505 }
506 
function_instance_release(struct usb_obj * obj)507 void function_instance_release(struct usb_obj *obj)
508 {
509   int ret;
510   struct function_instance *func_inst = container_of(obj, struct function_instance, obj);
511 
512   if (func_inst->minor >= DEV_GENERIC)
513     {
514       ret = usbdev_generic_free_instance(func_inst->name);
515       if (ret != 0)
516         {
517           usb_err("%s: free generic_func_inst %s failed\n", __func__, func_inst->name);
518         }
519     }
520   usbm_free(obj->parent, func_inst);
521 }
522 
fconfig_do_make_function(struct gadget_config * cfg,char * func_name)523 static int fconfig_do_make_function(struct gadget_config *cfg, char *func_name)
524 {
525   struct function_instance *func_inst = NULL;
526   struct usbdev_info *dev_info = NULL;
527   char *instance_name = NULL;
528   char *obj_name = NULL;
529 
530   /* split the whole name into function name and instance name */
531   instance_name = strchr(func_name, '.');
532   if (instance_name == NULL)
533     {
534       usb_err("%s: unable to locate . in %s\n", __FUNCTION__, func_name);
535       return -1;
536     }
537   *instance_name = '\0';
538   instance_name++;
539 
540   func_inst = usbm_malloc(&cfg->obj, sizeof(*func_inst));
541   if (func_inst == NULL)
542     {
543       usb_err("%s: malloc function instance failed\n", __FUNCTION__);
544       return -1;
545     }
546   memset_s(func_inst, sizeof(*func_inst), 0, sizeof(*func_inst));
547   usbobj_init(&func_inst->obj, "", function_instance_release);
548 
549   dev_info = fconfig_find_usbdev_info(func_name);
550   if (dev_info == NULL)
551     {
552       usb_err("%s: can not find dev_info\n", __FUNCTION__);
553       goto err;
554     }
555   obj_name = usbm_strdup(&func_inst->obj, instance_name);
556   func_inst->dev_info = dev_info;
557   func_inst->name     = obj_name;
558   func_inst->obj.name     = obj_name;
559   usbobj_add(&func_inst->obj, &cfg->obj);
560   dprintf("%s, func_inst->obj->name = %s\n", __func__, func_inst->obj.name);
561   if (dev_info->type != DEV_GENERIC)
562     {
563       /*for normal kernel driver */
564       func_inst->minor = dev_info->type;
565     }
566   else
567     {
568       /* for generic device */
569       int ret = usbdev_generic_alloc_instance(func_inst->name);
570       if (ret < DEV_GENERIC)
571         {
572           goto err;
573         }
574       func_inst->minor = ret;
575     }
576 
577   return 0;
578 
579 err:
580   usbobj_put(&func_inst->obj);
581   return -1;
582 }
583 
fconfig_do_drop_function(struct gadget_config * cfg,char * func_name)584 static int fconfig_do_drop_function(struct gadget_config *cfg, char *func_name)
585 {
586   struct usb_obj *obj = NULL;
587   char *instance_name = NULL;
588 
589   /* split the whole name into function name and instance name */
590   instance_name = strchr(func_name, '.');
591   if (instance_name == NULL)
592     {
593       usb_err("unable to locate . in %s\n", func_name);
594       return -1;
595     }
596   *instance_name = '\0';
597   instance_name++;
598 
599   obj = usbobj_find(&cfg->obj, usbobj_default_match, instance_name);
600   if (!obj)
601     {
602       dprintf("%s, usbobj_find %s obj failed\n", __func__, instance_name);
603       return -1;
604     }
605 
606   usbobj_put(obj);
607   return 0;
608 }
609 
fconfig_get_function_info(struct fconfig_softc * cdev,void * user_data,char ** name,struct gadget_config ** usb_cfg)610 static int fconfig_get_function_info(struct fconfig_softc *cdev, void *user_data,
611                                      char **name, struct gadget_config **usb_cfg)
612 {
613   struct fconfig_func_info func_info;
614   struct gadget_config *cfg = NULL;
615   struct gadget_info *gi = NULL;
616   struct usb_obj *obj = NULL;
617   char *config_name = NULL;
618   char *func_name   = NULL;
619   int ret;
620 
621   ret = memcpy_s(&func_info, sizeof(func_info), (void *)user_data, sizeof(func_info));
622   if (ret != EOK)
623     {
624       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
625       return -1;
626     }
627 
628   gi = gadget_find_by_name(cdev, &func_info.gadget_name);
629   if (gi == NULL)
630     {
631       usb_err("%s: can't find the gadget\n", __FUNCTION__);
632       goto err;
633     }
634 
635   config_name = fconfig_get_string(&gi->obj, &func_info.config_name);
636   if (config_name == NULL)
637     {
638       usb_err("%s: get config name failed\n", __FUNCTION__);
639       goto err;
640     }
641 
642   /* find config from gadget object by the name */
643   obj = usbobj_find(&gi->obj, usbobj_default_match, config_name);
644   if (!obj)
645     {
646       usb_err("%s: can't find the config %s\n", __FUNCTION__, config_name);
647       goto err;
648     }
649   cfg = container_of(obj, struct gadget_config, obj);
650 
651   func_name = fconfig_get_string(obj, &func_info.func_name);
652   if (func_name == NULL)
653     {
654       usb_err("%s: get func name failed\n", __FUNCTION__);
655       goto err2;
656     }
657 
658   *name    = func_name;
659   *usb_cfg = cfg;
660   usbm_free(&gi->obj, config_name);
661   return 0;
662 
663 err2:
664   usbm_free(&cfg->obj, func_name);
665 err:
666   usbm_free(&gi->obj, config_name);
667   return -1;
668 }
669 
fconfig_make_function(struct fconfig_softc * cdev,void * user_data)670 static int fconfig_make_function(struct fconfig_softc *cdev, void *user_data)
671 {
672   struct gadget_config *cfg = NULL;
673   char *func_name = NULL;
674   int ret;
675 
676   ret = fconfig_get_function_info(cdev, user_data, &func_name, &cfg);
677   if (ret != 0)
678     {
679       usb_err("%s: get function info failed\n", __FUNCTION__);
680       return -1;
681     }
682 
683   ret = fconfig_do_make_function(cfg, func_name);
684   if (ret != 0)
685     {
686       usb_err("%s: make function failed\n", __FUNCTION__);
687     }
688   usbm_free(&cfg->obj, func_name);
689 
690   return ret;
691 }
692 
fconfig_drop_function(struct fconfig_softc * cdev,void * user_data)693 static int fconfig_drop_function(struct fconfig_softc *cdev, void *user_data)
694 {
695   struct gadget_config *cfg = NULL;
696   char *func_name = NULL;
697   int ret;
698 
699   ret = fconfig_get_function_info(cdev, user_data, &func_name, &cfg);
700   if (ret != 0)
701     {
702       usb_err("%s: get function info failed\n", __FUNCTION__);
703       return -1;
704     }
705 
706   ret = fconfig_do_drop_function(cfg, func_name);
707   if (ret != 0)
708     {
709       usb_err("%s: make function failed\n", __FUNCTION__);
710     }
711 
712   usbm_free(&cfg->obj, func_name);
713   return ret;
714 }
715 
usb_config_match(struct usb_obj * obj,void * match_data)716 static int usb_config_match(struct usb_obj *obj, void *match_data)
717 {
718   struct gadget_config *cfg = container_of(obj, struct gadget_config, obj);
719   uint8_t config_num = *(uint8_t *)match_data;
720 
721   return (cfg->cfg_num == config_num);
722 }
723 
func_inst_init(struct usb_obj * obj,void * data)724 static void func_inst_init(struct usb_obj *obj, void *data)
725 {
726   struct function_instance *func = container_of(obj, struct function_instance, obj);
727   struct func_info * info = (struct func_info *)data;
728   struct usbdev_info *dev_info = NULL;
729 
730   if (func == NULL || func->dev_info == NULL)
731     {
732       usb_err("%s: get function_instance failed\n", __FUNCTION__);
733       return;
734     }
735   dev_info = func->dev_info;
736 
737   if (dev_info->type == DEV_GENERIC)
738     {
739       dev_info->initialize_sub(&info->devs[info->ndevices], info->ifnobase, func->minor);
740       info->devs[info->ndevices].devinfo.strbase = info->strbase;
741       info->ifnobase += info->devs[info->ndevices].devinfo.ninterfaces;
742       info->strbase += info->devs[info->ndevices].devinfo.nstrings;
743     }
744   else
745     {
746       dev_info->initialize_sub(&info->devs[info->ndevices], info->ifnobase, dev_info->type);
747       info->ifnobase += dev_info->ifnum;
748     }
749   info->ndevices++;
750 }
751 
fconfig_composite_initialize(struct gadget_info * gi,struct composite_softc * com_s)752 static int fconfig_composite_initialize(struct gadget_info *gi,
753                                         struct composite_softc *com_s)
754 {
755   struct composite_devdesc_s devs[NUM_DEVICES_TO_HANDLE];
756   struct func_info info;
757   uint8_t config_num = 1;
758   struct usb_obj *obj = NULL;
759   struct gadget_config *cfg = NULL;
760 
761   if (com_s)
762     {
763       config_num = com_s->dev.config;
764     }
765   info.devs = devs;
766   info.ndevices = 0;
767   info.ifnobase = 0;
768   info.strbase = 0;
769   config_num = 1;
770   obj = usbobj_find(&gi->obj, usb_config_match, &config_num);
771   if (!obj)
772     {
773       usb_err("%s: can't find the configNumber %d\n", __FUNCTION__, config_num);
774       return -1;
775     }
776   cfg = container_of(obj, struct gadget_config, obj);
777   usbobj_for_each_child(&cfg->obj, NULL, NULL, func_inst_init, &info);
778 
779   return fconfig_do_composite_initialize(com_s, info.ndevices, devs);
780 }
781 
fconfig_enable_udc(struct fconfig_softc * cdev,void * user_data)782 static int fconfig_enable_udc(struct fconfig_softc *cdev, void *user_data)
783 {
784   struct composite_softc *com_s = cdev->com_s;
785   struct fconfig_udc_info udc_info;
786   struct gadget_info *gi = NULL;
787   char *udc_name = NULL;
788   int ret;
789 
790   ret = memcpy_s(&udc_info, sizeof(udc_info), (void *)user_data, sizeof(udc_info));
791   if (ret != EOK)
792     {
793       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
794       return -1;
795     }
796 
797   gi = gadget_find_by_name(cdev, &udc_info.gadget_name);
798   if (gi == NULL)
799     {
800       usb_err("%s: can't find the gadget\n", __FUNCTION__);
801       goto err;
802     }
803 
804   udc_name = fconfig_get_string(&gi->obj, &udc_info.udc_name);
805   if (udc_name == NULL)
806     {
807       usb_err("%s: get udc name failed\n", __FUNCTION__);
808       goto err;
809     }
810 
811   gi->udc_name = udc_name;
812   ret = fconfig_composite_initialize(gi, com_s);
813   if (ret)
814     {
815       usb_err("%s: fcofnig composite init failed\n", __FUNCTION__);
816       goto err;
817     }
818   usbd_start_udc();
819   ret = usbd_gadget_attach_driver(com_s->parnet_conext, &com_s->drvr.drvr);
820   if (ret < 0)
821     {
822       usb_err("%s, usbd_gadget_attach_driver fail\n", __func__);
823       goto err;
824     }
825 
826   return 0;
827 
828 err:
829   usbm_free(&gi->obj, udc_name);
830   return -1;
831 }
832 
fconfig_disable_udc(struct fconfig_softc * cdev,void * user_data)833 static int fconfig_disable_udc(struct fconfig_softc *cdev, void *user_data)
834 {
835   struct gadget_info *gi = NULL;
836   struct fconfig_udc_info udc_info;
837   int ret;
838 
839   ret = memcpy_s(&udc_info, sizeof(udc_info), (void *)user_data, sizeof(udc_info));
840   if (ret != EOK)
841     {
842       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
843       return -1;
844     }
845 
846   gi = gadget_find_by_name(cdev, &udc_info.gadget_name);
847   if (gi == NULL)
848     {
849       usb_err("%s: can't find the gadget\n", __FUNCTION__);
850       goto err;
851     }
852 
853   /* disable UDC */
854   usbd_stop_udc();
855   usbm_free(&gi->obj, gi->udc_name);
856   gi->udc_name = NULL;
857   return 0;
858 
859 err:
860   return -1;
861 }
862 
change_dev_descritor_info(struct gadget_info * gi,struct fconfig_dev_desc_info * desc_info)863 static int change_dev_descritor_info(struct gadget_info *gi,
864                                      struct fconfig_dev_desc_info *desc_info)
865 {
866   const char *name = NULL;
867 
868   if (desc_info == NULL || gi == NULL)
869     {
870       usb_err("%s: param invail\n", __FUNCTION__);
871       return -1;
872     }
873   name = desc_info->prop.prop_name;
874   if (strcmp(USBDEV_VENDOR, name) == 0)
875     {
876       gi->dev_desc->idVendor[0] = (uint8_t)desc_info->prop.prop_value;
877       gi->dev_desc->idVendor[1] = (uint8_t)(desc_info->prop.prop_value >> 8);
878     }
879   else if (strcmp(USBDEV_IDPRODUCT, name) == 0)
880     {
881       gi->dev_desc->idProduct[0] = (uint8_t)desc_info->prop.prop_value;
882       gi->dev_desc->idProduct[1] = (uint8_t)(desc_info->prop.prop_value >> 8);
883     }
884   else if (strcmp(USBDEV_CLASS, name) == 0)
885     {
886       gi->dev_desc->bDeviceClass = (uint8_t)desc_info->prop.prop_value;
887     }
888   else if (strcmp(USBDEV_SUBCLASS, name) == 0)
889     {
890       gi->dev_desc->bDeviceSubClass = (uint8_t)desc_info->prop.prop_value;
891     }
892   else if (strcmp(USBDEV_PROTOCOL, name) == 0)
893     {
894       gi->dev_desc->bDeviceProtocol = (uint8_t)desc_info->prop.prop_value;
895     }
896   else if (strcmp(USBDEV_MAXSIZE, name) == 0)
897     {
898       gi->dev_desc->bMaxPacketSize = (uint8_t)desc_info->prop.prop_value;
899     }
900   else if (strcmp(USBDEV_NUMCFG, name) == 0)
901     {
902       gi->dev_desc->bNumConfigurations = (uint8_t)desc_info->prop.prop_value;
903     }
904   else if (strcmp(USBDEV_BCD, name) == 0)
905     {
906       gi->dev_desc->bcdUSB[0] = (uint8_t)desc_info->prop.prop_value;
907       gi->dev_desc->bcdUSB[1] = (uint8_t)(desc_info->prop.prop_value >> 8);
908     }
909   else if (strcmp(USBDEV_BCDDEVICE, name) == 0)
910     {
911       gi->dev_desc->bcdDevice[0] = (uint8_t)desc_info->prop.prop_value;
912       gi->dev_desc->bcdDevice[1] = (uint8_t)(desc_info->prop.prop_value >> 8);
913     }
914   else
915     {
916       usb_err("%{public}s: other prop", __func__);
917       return -1;
918     }
919   return 0;
920 }
921 
fconfig_change_dev_desc_info(struct fconfig_softc * cdev,void * user_data)922 static int fconfig_change_dev_desc_info(struct fconfig_softc *cdev, void *user_data)
923 {
924   struct gadget_info *gi = NULL;
925   struct fconfig_dev_desc_info desc_info;
926   int ret;
927 
928   ret = memcpy_s(&desc_info, sizeof(desc_info), (void *)user_data, sizeof(desc_info));
929   if (ret != EOK)
930     {
931       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
932       return -1;
933     }
934 
935   gi = gadget_find_by_name(cdev, &desc_info.gadget_name);
936   if (gi == NULL)
937     {
938       usb_err("%s: can't find the gadget\n", __FUNCTION__);
939       return -1;
940     }
941   if (gi->dev_desc == NULL)
942     {
943       usb_err("%s: dev_desc is null\n", __FUNCTION__);
944       return -1;
945     }
946   ret = change_dev_descritor_info(gi, &desc_info);
947   if (ret != EOK)
948     {
949       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
950       return -1;
951     }
952   return 0;
953 }
954 
change_dev_descritor_string(struct gadget_info * gi,struct fconfig_dev_desc_string * desc_string,struct gadget_strings * dev_strings)955 static int change_dev_descritor_string(struct gadget_info *gi,
956                                        struct fconfig_dev_desc_string *desc_string,
957                                        struct gadget_strings *dev_strings)
958 {
959   uint8_t id = 0xff;
960   int i;
961   const char *name = NULL;
962 
963   if (desc_string == NULL || gi == NULL || dev_strings == NULL)
964     {
965       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
966       return -1;
967     }
968   for (i = 0; dev_strings->strings[i].s != NULL; i++)
969     {
970       const char *str = dev_strings->strings[i].s;
971       if (strcmp(str, desc_string->prop.prop_value) == 0)
972         {
973           id = dev_strings->strings[i].id;
974           break;
975         }
976     }
977   if (id == 0xff)
978     {
979       usb_err("%s: not found ringht string ID\n", __FUNCTION__);
980       return -1;
981     }
982   name = desc_string->prop.prop_name;
983   if (strcmp(USBDEV_MANUFACTURER, name) == 0)
984     {
985       gi->dev_desc->iManufacturer = id;
986     }
987   else if (strcmp(USBDEV_PRODUCT, name) == 0)
988     {
989       gi->dev_desc->iProduct = id;
990     }
991   else if (strcmp(USBDEV_SERIALNUM, name) == 0)
992     {
993       gi->dev_desc->iSerialNumber = id;
994     }
995   else
996     {
997       usb_err("%{public}s: other prop", __func__);
998       return -1;
999     }
1000   return 0;
1001 }
1002 
fconfig_change_dev_desc_string(struct fconfig_softc * cdev,void * user_data)1003 static int fconfig_change_dev_desc_string(struct fconfig_softc *cdev, void *user_data)
1004 {
1005   struct usb_obj *obj = NULL;
1006   struct gadget_info *gi = NULL;
1007   struct fconfig_dev_desc_string desc_string;
1008   struct gadget_strings *dev_strings = NULL;
1009   int ret;
1010 
1011   ret = memcpy_s(&desc_string, sizeof(desc_string), (void *)user_data, sizeof(desc_string));
1012   if (ret != EOK)
1013     {
1014       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
1015       return -1;
1016     }
1017 
1018   gi = gadget_find_by_name(cdev, &desc_string.gadget_name);
1019   if (gi == NULL)
1020     {
1021       usb_err("%s: can't find the gadget\n", __FUNCTION__);
1022       return -1;
1023     }
1024   if (gi->dev_desc == NULL)
1025     {
1026       usb_err("%s: dev_desc is null\n", __FUNCTION__);
1027       return -1;
1028     }
1029 
1030   obj = usbobj_find(&gi->strings, gadget_strings_match, &desc_string.prop.lang);
1031   if (!obj)
1032     {
1033       usb_err("%s: can not find language = 0x%x strings\n", __func__, desc_string.prop.lang);
1034       return -1;
1035     }
1036   dev_strings = container_of(obj, struct gadget_strings, obj);
1037 
1038   ret = change_dev_descritor_string(gi, &desc_string, dev_strings);
1039   if (ret != EOK)
1040     {
1041       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
1042       return -1;
1043     }
1044   return 0;
1045 }
1046 
fconfig_handle_open(struct usb_handle * handle)1047 int fconfig_handle_open(struct usb_handle *handle)
1048 {
1049   struct fconfig_softc *cdev = (struct fconfig_softc *)(handle->priv);
1050 
1051 
1052   if (cdev == NULL)
1053     {
1054       usb_err("Invalid private parameter!\n");
1055       return -1;
1056     }
1057 
1058   usbobj_get(&cdev->obj);
1059   return 0;
1060 }
1061 
fconfig_handle_close(struct usb_handle * handle)1062 int fconfig_handle_close(struct usb_handle *handle)
1063 {
1064   struct fconfig_softc *cdev = (struct fconfig_softc *)(handle->priv);
1065 
1066   if (cdev == NULL)
1067     {
1068       usb_err("Invalid private parameter!\n");
1069       return -1;
1070     }
1071 
1072   usbobj_put(&cdev->obj);
1073   return 0;
1074 }
1075 
fconfig_handle_read(struct usb_handle * handle,void * buffer,size_t len)1076 int fconfig_handle_read(struct usb_handle *handle, void *buffer, size_t len)
1077 {
1078   struct fconfig_softc *cdev = (struct fconfig_softc *)(handle->priv);
1079 
1080   if (len == 0)
1081     {
1082       usb_err("buflen is 0!\n");
1083       return -1;
1084     }
1085 
1086   if (cdev == NULL)
1087     {
1088       usb_err("Invalid private parameter!\n");
1089       return -1;
1090     }
1091 
1092   return 0;
1093 }
1094 
fconfig_handle_write(struct usb_handle * handle,void * buffer,size_t len)1095 int fconfig_handle_write(struct usb_handle *handle, void *buffer, size_t len)
1096 {
1097   struct fconfig_softc *cdev = (struct fconfig_softc *)(handle->priv);
1098 
1099   if (len == 0)
1100     {
1101       usb_err("buflen is 0!\n");
1102       return -1;
1103     }
1104 
1105   if (cdev == NULL)
1106     {
1107       usb_err("Invalid private parameter!\n");
1108       return -1;
1109     }
1110 
1111   return 0;
1112 }
1113 
fconfig_handle_ioctl(struct usb_handle * handle,int cmd,void * arg)1114 int fconfig_handle_ioctl(struct usb_handle *handle, int cmd, void *arg)
1115 {
1116   struct fconfig_softc *cdev = (struct fconfig_softc *)(handle->priv);
1117   void *argp = (void *)arg;
1118   int ret = -1;
1119 
1120   if (cdev == NULL || argp == NULL)
1121     {
1122       usb_err("Invalid private parameter!\n");
1123       return -ENODEV;
1124     }
1125 
1126   switch (cmd)
1127     {
1128     case FCONFIG_CMD_MAKE_GADGET:
1129 	  ret = fconfig_make_gadget(cdev, argp);
1130 	  break;
1131 
1132     case FCONFIG_CMD_DROP_GADGET:
1133       ret = fconfig_drop_gadget(cdev, argp);
1134       break;
1135 
1136     case FCONFIG_CMD_WRITE_DEV_DESC:
1137       ret = fconfig_write_dev_desc(cdev, argp);
1138       break;
1139 
1140     case FCONFIG_CMD_ADD_CONFIG:
1141       ret = fconfig_add_gadget_cfg(cdev, argp);
1142       break;
1143 
1144     case FCONFIG_CMD_REMOVE_CONFIG:
1145       ret = fconfig_remove_gadget_cfg(cdev, argp);
1146       break;
1147 
1148     case FCONFIG_CMD_WRITE_STRINGS:
1149       ret = fconfig_write_strings(cdev, argp);
1150       break;
1151 
1152     case FCONFIG_CMD_MAKE_FUNCTION:
1153       ret = fconfig_make_function(cdev, argp);
1154       break;
1155 
1156     case FCONFIG_CMD_DROP_FUNCTION:
1157       ret = fconfig_drop_function(cdev, argp);
1158       break;
1159 
1160     case FCONFIG_CMD_ENABLE_UDC:
1161       ret = fconfig_enable_udc(cdev, argp);
1162       break;
1163 
1164     case FCONFIG_CMD_DISABLE_UDC:
1165       ret = fconfig_disable_udc(cdev, argp);
1166       break;
1167     case FCONFIG_CMD_CHAGE_DEVINFO:
1168       ret = fconfig_change_dev_desc_info(cdev, argp);
1169       break;
1170     case FCONFIG_CMD_CHAGE_DEVSTRING:
1171       ret = fconfig_change_dev_desc_string(cdev, argp);
1172       break;
1173     default:
1174       usb_err("the ioctl %d is not supported\n", cmd);
1175       break;
1176     }
1177 
1178   return ret;
1179 }
1180 
1181 static struct UsbHandleOps g_fconfig_handle_fops =
1182 {
1183   .open   = fconfig_handle_open,
1184   .close  = fconfig_handle_close,
1185   .read   = fconfig_handle_read,
1186   .write  = fconfig_handle_write,
1187   .ioctl  = fconfig_handle_ioctl,
1188 };
1189 
fconfig_fops_init(struct fconfig_softc * cdev)1190 int fconfig_fops_init(struct fconfig_softc *cdev)
1191 {
1192   int ret;
1193   char *devName = NULL;
1194 
1195   if (cdev == NULL)
1196     {
1197       usb_err("%s: cdev is NULL\n", __FUNCTION__);
1198       return -1;
1199     }
1200 
1201   devName = usbm_malloc(&cdev->obj, strlen(USB_FCONFIG_DEV) + 1);
1202   if (!devName)
1203     {
1204       return -1;
1205     }
1206   ret = snprintf_s(devName, strlen(USB_FCONFIG_DEV) + 1, strlen(USB_FCONFIG_DEV),
1207                    "%s", USB_FCONFIG_DEV);
1208     if (ret < 0)
1209       {
1210         goto free_devname;
1211       }
1212   ret = register_handle(devName, &g_fconfig_handle_fops, cdev, &cdev->obj);
1213   if (ret != OK)
1214     {
1215       usb_err("%s: fconfig device register failed!\n", __FUNCTION__);
1216       goto free_devname;
1217     }
1218 
1219   return 0;
1220 
1221 free_devname:
1222   usbm_free(&cdev->obj, devName);
1223   return ret;
1224 }
1225 
fconfig_fops_deinit(const struct fconfig_softc * cdev)1226 int fconfig_fops_deinit(const struct fconfig_softc *cdev)
1227 {
1228   int ret;
1229 
1230   if (cdev == NULL)
1231     {
1232       usb_err("%s: cdev is NULL\n", __FUNCTION__);
1233       return -1;
1234     }
1235   ret = unregister_handle(USB_FCONFIG_DEV);
1236   if (ret != OK)
1237     {
1238       usb_err("%s: fconfig device unregister failed!\n", __FUNCTION__);
1239     }
1240 
1241   return ret;
1242 }
1243 
1244 #ifdef __cplusplus
1245 #if __cplusplus
1246 //}
1247 #endif /* __cplusplus */
1248 #endif /* __cplusplus */
1249