1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2021-2023 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 "device_resource_if.h"
17094332d3Sopenharmony_ci#include "hdf_base.h"
18094332d3Sopenharmony_ci#include "hdf_device_desc.h"
19094332d3Sopenharmony_ci#include "hdf_device_object.h"
20094332d3Sopenharmony_ci#include "hdf_log.h"
21094332d3Sopenharmony_ci#include "osal_mem.h"
22094332d3Sopenharmony_ci#include "osal_time.h"
23094332d3Sopenharmony_ci#include "securec.h"
24094332d3Sopenharmony_ci#include "usbfn_device.h"
25094332d3Sopenharmony_ci#include "usbfn_interface.h"
26094332d3Sopenharmony_ci#include "usbfn_request.h"
27094332d3Sopenharmony_ci
28094332d3Sopenharmony_ci#define HDF_LOG_TAG dev_usbfn
29094332d3Sopenharmony_ci#define UDC_NAME "invalid_udc_name"
30094332d3Sopenharmony_ci
31094332d3Sopenharmony_cienum DevUsbFnCmd {
32094332d3Sopenharmony_ci    DEV_USBFN_INIT = 0x1,
33094332d3Sopenharmony_ci    DEV_USBFN_RELEASE,
34094332d3Sopenharmony_ci};
35094332d3Sopenharmony_ci
36094332d3Sopenharmony_cistruct DevUsbFnMgr {
37094332d3Sopenharmony_ci    struct IDeviceIoService service;
38094332d3Sopenharmony_ci    struct UsbFnDescriptorData descData;
39094332d3Sopenharmony_ci    struct HdfDeviceObject *device;
40094332d3Sopenharmony_ci    const char *udcName;
41094332d3Sopenharmony_ci};
42094332d3Sopenharmony_ci
43094332d3Sopenharmony_cistruct UsbFnDevice *g_fnDev = NULL;
44094332d3Sopenharmony_cistatic int32_t UsbFnReleaseFuncDevice(void)
45094332d3Sopenharmony_ci{
46094332d3Sopenharmony_ci    int32_t ret;
47094332d3Sopenharmony_ci    if (g_fnDev == NULL) {
48094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: fnDev is null", __func__);
49094332d3Sopenharmony_ci        return HDF_FAILURE;
50094332d3Sopenharmony_ci    }
51094332d3Sopenharmony_ci    ret = UsbFnRemoveDevice(g_fnDev);
52094332d3Sopenharmony_ci    if (ret == HDF_SUCCESS) {
53094332d3Sopenharmony_ci        g_fnDev = NULL;
54094332d3Sopenharmony_ci    } else {
55094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: remove usb function device failed", __func__);
56094332d3Sopenharmony_ci    }
57094332d3Sopenharmony_ci
58094332d3Sopenharmony_ci    return ret;
59094332d3Sopenharmony_ci}
60094332d3Sopenharmony_ci
61094332d3Sopenharmony_cistatic int32_t UsbFnRegistUsbfnDevice(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
62094332d3Sopenharmony_ci{
63094332d3Sopenharmony_ci    struct HdfDeviceObject *device = client->device;
64094332d3Sopenharmony_ci    struct DevUsbFnMgr *devMgr = NULL;
65094332d3Sopenharmony_ci    struct UsbFnDevice *fnDev = NULL;
66094332d3Sopenharmony_ci    uint8_t value;
67094332d3Sopenharmony_ci    struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
68094332d3Sopenharmony_ci
69094332d3Sopenharmony_ci    if (iface == NULL || iface->GetUint32 == NULL || device == NULL) {
70094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: iface is invalid", __func__);
71094332d3Sopenharmony_ci        return HDF_FAILURE;
72094332d3Sopenharmony_ci    }
73094332d3Sopenharmony_ci    devMgr = (struct DevUsbFnMgr *)device->service;
74094332d3Sopenharmony_ci    if (HdfSbufReadUint8(data, &value) != true) {
75094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: read sbuf failed", __func__);
76094332d3Sopenharmony_ci        return HDF_FAILURE;
77094332d3Sopenharmony_ci    }
78094332d3Sopenharmony_ci    HDF_LOGI("%{public}s: data=%{public}d, descriptor in %{public}s", __func__, value,
79094332d3Sopenharmony_ci        (devMgr->descData.type == USBFN_DESC_DATA_TYPE_DESC ? "code" : "hcs"));
80094332d3Sopenharmony_ci    devMgr->descData.functionMask = value;
81094332d3Sopenharmony_ci    fnDev = (struct UsbFnDevice *)UsbFnCreateDevice(devMgr->udcName, &devMgr->descData);
82094332d3Sopenharmony_ci    if (fnDev == NULL) {
83094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: create usb function device failed", __func__);
84094332d3Sopenharmony_ci        if (!HdfSbufWriteInt8(reply, 0)) {
85094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: fn_usbfn sbuf write error", __func__);
86094332d3Sopenharmony_ci        }
87094332d3Sopenharmony_ci        return HDF_FAILURE;
88094332d3Sopenharmony_ci    }
89094332d3Sopenharmony_ci    g_fnDev = fnDev;
90094332d3Sopenharmony_ci    if (!HdfSbufWriteInt8(reply, value)) {
91094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: fn_usbfn sbuf write error", __func__);
92094332d3Sopenharmony_ci        return HDF_FAILURE;
93094332d3Sopenharmony_ci    }
94094332d3Sopenharmony_ci    HDF_LOGI("%{public}s: create device done, reply: %{public}d", __func__, value);
95094332d3Sopenharmony_ci    return HDF_SUCCESS;
96094332d3Sopenharmony_ci}
97094332d3Sopenharmony_ci
98094332d3Sopenharmony_cistatic int32_t UsbFnDispatch(
99094332d3Sopenharmony_ci    struct HdfDeviceIoClient *client, int32_t cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
100094332d3Sopenharmony_ci{
101094332d3Sopenharmony_ci    int32_t ret;
102094332d3Sopenharmony_ci    if (client == NULL) {
103094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: client is NULL", __func__);
104094332d3Sopenharmony_ci        return HDF_FAILURE;
105094332d3Sopenharmony_ci    }
106094332d3Sopenharmony_ci
107094332d3Sopenharmony_ci    if (HdfDeviceObjectCheckInterfaceDesc(client->device, data) == false) {
108094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: check interface desc fail", __func__);
109094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
110094332d3Sopenharmony_ci    }
111094332d3Sopenharmony_ci
112094332d3Sopenharmony_ci    switch (cmdId) {
113094332d3Sopenharmony_ci        case DEV_USBFN_INIT:
114094332d3Sopenharmony_ci            ret = UsbFnRegistUsbfnDevice(client, data, reply);
115094332d3Sopenharmony_ci            if (ret != HDF_SUCCESS) {
116094332d3Sopenharmony_ci                HDF_LOGE("%{public}s: create usbfn device failed", __func__);
117094332d3Sopenharmony_ci            }
118094332d3Sopenharmony_ci            break;
119094332d3Sopenharmony_ci        case DEV_USBFN_RELEASE:
120094332d3Sopenharmony_ci            ret = UsbFnReleaseFuncDevice();
121094332d3Sopenharmony_ci            break;
122094332d3Sopenharmony_ci        default:
123094332d3Sopenharmony_ci            ret = HDF_ERR_INVALID_OBJECT;
124094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: unknown cmd id %{public}d", __func__, cmdId);
125094332d3Sopenharmony_ci            break;
126094332d3Sopenharmony_ci    }
127094332d3Sopenharmony_ci    return ret;
128094332d3Sopenharmony_ci}
129094332d3Sopenharmony_ci
130094332d3Sopenharmony_ci/* HdfDriverEntry implementations */
131094332d3Sopenharmony_cistatic int32_t UsbFnDriverBind(struct HdfDeviceObject *device)
132094332d3Sopenharmony_ci{
133094332d3Sopenharmony_ci    struct DevUsbFnMgr *devMgr = NULL;
134094332d3Sopenharmony_ci    if (device == NULL) {
135094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: device is null", __func__);
136094332d3Sopenharmony_ci        return HDF_FAILURE;
137094332d3Sopenharmony_ci    }
138094332d3Sopenharmony_ci    devMgr = (struct DevUsbFnMgr *)OsalMemCalloc(sizeof(*devMgr));
139094332d3Sopenharmony_ci    if (devMgr == NULL) {
140094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: usbfn Alloc usb devMgr failed", __func__);
141094332d3Sopenharmony_ci        return HDF_FAILURE;
142094332d3Sopenharmony_ci    }
143094332d3Sopenharmony_ci
144094332d3Sopenharmony_ci    if (HdfDeviceObjectSetInterfaceDesc(device, "hdf.usb.usbfn") != HDF_SUCCESS) {
145094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: Set Desc fail!", __func__);
146094332d3Sopenharmony_ci        OsalMemFree(devMgr);
147094332d3Sopenharmony_ci        return HDF_FAILURE;
148094332d3Sopenharmony_ci    }
149094332d3Sopenharmony_ci
150094332d3Sopenharmony_ci    devMgr->device = device;
151094332d3Sopenharmony_ci    device->service = &(devMgr->service);
152094332d3Sopenharmony_ci    devMgr->device->service->Dispatch = UsbFnDispatch;
153094332d3Sopenharmony_ci    return HDF_SUCCESS;
154094332d3Sopenharmony_ci}
155094332d3Sopenharmony_ci
156094332d3Sopenharmony_cistatic int32_t UsbFnDriverInit(struct HdfDeviceObject *device)
157094332d3Sopenharmony_ci{
158094332d3Sopenharmony_ci    struct DevUsbFnMgr *devMgr = NULL;
159094332d3Sopenharmony_ci    uint8_t useHcs;
160094332d3Sopenharmony_ci
161094332d3Sopenharmony_ci    struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
162094332d3Sopenharmony_ci    if (iface == NULL || iface->GetUint32 == NULL || device == NULL) {
163094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: iface is invalid", __func__);
164094332d3Sopenharmony_ci        return HDF_FAILURE;
165094332d3Sopenharmony_ci    }
166094332d3Sopenharmony_ci    devMgr = (struct DevUsbFnMgr *)device->service;
167094332d3Sopenharmony_ci    if (iface->GetString(device->property, "udc_name", &devMgr->udcName, UDC_NAME) != HDF_SUCCESS) {
168094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: read udc_name failed, use default: %{public}s", __func__, UDC_NAME);
169094332d3Sopenharmony_ci        return HDF_FAILURE;
170094332d3Sopenharmony_ci    }
171094332d3Sopenharmony_ci    HDF_LOGI("%{public}s: udcName=%{public}s", __func__, devMgr->udcName);
172094332d3Sopenharmony_ci    if (iface->GetUint8(device->property, "use_hcs", &useHcs, 0) != HDF_SUCCESS) {
173094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: read use_hcs fail, use default", __func__);
174094332d3Sopenharmony_ci    }
175094332d3Sopenharmony_ci    HDF_LOGI("%{public}s: use descriptor in %{public}s", __func__, (useHcs == 1) ? "hcs" : "code");
176094332d3Sopenharmony_ci    /* force use descripto in hcs, refer to sample for use descriptor in code */
177094332d3Sopenharmony_ci    devMgr->descData.type = USBFN_DESC_DATA_TYPE_PROP;
178094332d3Sopenharmony_ci    devMgr->descData.property = device->property;
179094332d3Sopenharmony_ci    return HDF_SUCCESS;
180094332d3Sopenharmony_ci}
181094332d3Sopenharmony_ci
182094332d3Sopenharmony_cistatic void UsbFnDriverRelease(struct HdfDeviceObject *device)
183094332d3Sopenharmony_ci{
184094332d3Sopenharmony_ci    struct DevUsbFnMgr *devMgr = NULL;
185094332d3Sopenharmony_ci    devMgr = (struct DevUsbFnMgr *)device->service;
186094332d3Sopenharmony_ci    if (devMgr == NULL) {
187094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: descriptor is NULL", __func__);
188094332d3Sopenharmony_ci        return;
189094332d3Sopenharmony_ci    }
190094332d3Sopenharmony_ci    OsalMemFree(devMgr);
191094332d3Sopenharmony_ci}
192094332d3Sopenharmony_ci
193094332d3Sopenharmony_cistruct HdfDriverEntry g_usbFnDriverEntry = {
194094332d3Sopenharmony_ci    .moduleVersion = 1,
195094332d3Sopenharmony_ci    .moduleName = "usbfn",
196094332d3Sopenharmony_ci    .Bind = UsbFnDriverBind,
197094332d3Sopenharmony_ci    .Init = UsbFnDriverInit,
198094332d3Sopenharmony_ci    .Release = UsbFnDriverRelease,
199094332d3Sopenharmony_ci};
200094332d3Sopenharmony_ci
201094332d3Sopenharmony_ciHDF_INIT(g_usbFnDriverEntry);
202