• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
19 #define HDF_LOG_TAG USB_PROTOCOL
20 
UsbProtocalFillControlSetup(const unsigned char * setup,const struct UsbControlRequest * ctrlReq)21 int32_t UsbProtocalFillControlSetup(const unsigned char *setup, const struct UsbControlRequest *ctrlReq)
22 {
23     struct UsbRawControlSetup *setupData = (struct UsbRawControlSetup *)setup;
24     int32_t ret = HDF_SUCCESS;
25     if ((setup == NULL) || (ctrlReq == NULL)) {
26         HDF_LOGE("%{public}s:%d invalid parameter", __func__, __LINE__);
27         return HDF_ERR_INVALID_PARAM;
28     }
29     switch (ctrlReq->reqType) {
30         case USB_REQUEST_TYPE_STANDARD:
31         case USB_REQUEST_TYPE_CLASS:
32             setupData->requestType = (((uint8_t)ctrlReq->directon) << USB_DIR_OFFSET) |
33                 ((uint8_t)ctrlReq->reqType << USB_TYPE_OFFSET) |
34                 ((uint8_t)ctrlReq->target << USB_RECIP_OFFSET);
35             setupData->request     = ctrlReq->request;
36             setupData->value       = CPU_TO_LE16(ctrlReq->value);
37             setupData->index       = CPU_TO_LE16(ctrlReq->index);
38             setupData->length      = CPU_TO_LE16(ctrlReq->length);
39             break;
40         case USB_REQUEST_TYPE_VENDOR:
41             setupData->requestType = ((uint8_t)ctrlReq->directon << USB_DIR_OFFSET) |
42                 ((uint8_t)ctrlReq->reqType << USB_TYPE_OFFSET) |
43                 ((uint8_t)ctrlReq->target << USB_RECIP_OFFSET);
44             setupData->request     = ctrlReq->request;
45             setupData->value       = CPU_TO_LE16(ctrlReq->value);
46             setupData->index       = CPU_TO_LE16(ctrlReq->index);
47             setupData->length      = CPU_TO_LE16(ctrlReq->length);
48             break;
49         default:
50             ret = HDF_ERR_INVALID_PARAM;
51             HDF_LOGE("%{public}s:%d invalid request type", __func__, __LINE__);
52             break;
53     }
54     return ret;
55 }
56 
CreateCtrPipe(const struct UsbInterfacePool * pool)57 static int32_t CreateCtrPipe(const struct UsbInterfacePool *pool)
58 {
59     int32_t ret = 0;
60     struct UsbSdkInterface *interfaceObj = NULL;
61     struct UsbPipe *pipe = NULL;
62 
63     if (pool == NULL) {
64         HDF_LOGE("%{public}s:%d invalid param pool", __func__, __LINE__);
65         return HDF_ERR_INVALID_PARAM;
66     }
67 
68     ret = UsbIfCreatInterfaceObj(pool, &interfaceObj);
69     if (ret != HDF_SUCCESS) {
70         return HDF_ERR_MALLOC_FAIL;
71     }
72     interfaceObj->interface.info.interfaceIndex = USB_CTRL_INTERFACE_ID;
73     interfaceObj->interface.info.pipeNum = 1;
74     interfaceObj->altSettingId = 0;
75     interfaceObj->interface.info.curAltSetting = 0;
76     ret = UsbIfCreatPipeObj(interfaceObj, &pipe);
77     if (ret != HDF_SUCCESS) {
78         return HDF_ERR_IO;
79     }
80 
81     pipe->info.pipeId = 0;
82     pipe->info.pipeAddress = 0;
83     pipe->info.pipeDirection = USB_PIPE_DIRECTION_OUT;
84     pipe->info.pipeType = USB_PIPE_TYPE_CONTROL;
85 
86     return ret;
87 }
88 
UsbInterfaceInit(struct UsbSdkInterface * interfaceObj,const struct UsbRawInterfaceDescriptor * iface,const struct UsbRawInterface * altsettings)89 static int32_t UsbInterfaceInit(struct UsbSdkInterface *interfaceObj,
90     const struct UsbRawInterfaceDescriptor *iface, const struct UsbRawInterface *altsettings)
91 {
92     struct UsbInterfaceInfo *ptr = NULL;
93 
94     if ((interfaceObj == NULL) || (iface == NULL)) {
95         HDF_LOGE("%{public}s: invalid parameter", __func__);
96         return HDF_ERR_INVALID_PARAM;
97     }
98     ptr = &interfaceObj->interface.info;
99     ptr->pipeNum = iface->interfaceDescriptor.bNumEndpoints;
100     ptr->interfaceClass = iface->interfaceDescriptor.bInterfaceClass;
101     ptr->interfaceSubClass = iface->interfaceDescriptor.bInterfaceSubClass;
102     ptr->interfaceProtocol = iface->interfaceDescriptor.bInterfaceProtocol;
103     ptr->interfaceIndex = iface->interfaceDescriptor.bInterfaceNumber;
104     ptr->altSettings = altsettings->numAltsetting;
105     ptr->curAltSetting = USB_DEFAULT_ALTSETTING;
106 
107     interfaceObj->altSettingId = iface->interfaceDescriptor.bAlternateSetting;
108 
109     return HDF_SUCCESS;
110 }
111 
UsbPipeInit(struct UsbPipe * pipe,const struct UsbRawEndpointDescriptor * ep,uint8_t id)112 static int32_t UsbPipeInit(struct UsbPipe *pipe, const struct UsbRawEndpointDescriptor *ep, uint8_t id)
113 {
114     if ((pipe == NULL) || (ep == NULL)) {
115         HDF_LOGE("%{public}s: invalid parameter", __func__);
116         return HDF_ERR_INVALID_PARAM;
117     }
118 
119     pipe->info.pipeId = id;
120     pipe->info.maxPacketSize = ep->endpointDescriptor.wMaxPacketSize;
121     pipe->info.interval = ep->endpointDescriptor.bInterval;
122     pipe->info.pipeType =  ep->endpointDescriptor.bmAttributes & USB_DDK_ENDPOINT_XFERTYPE_MASK;
123     pipe->info.pipeAddress = ep->endpointDescriptor.bEndpointAddress & USB_DDK_ENDPOINT_NUMBER_MASK;
124     pipe->info.pipeDirection = ep->endpointDescriptor.bEndpointAddress & USB_DDK_ENDPOINT_DIR_MASK;
125     return HDF_SUCCESS;
126 }
127 
UsbGetInterfaceFromConfig(const struct UsbRawConfigDescriptor * config,uint8_t idx)128 static const struct UsbRawInterface *UsbGetInterfaceFromConfig(
129     const struct UsbRawConfigDescriptor *config, uint8_t idx)
130 {
131     if (config == NULL) {
132         HDF_LOGE("%{public}s: invalid param", __func__);
133         return NULL;
134     }
135     if (config->configDescriptor.bNumInterfaces < idx + 1) {
136         HDF_LOGE("%{public}s: invalid param", __func__);
137         return NULL;
138     }
139 
140     return config->interface[idx];
141 }
142 
143 /* The default AltSetting is 0 */
UsbGetInterfaceDesc(const struct UsbRawInterface * altSetting,uint8_t settingIndex)144 static const struct UsbRawInterfaceDescriptor *UsbGetInterfaceDesc(
145     const struct UsbRawInterface *altSetting, uint8_t settingIndex)
146 {
147     if (altSetting == NULL) {
148         HDF_LOGE("%{public}s:%d invalid param altSetting", __func__, __LINE__);
149         return NULL;
150     }
151 
152     return &altSetting->altsetting[settingIndex];
153 }
154 
UsbGetEpDesc(const struct UsbRawInterfaceDescriptor * ifDes,uint8_t idx)155 static const struct UsbRawEndpointDescriptor *UsbGetEpDesc(
156     const struct UsbRawInterfaceDescriptor *ifDes, uint8_t idx)
157 {
158     if (ifDes == NULL) {
159         HDF_LOGE("%{public}s:%d invalid param ifDes", __func__, __LINE__);
160         return NULL;
161     }
162     if (ifDes->interfaceDescriptor.bNumEndpoints < (idx + 1)) {
163         HDF_LOGE("%{public}s:invalid param numEp:%d+idx:%hhu\n", __func__, ifDes->interfaceDescriptor.bNumEndpoints,
164             idx);
165         return NULL;
166     }
167 
168     return &ifDes->endPoint[idx];
169 }
170 
UsbProtocalCreatePipeObj(const struct UsbRawInterfaceDescriptor * ifDes,const struct UsbSdkInterface * interfaceObj)171 static int32_t UsbProtocalCreatePipeObj(
172     const struct UsbRawInterfaceDescriptor *ifDes, const struct UsbSdkInterface *interfaceObj)
173 {
174     int32_t ret = HDF_SUCCESS;
175     uint8_t id = 0;
176     const struct UsbRawEndpointDescriptor *ep = NULL;
177     struct UsbPipe *pipe = NULL;
178 
179     for (int32_t cnep = 0; cnep < ifDes->interfaceDescriptor.bNumEndpoints; cnep++) {
180         if (ifDes->interfaceDescriptor.bNumEndpoints > USB_MAXENDPOINTS) {
181             HDF_LOGE("%{public}s:%d bNumEndpoints=%d is error",
182                 __func__, __LINE__, ifDes->interfaceDescriptor.bNumEndpoints);
183             ret = HDF_DEV_ERR_NORANGE;
184             break;
185         }
186         ep = UsbGetEpDesc(ifDes, cnep);
187         if (ep == NULL) {
188             ret = HDF_ERR_INVALID_PARAM;
189             break;
190         }
191         ret = UsbIfCreatPipeObj(interfaceObj, &pipe);
192         if (ret != HDF_SUCCESS) {
193             break;
194         }
195         ret = UsbPipeInit(pipe, ep, ++id);
196         if (ret != HDF_SUCCESS) {
197             break;
198         }
199     }
200 
201     return ret;
202 }
203 
UsbProtocalCreatInterfaceObj(const struct UsbRawConfigDescriptor * config,const struct UsbInterfacePool * interfacePool)204 static int32_t UsbProtocalCreatInterfaceObj(const struct UsbRawConfigDescriptor *config,
205     const struct UsbInterfacePool *interfacePool)
206 {
207     uint8_t j;
208     int32_t ret = HDF_SUCCESS;
209     const struct UsbRawInterface *itface = NULL;
210     const struct UsbRawInterfaceDescriptor *ifDes = NULL;
211     struct UsbSdkInterface *interfaceObj = NULL;
212 
213     for (int32_t i = 0; i < config->configDescriptor.bNumInterfaces; i++) {
214         itface = UsbGetInterfaceFromConfig(config, i);
215         if (itface == NULL) {
216             ret = HDF_ERR_INVALID_PARAM;
217             goto ERROR;
218         }
219 
220         for (j = 0; j < itface->numAltsetting; j++) {
221             ifDes = UsbGetInterfaceDesc(itface, j);
222             if (ifDes == NULL) {
223                 ret = HDF_ERR_INVALID_PARAM;
224                 goto ERROR;
225             }
226 
227             ret = UsbIfCreatInterfaceObj(interfacePool, &interfaceObj);
228             if (ret != HDF_SUCCESS) {
229                 goto ERROR;
230             }
231 
232             ret = UsbInterfaceInit(interfaceObj, ifDes, itface);
233             if (ret != 0) {
234                 ret = HDF_ERR_IO;
235                 goto ERROR;
236             }
237 
238             ret = UsbProtocalCreatePipeObj(ifDes, interfaceObj);
239             if (ret != HDF_SUCCESS) {
240                 goto ERROR;
241             }
242         }
243     }
244 
245 ERROR:
246     return ret;
247 }
248 
UsbProtocalParseDescriptor(struct UsbDeviceHandle * devHandle,uint8_t busNum,uint8_t devAddr)249 int32_t UsbProtocalParseDescriptor(struct UsbDeviceHandle *devHandle, uint8_t busNum, uint8_t devAddr)
250 {
251     int32_t ret;
252     int32_t activeConfig = -1;
253     struct UsbInterfacePool *interfacePool = NULL;
254     struct UsbRawConfigDescriptor *config = NULL;
255 
256     if ((devHandle == NULL) || (devHandle->dev == NULL) || (devHandle->dev->session == NULL)) {
257         HDF_LOGE("%{public}s:%d invalid param", __func__, __LINE__);
258         return HDF_ERR_INVALID_PARAM;
259     }
260 
261     ret = UsbIfCreatInterfacePool(devHandle->dev->session, busNum, devAddr, &interfacePool);
262     if (ret != HDF_SUCCESS) {
263         HDF_LOGE("%{public}s:%d UsbIfCreatInterfacePool error", __func__, __LINE__);
264         return HDF_ERR_IO;
265     }
266     interfacePool->session = devHandle->dev->session;
267     interfacePool->device = devHandle->dev;
268     devHandle->dev->privateObject = (void *)interfacePool;
269 
270     ret = CreateCtrPipe(interfacePool);
271     if (ret != HDF_SUCCESS) {
272         goto ERR;
273     }
274 
275     ret = RawGetConfiguration(devHandle, &activeConfig);
276     if (ret != HDF_SUCCESS) {
277         goto ERR;
278     }
279 
280     ret = RawGetConfigDescriptor(devHandle->dev, activeConfig, &config);
281     if (ret != HDF_SUCCESS) {
282         goto FREE_CONFIG;
283     }
284 
285     ret = UsbProtocalCreatInterfaceObj(config, interfacePool);
286     if (ret != HDF_SUCCESS) {
287         goto FREE_CONFIG;
288     }
289 
290 FREE_CONFIG:
291     if (config != NULL) {
292         RawClearConfiguration(config);
293         RawUsbMemFree(config);
294         config = NULL;
295     }
296 
297     if (ret == HDF_SUCCESS) {
298         return ret;
299     }
300 
301 ERR:
302     (void)UsbIfDestroyInterfaceObj(interfacePool, NULL);
303     return ret;
304 }
305 
306