1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include "usbfn_cfg_mgr.h"
17094332d3Sopenharmony_ci#include "usbfn_dev_mgr.h"
18094332d3Sopenharmony_ci#include "usbfn_device.h"
19094332d3Sopenharmony_ci#include "usbfn_interface.h"
20094332d3Sopenharmony_ci#include "usbfn_io_mgr.h"
21094332d3Sopenharmony_ci#include "usbfn_request.h"
22094332d3Sopenharmony_ci#include "usbd_wrapper.h"
23094332d3Sopenharmony_ci
24094332d3Sopenharmony_ci#define HDF_LOG_TAG usbfn_sdk_if
25094332d3Sopenharmony_ci
26094332d3Sopenharmony_cistatic struct UsbDeviceFunctionsInfo g_functionsInfo[] = {
27094332d3Sopenharmony_ci    {"f_generic.a",   1     },
28094332d3Sopenharmony_ci    {"f_generic.e",   1 << 1},
29094332d3Sopenharmony_ci    {"f_generic.mtp", 1 << 3},
30094332d3Sopenharmony_ci    {"f_generic.ptp", 1 << 4},
31094332d3Sopenharmony_ci    {NULL,            0     },
32094332d3Sopenharmony_ci};
33094332d3Sopenharmony_ci
34094332d3Sopenharmony_cistatic int32_t IsDescriptorOk(struct UsbFnDeviceDesc *des)
35094332d3Sopenharmony_ci{
36094332d3Sopenharmony_ci    int32_t i, j;
37094332d3Sopenharmony_ci    struct UsbFnStrings **strings = NULL;
38094332d3Sopenharmony_ci    struct UsbFnFunction *functions = NULL;
39094332d3Sopenharmony_ci    if (des == NULL) {
40094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: des null", __func__);
41094332d3Sopenharmony_ci        goto ERR_DES;
42094332d3Sopenharmony_ci    }
43094332d3Sopenharmony_ci    if (des->deviceDesc == NULL || des->deviceStrings == NULL || des->configs == NULL) {
44094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: deviceDesc  deviceStrings configs null", __func__);
45094332d3Sopenharmony_ci        goto ERR_DES;
46094332d3Sopenharmony_ci    }
47094332d3Sopenharmony_ci
48094332d3Sopenharmony_ci    strings = des->deviceStrings;
49094332d3Sopenharmony_ci    if (strings[0] == NULL) {
50094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: strings null", __func__);
51094332d3Sopenharmony_ci        goto ERR_DES;
52094332d3Sopenharmony_ci    }
53094332d3Sopenharmony_ci
54094332d3Sopenharmony_ci    for (i = 0; des->configs[i] != NULL; i++) {
55094332d3Sopenharmony_ci        for (j = 0; des->configs[i]->functions[j] != NULL; j++) {
56094332d3Sopenharmony_ci            functions = des->configs[i]->functions[j];
57094332d3Sopenharmony_ci            if (strncmp(functions->funcName, FUNCTION_GENERIC, strlen(FUNCTION_GENERIC)) != 0) {
58094332d3Sopenharmony_ci                continue;
59094332d3Sopenharmony_ci            }
60094332d3Sopenharmony_ci            if (functions->fsDescriptors == NULL) {
61094332d3Sopenharmony_ci                HDF_LOGE("%{public}s: fsDescriptors null", __func__);
62094332d3Sopenharmony_ci                goto ERR_DES;
63094332d3Sopenharmony_ci            }
64094332d3Sopenharmony_ci        }
65094332d3Sopenharmony_ci    }
66094332d3Sopenharmony_ci    if (i == 0 || j == 0) {
67094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: configs functions null", __func__);
68094332d3Sopenharmony_ci        goto ERR_DES;
69094332d3Sopenharmony_ci    }
70094332d3Sopenharmony_ci
71094332d3Sopenharmony_ci    return 0;
72094332d3Sopenharmony_ciERR_DES:
73094332d3Sopenharmony_ci    HDF_LOGE("%{public}s: DeviceDesc bad", __func__);
74094332d3Sopenharmony_ci    return HDF_ERR_INVALID_PARAM;
75094332d3Sopenharmony_ci}
76094332d3Sopenharmony_ci
77094332d3Sopenharmony_cistatic void DoChangeFunction(struct UsbFnFunction * const function, struct UsbFnDescriptorData * const descriptor)
78094332d3Sopenharmony_ci{
79094332d3Sopenharmony_ci    uint32_t i;
80094332d3Sopenharmony_ci    struct UsbDeviceFunctionsInfo *funcInfo = g_functionsInfo;
81094332d3Sopenharmony_ci    for (i = 0; funcInfo[i].functionName != NULL; i++) {
82094332d3Sopenharmony_ci        if (strncmp(function->funcName, funcInfo[i].functionName, strlen(funcInfo[i].functionName)) == 0) {
83094332d3Sopenharmony_ci            if ((descriptor->functionMask & funcInfo[i].numberMask) != 0) {
84094332d3Sopenharmony_ci                function->enable = true;
85094332d3Sopenharmony_ci                HDF_LOGI("%{public}s: enable function = %{public}s", __func__, funcInfo[i].functionName);
86094332d3Sopenharmony_ci            } else {
87094332d3Sopenharmony_ci                function->enable = false;
88094332d3Sopenharmony_ci                HDF_LOGI("%{public}s: disable function = %{public}s", __func__, funcInfo[i].functionName);
89094332d3Sopenharmony_ci            }
90094332d3Sopenharmony_ci        }
91094332d3Sopenharmony_ci    }
92094332d3Sopenharmony_ci}
93094332d3Sopenharmony_ci
94094332d3Sopenharmony_cistatic void UsbFnChangeFunction(struct UsbFnDeviceDesc * const des, struct UsbFnDescriptorData * const descriptor)
95094332d3Sopenharmony_ci{
96094332d3Sopenharmony_ci    uint32_t i;
97094332d3Sopenharmony_ci    uint32_t j;
98094332d3Sopenharmony_ci    if (des == NULL || descriptor == NULL) {
99094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: param is null", __func__);
100094332d3Sopenharmony_ci        return;
101094332d3Sopenharmony_ci    }
102094332d3Sopenharmony_ci    for (i = 0; des->configs[i] != NULL; i++) {
103094332d3Sopenharmony_ci        for (j = 0; des->configs[i]->functions[j] != NULL; j++) {
104094332d3Sopenharmony_ci            DoChangeFunction(des->configs[i]->functions[j], descriptor);
105094332d3Sopenharmony_ci        }
106094332d3Sopenharmony_ci    }
107094332d3Sopenharmony_ci}
108094332d3Sopenharmony_ci
109094332d3Sopenharmony_ciconst struct UsbFnDevice *UsbFnCreateDevice(const char *udcName, struct UsbFnDescriptorData *descriptor)
110094332d3Sopenharmony_ci{
111094332d3Sopenharmony_ci    int32_t ret;
112094332d3Sopenharmony_ci    const struct DeviceResourceNode *property = NULL;
113094332d3Sopenharmony_ci    struct UsbFnDeviceDesc *des = NULL;
114094332d3Sopenharmony_ci
115094332d3Sopenharmony_ci    if (udcName == NULL || descriptor == NULL) {
116094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
117094332d3Sopenharmony_ci        return NULL;
118094332d3Sopenharmony_ci    }
119094332d3Sopenharmony_ci    if (UsbFnMgrDeviceGet(udcName) != NULL) {
120094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: udc %{public}s haved create", __func__, udcName);
121094332d3Sopenharmony_ci        return NULL;
122094332d3Sopenharmony_ci    }
123094332d3Sopenharmony_ci    HDF_LOGD("%{public}s: type=%{public}d, fMask=%{public}d", __func__, descriptor->type, descriptor->functionMask);
124094332d3Sopenharmony_ci    if (descriptor->type == USBFN_DESC_DATA_TYPE_PROP) {
125094332d3Sopenharmony_ci        property = descriptor->property;
126094332d3Sopenharmony_ci        HDF_LOGD("%{public}s: use descriptor in HCS", __func__);
127094332d3Sopenharmony_ci        des = UsbFnCfgMgrGetInstanceFromHCS(property);
128094332d3Sopenharmony_ci        if (des == NULL) {
129094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: get descriptors from HCS failed", __func__);
130094332d3Sopenharmony_ci            return NULL;
131094332d3Sopenharmony_ci        }
132094332d3Sopenharmony_ci    } else {
133094332d3Sopenharmony_ci        des = descriptor->descriptor;
134094332d3Sopenharmony_ci    }
135094332d3Sopenharmony_ci    UsbFnChangeFunction(des, descriptor);
136094332d3Sopenharmony_ci    ret = IsDescriptorOk(des);
137094332d3Sopenharmony_ci    if (ret) {
138094332d3Sopenharmony_ci        return NULL;
139094332d3Sopenharmony_ci    }
140094332d3Sopenharmony_ci
141094332d3Sopenharmony_ci    return (struct UsbFnDevice *)UsbFnMgrDeviceCreate(udcName, des, property);
142094332d3Sopenharmony_ci}
143094332d3Sopenharmony_ci
144094332d3Sopenharmony_ciint32_t UsbFnRemoveDevice(struct UsbFnDevice *fnDevice)
145094332d3Sopenharmony_ci{
146094332d3Sopenharmony_ci    if (fnDevice == NULL) {
147094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
148094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
149094332d3Sopenharmony_ci    }
150094332d3Sopenharmony_ci    return UsbFnMgrDeviceRemove(fnDevice);
151094332d3Sopenharmony_ci}
152094332d3Sopenharmony_ci
153094332d3Sopenharmony_ciconst struct UsbFnDevice *UsbFnGetDevice(const char *udcName)
154094332d3Sopenharmony_ci{
155094332d3Sopenharmony_ci    if (udcName == NULL) {
156094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
157094332d3Sopenharmony_ci        return NULL;
158094332d3Sopenharmony_ci    }
159094332d3Sopenharmony_ci    return (struct UsbFnDevice *)UsbFnMgrDeviceGet((const char *)udcName);
160094332d3Sopenharmony_ci}
161094332d3Sopenharmony_ci
162094332d3Sopenharmony_ciint32_t UsbFnGetDeviceState(struct UsbFnDevice *fnDevice, UsbFnDeviceState *devState)
163094332d3Sopenharmony_ci{
164094332d3Sopenharmony_ci    if (fnDevice == NULL || devState == NULL) {
165094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
166094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
167094332d3Sopenharmony_ci    }
168094332d3Sopenharmony_ci    return UsbFnMgrDeviceGetState(fnDevice, devState);
169094332d3Sopenharmony_ci}
170094332d3Sopenharmony_ci
171094332d3Sopenharmony_ciconst struct UsbFnInterface *UsbFnGetInterface(struct UsbFnDevice *fnDevice, uint8_t interfaceIndex)
172094332d3Sopenharmony_ci{
173094332d3Sopenharmony_ci    if (fnDevice == NULL) {
174094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
175094332d3Sopenharmony_ci        return NULL;
176094332d3Sopenharmony_ci    }
177094332d3Sopenharmony_ci    return (struct UsbFnInterface *)UsbFnMgrDeviceGetInterface(fnDevice, interfaceIndex);
178094332d3Sopenharmony_ci}
179094332d3Sopenharmony_ci
180094332d3Sopenharmony_ciint32_t UsbFnStartRecvInterfaceEvent(
181094332d3Sopenharmony_ci    struct UsbFnInterface *interface, uint32_t eventMask, UsbFnEventCallback callback, void *context)
182094332d3Sopenharmony_ci{
183094332d3Sopenharmony_ci    if (interface == NULL || eventMask == 0 || callback == NULL) {
184094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID_PARAM", __func__);
185094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
186094332d3Sopenharmony_ci    }
187094332d3Sopenharmony_ci    return UsbFnMgrStartRecvEvent(interface, eventMask, callback, context);
188094332d3Sopenharmony_ci}
189094332d3Sopenharmony_ci
190094332d3Sopenharmony_ciint32_t UsbFnStopRecvInterfaceEvent(struct UsbFnInterface *interface)
191094332d3Sopenharmony_ci{
192094332d3Sopenharmony_ci    if (interface == NULL) {
193094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
194094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
195094332d3Sopenharmony_ci    }
196094332d3Sopenharmony_ci    return UsbFnStopRecvEvent(interface);
197094332d3Sopenharmony_ci}
198094332d3Sopenharmony_ci
199094332d3Sopenharmony_ciUsbFnInterfaceHandle UsbFnOpenInterface(struct UsbFnInterface *interface)
200094332d3Sopenharmony_ci{
201094332d3Sopenharmony_ci    if (interface == NULL) {
202094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
203094332d3Sopenharmony_ci        return NULL;
204094332d3Sopenharmony_ci    }
205094332d3Sopenharmony_ci    return (UsbFnInterfaceHandle)UsbFnIoMgrInterfaceOpen(interface);
206094332d3Sopenharmony_ci}
207094332d3Sopenharmony_ci
208094332d3Sopenharmony_ciint32_t UsbFnCloseInterface(UsbFnInterfaceHandle handle)
209094332d3Sopenharmony_ci{
210094332d3Sopenharmony_ci    if (handle == NULL) {
211094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
212094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
213094332d3Sopenharmony_ci    }
214094332d3Sopenharmony_ci    return UsbFnIoMgrInterfaceClose((struct UsbHandleMgr *)handle);
215094332d3Sopenharmony_ci}
216094332d3Sopenharmony_ci
217094332d3Sopenharmony_ciint32_t UsbFnGetInterfacePipeInfo(struct UsbFnInterface *interface, uint8_t pipeId, struct UsbFnPipeInfo *info)
218094332d3Sopenharmony_ci{
219094332d3Sopenharmony_ci    if (info == NULL || interface == NULL) {
220094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
221094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
222094332d3Sopenharmony_ci    }
223094332d3Sopenharmony_ci    return UsbFnIoMgrInterfaceGetPipeInfo(interface, pipeId, info);
224094332d3Sopenharmony_ci}
225094332d3Sopenharmony_ci
226094332d3Sopenharmony_ciint32_t UsbFnRegistInterfaceProp(const struct UsbFnInterface *interface, const struct UsbFnRegistInfo *registInfo)
227094332d3Sopenharmony_ci{
228094332d3Sopenharmony_ci    if (registInfo == NULL || interface == NULL) {
229094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
230094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
231094332d3Sopenharmony_ci    }
232094332d3Sopenharmony_ci    return UsbFnCfgMgrRegisterProp(interface, registInfo);
233094332d3Sopenharmony_ci}
234094332d3Sopenharmony_ci
235094332d3Sopenharmony_ciint32_t UsbFnGetInterfaceProp(const struct UsbFnInterface *interface, const char *name, char *value)
236094332d3Sopenharmony_ci{
237094332d3Sopenharmony_ci    if (name == NULL || interface == NULL || value == NULL) {
238094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
239094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
240094332d3Sopenharmony_ci    }
241094332d3Sopenharmony_ci    return UsbFnCfgMgrGetProp(interface, name, value);
242094332d3Sopenharmony_ci}
243094332d3Sopenharmony_ci
244094332d3Sopenharmony_ciint32_t UsbFnSetInterfaceProp(const struct UsbFnInterface *interface, const char *name, const char *value)
245094332d3Sopenharmony_ci{
246094332d3Sopenharmony_ci    if (name == NULL || interface == NULL) {
247094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
248094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
249094332d3Sopenharmony_ci    }
250094332d3Sopenharmony_ci    return UsbFnCfgMgrSetProp(interface, name, value);
251094332d3Sopenharmony_ci}
252094332d3Sopenharmony_ci
253094332d3Sopenharmony_cistruct UsbFnRequest *UsbFnAllocRequest(UsbFnInterfaceHandle handle, uint8_t pipe, uint32_t len)
254094332d3Sopenharmony_ci{
255094332d3Sopenharmony_ci    struct UsbHandleMgr *handleMgr = handle;
256094332d3Sopenharmony_ci    if (handle == NULL || len > MAX_BUFLEN || len == 0 || pipe >= handleMgr->numFd) {
257094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
258094332d3Sopenharmony_ci        return NULL;
259094332d3Sopenharmony_ci    }
260094332d3Sopenharmony_ci    return UsbFnIoMgrRequestAlloc(handleMgr, pipe + 1, len);
261094332d3Sopenharmony_ci}
262094332d3Sopenharmony_ci
263094332d3Sopenharmony_cistruct UsbFnRequest *UsbFnAllocCtrlRequest(UsbFnInterfaceHandle handle, uint32_t len)
264094332d3Sopenharmony_ci{
265094332d3Sopenharmony_ci    struct UsbHandleMgr *handleMgr = handle;
266094332d3Sopenharmony_ci    if (handle == NULL || len > MAX_BUFLEN || len == 0) {
267094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
268094332d3Sopenharmony_ci        return NULL;
269094332d3Sopenharmony_ci    }
270094332d3Sopenharmony_ci    return UsbFnIoMgrRequestAlloc(handleMgr, 0, len);
271094332d3Sopenharmony_ci}
272094332d3Sopenharmony_ci
273094332d3Sopenharmony_ciint32_t UsbFnFreeRequest(struct UsbFnRequest *req)
274094332d3Sopenharmony_ci{
275094332d3Sopenharmony_ci    if (req == NULL) {
276094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
277094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
278094332d3Sopenharmony_ci    }
279094332d3Sopenharmony_ci    return UsbFnIoMgrRequestFree(req);
280094332d3Sopenharmony_ci}
281094332d3Sopenharmony_ci
282094332d3Sopenharmony_ciint32_t UsbFnGetRequestStatus(struct UsbFnRequest *req, UsbRequestStatus *status)
283094332d3Sopenharmony_ci{
284094332d3Sopenharmony_ci    if (req == NULL || status == NULL) {
285094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
286094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
287094332d3Sopenharmony_ci    }
288094332d3Sopenharmony_ci    return UsbFnIoMgrRequestGetStatus(req, status);
289094332d3Sopenharmony_ci}
290094332d3Sopenharmony_ci
291094332d3Sopenharmony_ciint32_t UsbFnSubmitRequestAsync(struct UsbFnRequest *req)
292094332d3Sopenharmony_ci{
293094332d3Sopenharmony_ci    if (req == NULL) {
294094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
295094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
296094332d3Sopenharmony_ci    }
297094332d3Sopenharmony_ci    return UsbFnIoMgrRequestSubmitAsync(req);
298094332d3Sopenharmony_ci}
299094332d3Sopenharmony_ci
300094332d3Sopenharmony_ciint32_t UsbFnCancelRequest(struct UsbFnRequest *req)
301094332d3Sopenharmony_ci{
302094332d3Sopenharmony_ci    if (req == NULL) {
303094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
304094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
305094332d3Sopenharmony_ci    }
306094332d3Sopenharmony_ci    return UsbFnIoMgrRequestCancel(req);
307094332d3Sopenharmony_ci}
308094332d3Sopenharmony_ci
309094332d3Sopenharmony_ciint32_t UsbFnSubmitRequestSync(struct UsbFnRequest *req, uint32_t timeout)
310094332d3Sopenharmony_ci{
311094332d3Sopenharmony_ci    if (req == NULL) {
312094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: INVALID PARAM", __func__);
313094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
314094332d3Sopenharmony_ci    }
315094332d3Sopenharmony_ci    return UsbFnIoMgrRequestSubmitSync(req, timeout);
316094332d3Sopenharmony_ci}
317