• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  * drivers/usbdev/composite_desc.c
3  *
4  *   Copyright (C) 2011-2012, 2017 Gregory Nutt. All rights reserved.
5  *   Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved.
6  *   Author: Gregory Nutt <gnutt@nuttx.org>
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  * 3. Neither the name NuttX nor the names of its contributors may be
19  *    used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
29  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  ****************************************************************************/
36 /****************************************************************************
37  * Notice of Export Control Law
38  * ===============================================
39  * Huawei LiteOS may be subject to applicable export control laws and regulations,
40  * which might include those applicable to Huawei LiteOS of U.S. and the country in
41  * which you are located.
42  * Import, export and usage of Huawei LiteOS in any manner by you shall be in
43  * compliance with such applicable export control laws and regulations.
44  ****************************************************************************/
45 
46 /****************************************************************************
47  * Included Files
48  ****************************************************************************/
49 
50 #include "gadget/composite.h"
51 
52 #ifdef CONFIG_USBDEV_COMPOSITE
53 
54 #define OS_STRING_SIGN_LEN 18
55 #define OS_STRING_ID       0xEE
56 
57 static const char g_os_string[OS_STRING_SIGN_LEN] =
58 {
59   OS_STRING_SIGN_LEN,
60   UDESC_STRING,
61   'L', 0, 'i', 0, 't', 0, 'e', 0,
62   'O', 0, 'S', 0, ' ', 0, 0, 0
63 };
64 
65 /****************************************************************************
66  * Public Functions
67  ****************************************************************************/
68 
69 /****************************************************************************
70  * Name: composite_mkstrdesc
71  *
72  * Description:
73  *   Construct a string descriptor
74  *
75  ****************************************************************************/
76 
composite_mkstrdesc(struct composite_dev_s * priv,uint8_t id,uint16_t index,uint8_t * buf)77 int composite_mkstrdesc(struct composite_dev_s *priv, uint8_t id, uint16_t index, uint8_t *buf)
78 {
79   int len = -1;
80   int i;
81   int ret;
82 
83   if (index == 0 && id == OS_STRING_ID)
84     {
85       ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, (void *)g_os_string, g_os_string[0]);
86       if (ret != EOK)
87         {
88           return -1;
89         }
90       return g_os_string[0];
91     }
92 
93   for (i = 0; i < priv->ndevices; i++)
94     {
95       len = priv->device[i].compdesc.mkstrdesc(id, buf);
96     }
97 
98   return len;
99 }
100 
composite_mkdevdesc(struct composite_dev_s * priv,uint8_t * buf)101 void composite_mkdevdesc(struct composite_dev_s *priv, uint8_t *buf)
102 {
103   int i;
104 
105   for (i = 0; i < priv->ndevices; i++)
106     {
107       priv->device[i].compdesc.mkdevdesc(buf);
108     }
109 }
110 
composite_mkcfgdesc_sub(uint8_t * buf,int16_t len)111 int16_t composite_mkcfgdesc_sub(uint8_t *buf, int16_t len)
112 {
113   uint8_t *buf_tmp;
114   struct usb_descriptor *desc;
115   int16_t new_config_len = 0;
116   int ret;
117   int i;
118 
119   buf_tmp = (uint8_t *)malloc(len);
120   if (buf_tmp == NULL)
121     {
122       return -1;
123     }
124 
125   ret = memcpy_s(buf_tmp, len, buf, USB_CONFIG_DESC_SIZE);
126   if (ret != EOK)
127     {
128       goto err;
129     }
130   len -= USB_CONFIG_DESC_SIZE;
131   new_config_len += USB_CONFIG_DESC_SIZE;
132 
133   desc = (struct usb_descriptor *)(buf + USB_CONFIG_DESC_SIZE);
134   i = 0;
135   while (i < len)
136     {
137       i += desc->bLength;
138       if (desc->bDescriptorType == UDESC_CONFIG)
139         {
140           desc = (struct usb_descriptor *)((char *)desc + desc->bLength);
141           continue;
142         }
143       ret = memcpy_s(buf_tmp + new_config_len, (len + USB_CONFIG_DESC_SIZE - new_config_len),
144                      desc, desc->bLength);
145       if (ret != EOK)
146         {
147           goto err;
148         }
149       new_config_len += desc->bLength;
150       desc = (struct usb_descriptor *)((char *)desc + desc->bLength);
151     }
152 
153   ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, buf_tmp, new_config_len);
154   if (ret != EOK)
155     {
156       goto err;
157     }
158   free(buf_tmp);
159 
160   return new_config_len;
161 
162 err:
163   free(buf_tmp);
164   return -1;
165 }
166 
167 /****************************************************************************
168  * Name: composite_mkcfgdesc
169  *
170  * Description:
171  *   Construct the configuration descriptor
172  *
173  ****************************************************************************/
174 
composite_mkcfgdesc(struct composite_dev_s * priv,uint8_t * buf)175 int16_t composite_mkcfgdesc(struct composite_dev_s *priv, uint8_t *buf)
176 {
177   struct usb_config_descriptor *config_desc;
178   uint8_t *buf_tmp = buf;
179   int16_t len;
180   int16_t total = 0;
181   int16_t config_len;
182   int i;
183 
184   /* Copy all contained interface descriptors into the buffer too */
185 
186   for (i = 0; i < priv->ndevices; i++)
187     {
188       len = priv->device[i].compdesc.mkconfdesc(buf_tmp, &priv->device[i].compdesc.devinfo);
189       if (len <= 0)
190         {
191           return -1;
192         }
193       total   += len;
194       buf_tmp += len;
195     }
196 
197   if (priv->ndevices > 1)
198     {
199       config_len = total;
200       total      = composite_mkcfgdesc_sub(buf, config_len);
201       if (total < 0)
202         {
203           return -1;
204         }
205 
206       config_len  = total;
207       config_desc = (struct usb_config_descriptor *)buf;
208       USETW(config_desc->wTotalLength, config_len);
209       config_desc->bNumInterface = priv->ninterfaces;
210     }
211 
212   return total;
213 }
214 
215 #endif /* CONFIG_USBDEV_COMPOSITE */
216