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 "usbfn_cfg_mgr.h"
17#include "usbfn_dev_mgr.h"
18#include "usbfn_device.h"
19#include "usbfn_interface.h"
20#include "usbfn_io_mgr.h"
21#include "usbfn_request.h"
22#include "usbd_wrapper.h"
23
24#define HDF_LOG_TAG usbfn_sdk_if
25
26static struct UsbDeviceFunctionsInfo g_functionsInfo[] = {
27    {"f_generic.a",   1     },
28    {"f_generic.e",   1 << 1},
29    {"f_generic.mtp", 1 << 3},
30    {"f_generic.ptp", 1 << 4},
31    {NULL,            0     },
32};
33
34static int32_t IsDescriptorOk(struct UsbFnDeviceDesc *des)
35{
36    int32_t i, j;
37    struct UsbFnStrings **strings = NULL;
38    struct UsbFnFunction *functions = NULL;
39    if (des == NULL) {
40        HDF_LOGE("%{public}s: des null", __func__);
41        goto ERR_DES;
42    }
43    if (des->deviceDesc == NULL || des->deviceStrings == NULL || des->configs == NULL) {
44        HDF_LOGE("%{public}s: deviceDesc  deviceStrings configs null", __func__);
45        goto ERR_DES;
46    }
47
48    strings = des->deviceStrings;
49    if (strings[0] == NULL) {
50        HDF_LOGE("%{public}s: strings null", __func__);
51        goto ERR_DES;
52    }
53
54    for (i = 0; des->configs[i] != NULL; i++) {
55        for (j = 0; des->configs[i]->functions[j] != NULL; j++) {
56            functions = des->configs[i]->functions[j];
57            if (strncmp(functions->funcName, FUNCTION_GENERIC, strlen(FUNCTION_GENERIC)) != 0) {
58                continue;
59            }
60            if (functions->fsDescriptors == NULL) {
61                HDF_LOGE("%{public}s: fsDescriptors null", __func__);
62                goto ERR_DES;
63            }
64        }
65    }
66    if (i == 0 || j == 0) {
67        HDF_LOGE("%{public}s: configs functions null", __func__);
68        goto ERR_DES;
69    }
70
71    return 0;
72ERR_DES:
73    HDF_LOGE("%{public}s: DeviceDesc bad", __func__);
74    return HDF_ERR_INVALID_PARAM;
75}
76
77static void DoChangeFunction(struct UsbFnFunction * const function, struct UsbFnDescriptorData * const descriptor)
78{
79    uint32_t i;
80    struct UsbDeviceFunctionsInfo *funcInfo = g_functionsInfo;
81    for (i = 0; funcInfo[i].functionName != NULL; i++) {
82        if (strncmp(function->funcName, funcInfo[i].functionName, strlen(funcInfo[i].functionName)) == 0) {
83            if ((descriptor->functionMask & funcInfo[i].numberMask) != 0) {
84                function->enable = true;
85                HDF_LOGI("%{public}s: enable function = %{public}s", __func__, funcInfo[i].functionName);
86            } else {
87                function->enable = false;
88                HDF_LOGI("%{public}s: disable function = %{public}s", __func__, funcInfo[i].functionName);
89            }
90        }
91    }
92}
93
94static void UsbFnChangeFunction(struct UsbFnDeviceDesc * const des, struct UsbFnDescriptorData * const descriptor)
95{
96    uint32_t i;
97    uint32_t j;
98    if (des == NULL || descriptor == NULL) {
99        HDF_LOGE("%{public}s: param is null", __func__);
100        return;
101    }
102    for (i = 0; des->configs[i] != NULL; i++) {
103        for (j = 0; des->configs[i]->functions[j] != NULL; j++) {
104            DoChangeFunction(des->configs[i]->functions[j], descriptor);
105        }
106    }
107}
108
109const struct UsbFnDevice *UsbFnCreateDevice(const char *udcName, struct UsbFnDescriptorData *descriptor)
110{
111    int32_t ret;
112    const struct DeviceResourceNode *property = NULL;
113    struct UsbFnDeviceDesc *des = NULL;
114
115    if (udcName == NULL || descriptor == NULL) {
116        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
117        return NULL;
118    }
119    if (UsbFnMgrDeviceGet(udcName) != NULL) {
120        HDF_LOGE("%{public}s: udc %{public}s haved create", __func__, udcName);
121        return NULL;
122    }
123    HDF_LOGD("%{public}s: type=%{public}d, fMask=%{public}d", __func__, descriptor->type, descriptor->functionMask);
124    if (descriptor->type == USBFN_DESC_DATA_TYPE_PROP) {
125        property = descriptor->property;
126        HDF_LOGD("%{public}s: use descriptor in HCS", __func__);
127        des = UsbFnCfgMgrGetInstanceFromHCS(property);
128        if (des == NULL) {
129            HDF_LOGE("%{public}s: get descriptors from HCS failed", __func__);
130            return NULL;
131        }
132    } else {
133        des = descriptor->descriptor;
134    }
135    UsbFnChangeFunction(des, descriptor);
136    ret = IsDescriptorOk(des);
137    if (ret) {
138        return NULL;
139    }
140
141    return (struct UsbFnDevice *)UsbFnMgrDeviceCreate(udcName, des, property);
142}
143
144int32_t UsbFnRemoveDevice(struct UsbFnDevice *fnDevice)
145{
146    if (fnDevice == NULL) {
147        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
148        return HDF_ERR_INVALID_PARAM;
149    }
150    return UsbFnMgrDeviceRemove(fnDevice);
151}
152
153const struct UsbFnDevice *UsbFnGetDevice(const char *udcName)
154{
155    if (udcName == NULL) {
156        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
157        return NULL;
158    }
159    return (struct UsbFnDevice *)UsbFnMgrDeviceGet((const char *)udcName);
160}
161
162int32_t UsbFnGetDeviceState(struct UsbFnDevice *fnDevice, UsbFnDeviceState *devState)
163{
164    if (fnDevice == NULL || devState == NULL) {
165        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
166        return HDF_ERR_INVALID_PARAM;
167    }
168    return UsbFnMgrDeviceGetState(fnDevice, devState);
169}
170
171const struct UsbFnInterface *UsbFnGetInterface(struct UsbFnDevice *fnDevice, uint8_t interfaceIndex)
172{
173    if (fnDevice == NULL) {
174        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
175        return NULL;
176    }
177    return (struct UsbFnInterface *)UsbFnMgrDeviceGetInterface(fnDevice, interfaceIndex);
178}
179
180int32_t UsbFnStartRecvInterfaceEvent(
181    struct UsbFnInterface *interface, uint32_t eventMask, UsbFnEventCallback callback, void *context)
182{
183    if (interface == NULL || eventMask == 0 || callback == NULL) {
184        HDF_LOGE("%{public}s: INVALID_PARAM", __func__);
185        return HDF_ERR_INVALID_PARAM;
186    }
187    return UsbFnMgrStartRecvEvent(interface, eventMask, callback, context);
188}
189
190int32_t UsbFnStopRecvInterfaceEvent(struct UsbFnInterface *interface)
191{
192    if (interface == NULL) {
193        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
194        return HDF_ERR_INVALID_PARAM;
195    }
196    return UsbFnStopRecvEvent(interface);
197}
198
199UsbFnInterfaceHandle UsbFnOpenInterface(struct UsbFnInterface *interface)
200{
201    if (interface == NULL) {
202        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
203        return NULL;
204    }
205    return (UsbFnInterfaceHandle)UsbFnIoMgrInterfaceOpen(interface);
206}
207
208int32_t UsbFnCloseInterface(UsbFnInterfaceHandle handle)
209{
210    if (handle == NULL) {
211        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
212        return HDF_ERR_INVALID_PARAM;
213    }
214    return UsbFnIoMgrInterfaceClose((struct UsbHandleMgr *)handle);
215}
216
217int32_t UsbFnGetInterfacePipeInfo(struct UsbFnInterface *interface, uint8_t pipeId, struct UsbFnPipeInfo *info)
218{
219    if (info == NULL || interface == NULL) {
220        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
221        return HDF_ERR_INVALID_PARAM;
222    }
223    return UsbFnIoMgrInterfaceGetPipeInfo(interface, pipeId, info);
224}
225
226int32_t UsbFnRegistInterfaceProp(const struct UsbFnInterface *interface, const struct UsbFnRegistInfo *registInfo)
227{
228    if (registInfo == NULL || interface == NULL) {
229        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
230        return HDF_ERR_INVALID_PARAM;
231    }
232    return UsbFnCfgMgrRegisterProp(interface, registInfo);
233}
234
235int32_t UsbFnGetInterfaceProp(const struct UsbFnInterface *interface, const char *name, char *value)
236{
237    if (name == NULL || interface == NULL || value == NULL) {
238        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
239        return HDF_ERR_INVALID_PARAM;
240    }
241    return UsbFnCfgMgrGetProp(interface, name, value);
242}
243
244int32_t UsbFnSetInterfaceProp(const struct UsbFnInterface *interface, const char *name, const char *value)
245{
246    if (name == NULL || interface == NULL) {
247        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
248        return HDF_ERR_INVALID_PARAM;
249    }
250    return UsbFnCfgMgrSetProp(interface, name, value);
251}
252
253struct UsbFnRequest *UsbFnAllocRequest(UsbFnInterfaceHandle handle, uint8_t pipe, uint32_t len)
254{
255    struct UsbHandleMgr *handleMgr = handle;
256    if (handle == NULL || len > MAX_BUFLEN || len == 0 || pipe >= handleMgr->numFd) {
257        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
258        return NULL;
259    }
260    return UsbFnIoMgrRequestAlloc(handleMgr, pipe + 1, len);
261}
262
263struct UsbFnRequest *UsbFnAllocCtrlRequest(UsbFnInterfaceHandle handle, uint32_t len)
264{
265    struct UsbHandleMgr *handleMgr = handle;
266    if (handle == NULL || len > MAX_BUFLEN || len == 0) {
267        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
268        return NULL;
269    }
270    return UsbFnIoMgrRequestAlloc(handleMgr, 0, len);
271}
272
273int32_t UsbFnFreeRequest(struct UsbFnRequest *req)
274{
275    if (req == NULL) {
276        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
277        return HDF_ERR_INVALID_PARAM;
278    }
279    return UsbFnIoMgrRequestFree(req);
280}
281
282int32_t UsbFnGetRequestStatus(struct UsbFnRequest *req, UsbRequestStatus *status)
283{
284    if (req == NULL || status == NULL) {
285        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
286        return HDF_ERR_INVALID_PARAM;
287    }
288    return UsbFnIoMgrRequestGetStatus(req, status);
289}
290
291int32_t UsbFnSubmitRequestAsync(struct UsbFnRequest *req)
292{
293    if (req == NULL) {
294        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
295        return HDF_ERR_INVALID_PARAM;
296    }
297    return UsbFnIoMgrRequestSubmitAsync(req);
298}
299
300int32_t UsbFnCancelRequest(struct UsbFnRequest *req)
301{
302    if (req == NULL) {
303        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
304        return HDF_ERR_INVALID_PARAM;
305    }
306    return UsbFnIoMgrRequestCancel(req);
307}
308
309int32_t UsbFnSubmitRequestSync(struct UsbFnRequest *req, uint32_t timeout)
310{
311    if (req == NULL) {
312        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
313        return HDF_ERR_INVALID_PARAM;
314    }
315    return UsbFnIoMgrRequestSubmitSync(req, timeout);
316}
317