1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "usb_protocol.h"
17 #include "usb_io_manage.h"
18 #include "usbd_wrapper.h"
19 
20 #define HDF_LOG_TAG USB_PROTOCOL
21 
UsbProtocalFillControlSetup(const unsigned char * setup,const struct UsbControlRequest * ctrlReq)22 int32_t UsbProtocalFillControlSetup(const unsigned char *setup, const struct UsbControlRequest *ctrlReq)
23 {
24     struct UsbRawControlSetup *setupData = (struct UsbRawControlSetup *)setup;
25     int32_t ret = HDF_SUCCESS;
26     if ((setup == NULL) || (ctrlReq == NULL)) {
27         HDF_LOGE("%{public}s:%{public}d invalid parameter", __func__, __LINE__);
28         return HDF_ERR_INVALID_PARAM;
29     }
30 
31     setupData->requestType = ctrlReq->reqType;
32     setupData->request     = ctrlReq->request;
33     setupData->value       = CPU_TO_LE16(ctrlReq->value);
34     setupData->index       = CPU_TO_LE16(ctrlReq->index);
35     setupData->length      = CPU_TO_LE16(ctrlReq->length);
36 
37     return ret;
38 }
39 
CreateCtrPipe(const struct UsbInterfacePool * pool)40 static int32_t CreateCtrPipe(const struct UsbInterfacePool *pool)
41 {
42     int32_t ret = 0;
43     struct UsbSdkInterface *interfaceObj = NULL;
44     struct UsbPipe *pipe = NULL;
45 
46     if (pool == NULL) {
47         HDF_LOGE("%{public}s:%{public}d invalid param pool", __func__, __LINE__);
48         return HDF_ERR_INVALID_PARAM;
49     }
50 
51     ret = UsbIfCreatInterfaceObj(pool, &interfaceObj);
52     if (ret != HDF_SUCCESS) {
53         return HDF_ERR_MALLOC_FAIL;
54     }
55     interfaceObj->interface.info.interfaceIndex = USB_CTRL_INTERFACE_ID;
56     interfaceObj->interface.info.pipeNum = 1;
57     interfaceObj->altSettingId = 0;
58     interfaceObj->interface.info.curAltSetting = 0;
59     ret = UsbIfCreatPipeObj(interfaceObj, &pipe);
60     if (ret != HDF_SUCCESS) {
61         return HDF_ERR_IO;
62     }
63 
64     pipe->info.pipeId = 0;
65     pipe->info.pipeAddress = 0;
66     pipe->info.pipeDirection = USB_PIPE_DIRECTION_OUT;
67     pipe->info.pipeType = USB_PIPE_TYPE_CONTROL;
68 
69     return ret;
70 }
71 
UsbInterfaceInit(struct UsbSdkInterface * interfaceObj,const struct UsbRawInterfaceDescriptor * iface,const struct UsbRawInterface * altsettings)72 static int32_t UsbInterfaceInit(struct UsbSdkInterface *interfaceObj,
73     const struct UsbRawInterfaceDescriptor *iface, const struct UsbRawInterface *altsettings)
74 {
75     struct UsbInterfaceInfo *ptr = NULL;
76 
77     if ((interfaceObj == NULL) || (iface == NULL)) {
78         HDF_LOGE("%{public}s: invalid parameter", __func__);
79         return HDF_ERR_INVALID_PARAM;
80     }
81     ptr = &interfaceObj->interface.info;
82     ptr->pipeNum = iface->interfaceDescriptor.bNumEndpoints;
83     ptr->interfaceClass = iface->interfaceDescriptor.bInterfaceClass;
84     ptr->interfaceSubClass = iface->interfaceDescriptor.bInterfaceSubClass;
85     ptr->interfaceProtocol = iface->interfaceDescriptor.bInterfaceProtocol;
86     ptr->interfaceIndex = iface->interfaceDescriptor.bInterfaceNumber;
87     ptr->altSettings = altsettings->numAltsetting;
88     ptr->curAltSetting = USB_DEFAULT_ALTSETTING;
89 
90     interfaceObj->altSettingId = iface->interfaceDescriptor.bAlternateSetting;
91 
92     return HDF_SUCCESS;
93 }
94 
UsbPipeInit(struct UsbPipe * pipe,const struct UsbRawEndpointDescriptor * ep)95 static int32_t UsbPipeInit(struct UsbPipe *pipe, const struct UsbRawEndpointDescriptor *ep)
96 {
97     if ((pipe == NULL) || (ep == NULL)) {
98         HDF_LOGE("%{public}s: invalid parameter", __func__);
99         return HDF_ERR_INVALID_PARAM;
100     }
101 
102     pipe->info.pipeId = ep->endpointDescriptor.bEndpointAddress;
103     pipe->info.maxPacketSize = ep->endpointDescriptor.wMaxPacketSize;
104     pipe->info.interval = ep->endpointDescriptor.bInterval;
105     pipe->info.pipeType =  ep->endpointDescriptor.bmAttributes & USB_DDK_ENDPOINT_XFERTYPE_MASK;
106     pipe->info.pipeAddress = ep->endpointDescriptor.bEndpointAddress & USB_DDK_ENDPOINT_NUMBER_MASK;
107     pipe->info.pipeDirection = ep->endpointDescriptor.bEndpointAddress & USB_DDK_ENDPOINT_DIR_MASK;
108     return HDF_SUCCESS;
109 }
110 
UsbGetInterfaceFromConfig(const struct UsbRawConfigDescriptor * config,uint8_t idx)111 static const struct UsbRawInterface *UsbGetInterfaceFromConfig(
112     const struct UsbRawConfigDescriptor *config, uint8_t idx)
113 {
114     if (config == NULL) {
115         HDF_LOGE("%{public}s: invalid param", __func__);
116         return NULL;
117     }
118     if (config->configDescriptor.bNumInterfaces < idx + 1) {
119         HDF_LOGE("%{public}s: invalid param", __func__);
120         return NULL;
121     }
122 
123     return config->interface[idx];
124 }
125 
126 /* The default AltSetting is 0 */
UsbGetInterfaceDesc(const struct UsbRawInterface * altSetting,uint8_t settingIndex)127 static const struct UsbRawInterfaceDescriptor *UsbGetInterfaceDesc(
128     const struct UsbRawInterface *altSetting, uint8_t settingIndex)
129 {
130     if (altSetting == NULL) {
131         HDF_LOGE("%{public}s:%{public}d invalid param altSetting", __func__, __LINE__);
132         return NULL;
133     }
134 
135     return &altSetting->altsetting[settingIndex];
136 }
137 
UsbGetEpDesc(const struct UsbRawInterfaceDescriptor * ifDes,uint8_t idx)138 static const struct UsbRawEndpointDescriptor *UsbGetEpDesc(
139     const struct UsbRawInterfaceDescriptor *ifDes, uint8_t idx)
140 {
141     if (ifDes == NULL) {
142         HDF_LOGE("%{public}s:%{public}d invalid param ifDes", __func__, __LINE__);
143         return NULL;
144     }
145     if (ifDes->interfaceDescriptor.bNumEndpoints < (idx + 1)) {
146         HDF_LOGE("%{public}s:invalid param numEp:%{public}d+idx:%{public}hhu",
147             __func__, ifDes->interfaceDescriptor.bNumEndpoints, idx);
148         return NULL;
149     }
150 
151     return &ifDes->endPoint[idx];
152 }
153 
UsbProtocalCreatePipeObj(const struct UsbRawInterfaceDescriptor * ifDes,const struct UsbSdkInterface * interfaceObj)154 static int32_t UsbProtocalCreatePipeObj(
155     const struct UsbRawInterfaceDescriptor *ifDes, const struct UsbSdkInterface *interfaceObj)
156 {
157     int32_t ret = HDF_SUCCESS;
158     const struct UsbRawEndpointDescriptor *ep = NULL;
159     struct UsbPipe *pipe = NULL;
160 
161     for (int32_t cnep = 0; cnep < ifDes->interfaceDescriptor.bNumEndpoints; cnep++) {
162         if (ifDes->interfaceDescriptor.bNumEndpoints > USB_MAXENDPOINTS) {
163             HDF_LOGE("%{public}s:%{public}d bNumEndpoints=%{public}d is error",
164                 __func__, __LINE__, ifDes->interfaceDescriptor.bNumEndpoints);
165             ret = HDF_DEV_ERR_NORANGE;
166             break;
167         }
168         ep = UsbGetEpDesc(ifDes, cnep);
169         if (ep == NULL) {
170             ret = HDF_ERR_INVALID_PARAM;
171             break;
172         }
173         ret = UsbIfCreatPipeObj(interfaceObj, &pipe);
174         if (ret != HDF_SUCCESS) {
175             break;
176         }
177         ret = UsbPipeInit(pipe, ep);
178         if (ret != HDF_SUCCESS) {
179             break;
180         }
181     }
182 
183     return ret;
184 }
185 
UsbProtocalCreatInterfaceObj(const struct UsbRawConfigDescriptor * config,const struct UsbInterfacePool * interfacePool)186 static int32_t UsbProtocalCreatInterfaceObj(const struct UsbRawConfigDescriptor *config,
187     const struct UsbInterfacePool *interfacePool)
188 {
189     uint8_t j;
190     int32_t ret = HDF_SUCCESS;
191     const struct UsbRawInterface *itface = NULL;
192     const struct UsbRawInterfaceDescriptor *ifDes = NULL;
193     struct UsbSdkInterface *interfaceObj = NULL;
194 
195     for (int32_t i = 0; i < config->configDescriptor.bNumInterfaces; i++) {
196         itface = UsbGetInterfaceFromConfig(config, i);
197         if (itface == NULL) {
198             ret = HDF_ERR_INVALID_PARAM;
199             goto ERROR;
200         }
201 
202         for (j = 0; j < itface->numAltsetting; j++) {
203             ifDes = UsbGetInterfaceDesc(itface, j);
204             if (ifDes == NULL) {
205                 ret = HDF_ERR_INVALID_PARAM;
206                 goto ERROR;
207             }
208 
209             ret = UsbIfCreatInterfaceObj(interfacePool, &interfaceObj);
210             if (ret != HDF_SUCCESS) {
211                 goto ERROR;
212             }
213 
214             ret = UsbInterfaceInit(interfaceObj, ifDes, itface);
215             if (ret != 0) {
216                 ret = HDF_ERR_IO;
217                 goto ERROR;
218             }
219 
220             ret = UsbProtocalCreatePipeObj(ifDes, interfaceObj);
221             if (ret != HDF_SUCCESS) {
222                 goto ERROR;
223             }
224         }
225     }
226 
227 ERROR:
228     return ret;
229 }
230 
UsbProtocalParseDescriptor(struct UsbDeviceHandle * devHandle,uint8_t busNum,uint8_t devAddr)231 int32_t UsbProtocalParseDescriptor(struct UsbDeviceHandle *devHandle, uint8_t busNum, uint8_t devAddr)
232 {
233     int32_t ret;
234     int32_t activeConfig = -1;
235     struct UsbInterfacePool *interfacePool = NULL;
236     struct UsbRawConfigDescriptor *config = NULL;
237 
238     if ((devHandle == NULL) || (devHandle->dev == NULL) || (devHandle->dev->session == NULL)) {
239         HDF_LOGE("%{public}s:%{public}d invalid param", __func__, __LINE__);
240         return HDF_ERR_INVALID_PARAM;
241     }
242 
243     ret = UsbIfCreatInterfacePool(devHandle->dev->session, busNum, devAddr, &interfacePool);
244     if (ret != HDF_SUCCESS) {
245         HDF_LOGE("%{public}s:%{public}d UsbIfCreatInterfacePool error", __func__, __LINE__);
246         return HDF_ERR_IO;
247     }
248     interfacePool->session = devHandle->dev->session;
249     interfacePool->device = devHandle->dev;
250     devHandle->dev->privateObject = (void *)interfacePool;
251 
252     ret = CreateCtrPipe(interfacePool);
253     if (ret != HDF_SUCCESS) {
254         goto ERR;
255     }
256 
257     ret = RawGetConfiguration(devHandle, &activeConfig);
258     if (ret != HDF_SUCCESS) {
259         goto ERR;
260     }
261 
262     ret = RawGetConfigDescriptor(devHandle->dev, activeConfig, &config);
263     if (ret != HDF_SUCCESS) {
264         goto FREE_CONFIG;
265     }
266 
267     ret = UsbProtocalCreatInterfaceObj(config, interfacePool);
268     if (ret != HDF_SUCCESS) {
269         goto FREE_CONFIG;
270     }
271 
272 FREE_CONFIG:
273     if (config != NULL) {
274         RawClearConfiguration(config);
275         RawUsbMemFree(config);
276         config = NULL;
277     }
278 
279     if (ret == HDF_SUCCESS) {
280         return ret;
281     }
282 
283 ERR:
284     (void)UsbIfDestroyInterfaceObj(interfacePool, NULL);
285     return ret;
286 }
287 
288