1/*
2 * Copyright (c) 2022-2023 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 "usbd_function.h"
17
18#include <dlfcn.h>
19#include <unistd.h>
20#include <cerrno>
21
22#include "devmgr_hdi.h"
23#include "hdf_log.h"
24#include "hdf_remote_service.h"
25#include "hdf_sbuf.h"
26#include "idevmgr_hdi.h"
27#include "iservmgr_hdi.h"
28#include "message_option.h"
29#include "message_parcel.h"
30#include "osal_time.h"
31#include "parameter.h"
32#include "securec.h"
33#include "string_ex.h"
34#include "usbd_type.h"
35#include "usbfn_mtp_impl.h"
36#include "usbd_wrapper.h"
37
38namespace OHOS {
39namespace HDI {
40namespace Usb {
41namespace V1_1 {
42uint32_t UsbdFunction::currentFuncs_ = USB_FUNCTION_HDC;
43
44using OHOS::HDI::DeviceManager::V1_0::IDeviceManager;
45using OHOS::HDI::ServiceManager::V1_0::IServiceManager;
46using OHOS::HDI::Usb::Gadget::Mtp::V1_0::IUsbfnMtpInterface;
47using GetMtpImplFunc = void*(*)();
48
49constexpr uint32_t UDC_NAME_MAX_LEN = 32;
50constexpr int32_t WAIT_UDC_MAX_LOOP = 30;
51constexpr uint32_t WAIT_UDC_TIME = 100000;
52constexpr int32_t WRITE_UDC_MAX_RETRY = 5;
53/* mtp and ptp use same driver and same service */
54static std::string MTP_PTP_SERVICE_NAME {"usbfn_mtp_interface_service"};
55#define UDC_PATH "/config/usb_gadget/g1/UDC"
56
57static void *g_libHandle = nullptr;
58static GetMtpImplFunc g_getMtpImpl = nullptr;
59
60static void InitGetMtpImpl()
61{
62    if (g_getMtpImpl != nullptr) {
63        return;
64    }
65
66    g_libHandle = dlopen("libusbfn_mtp_interface_service_1.0.z.so", RTLD_LAZY);
67    if (g_libHandle == nullptr) {
68        HDF_LOGE("%{public}s dlopen failed: %{public}s", __func__, dlerror());
69        return;
70    }
71
72    void *funcPtr = dlsym(g_libHandle, "UsbfnMtpInterfaceImplGetInstance");
73    if (funcPtr == nullptr) {
74        HDF_LOGE("%{public}s dlsym failed: %{public}s", __func__, dlerror());
75        dlclose(g_libHandle);
76        g_libHandle = nullptr;
77        return;
78    }
79
80    g_getMtpImpl = reinterpret_cast<GetMtpImplFunc>(funcPtr);
81}
82
83static void ReleaseGetMtpImpl()
84{
85    g_getMtpImpl = nullptr;
86    if (g_libHandle != nullptr) {
87        dlclose(g_libHandle);
88        g_libHandle = nullptr;
89    }
90}
91
92static IUsbfnMtpInterface *GetUsbfnMtpImpl()
93{
94    InitGetMtpImpl();
95    if (g_getMtpImpl == nullptr) {
96        return nullptr;
97    }
98
99    void *instance = g_getMtpImpl();
100    if (instance != nullptr) {
101        return reinterpret_cast<IUsbfnMtpInterface *>(instance);
102    }
103    return nullptr;
104}
105
106int32_t UsbdFunction::SendCmdToService(const char *name, int32_t cmd, unsigned char funcMask)
107{
108    auto servMgr = IServiceManager::Get();
109    if (servMgr == nullptr) {
110        HDF_LOGE("%{public}s: get IServiceManager failed", __func__);
111        return HDF_FAILURE;
112    }
113
114    sptr<IRemoteObject> remote = servMgr->GetService(name);
115    if (remote == nullptr) {
116        HDF_LOGE("%{public}s: get remote object failed: %{public}s", __func__, name);
117        return HDF_FAILURE;
118    }
119
120    OHOS::MessageParcel data;
121    OHOS::MessageParcel reply;
122    OHOS::MessageOption option;
123
124    if (!data.WriteInterfaceToken(Str8ToStr16(HDF_USB_USBFN_DESC))) {
125        HDF_LOGE("%{public}s: WriteInterfaceToken failed", __func__);
126        return HDF_FAILURE;
127    }
128
129    if (!data.WriteUint8(funcMask)) {
130        HDF_LOGE("%{public}s: WriteInt8 failed: %{public}d", __func__, funcMask);
131        return HDF_FAILURE;
132    }
133
134    int32_t ret = remote->SendRequest(cmd, data, reply, option);
135    if (ret != HDF_SUCCESS) {
136        HDF_LOGE("%{public}s: send request to %{public}s failed, ret=%{public}d", __func__, name, ret);
137        return ret;
138    }
139    return HDF_SUCCESS;
140}
141
142int32_t UsbdFunction::InitMtp()
143{
144    int32_t ret = UsbdRegisterDevice(MTP_PTP_SERVICE_NAME);
145    if (ret != HDF_SUCCESS) {
146        HDF_LOGE("%{public}s: register mtp device failed: %{public}d", __func__, ret);
147        return ret;
148    }
149    auto serviceImpl = GetUsbfnMtpImpl();
150    if (serviceImpl == nullptr) {
151        HDF_LOGE("%{public}s: failed to get of implement service", __func__);
152        return HDF_FAILURE;
153    }
154    ret = serviceImpl->Init();
155    if (ret != HDF_SUCCESS) {
156        UsbdUnregisterDevice(MTP_PTP_SERVICE_NAME);
157        HDF_LOGE("%{public}s: init mtp device failed: %{public}d", __func__, ret);
158    }
159    HDF_LOGI("%{public}s: start Init done", __func__);
160    return ret;
161}
162
163int32_t UsbdFunction::ReleaseMtp()
164{
165    auto serviceImpl = GetUsbfnMtpImpl();
166    if (serviceImpl == nullptr) {
167        HDF_LOGE("%{public}s: failed to get of implement service", __func__);
168        return HDF_FAILURE;
169    }
170    int32_t ret = serviceImpl->Release();
171    if (ret != HDF_SUCCESS) {
172        HDF_LOGE("%{public}s: release mtp device failed: %{public}d", __func__, ret);
173    }
174    ReleaseGetMtpImpl();
175
176    UsbdUnregisterDevice(MTP_PTP_SERVICE_NAME);
177    HDF_LOGI("%{public}s: release Mtp done", __func__);
178    return ret;
179}
180
181int32_t UsbdFunction::RemoveHdc()
182{
183    int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_OFF);
184    if (status != 0) {
185        HDF_LOGE("%{public}s:remove hdc config error = %{public}d", __func__, status);
186        return HDF_FAILURE;
187    }
188    return HDF_SUCCESS;
189}
190
191int32_t UsbdFunction::AddHdc()
192{
193    int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_ON);
194    if (status != 0) {
195        HDF_LOGE("%{public}s:add hdc config error = %{public}d", __func__, status);
196        return HDF_FAILURE;
197    }
198
199    status = SetParameter(PERSIST_SYS_USB_CONFIG, HDC_CONFIG_ON);
200    if (status != 0) {
201        HDF_LOGE("%{public}s:add hdc persist config error = %{public}d", __func__, status);
202        return HDF_FAILURE;
203    }
204    return HDF_SUCCESS;
205}
206
207int32_t UsbdFunction::SetFunctionToRndis()
208{
209    int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_RNDIS);
210    if (status != 0) {
211        HDF_LOGE("%{public}s:add rndis config error = %{public}d", __func__, status);
212        return HDF_FAILURE;
213    }
214    return HDF_SUCCESS;
215}
216
217int32_t UsbdFunction::SetFunctionToStorage()
218{
219    int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_STORAGE);
220    if (status != 0) {
221        HDF_LOGE("%{public}s:add storage config error = %{public}d", __func__, status);
222        return HDF_FAILURE;
223    }
224
225    status = SetParameter(PERSIST_SYS_USB_CONFIG, HDC_CONFIG_STORAGE);
226    if (status != 0) {
227        HDF_LOGE("%{public}s:add storage persist config error = %{public}d", __func__, status);
228        return HDF_FAILURE;
229    }
230    return HDF_SUCCESS;
231}
232
233int32_t UsbdFunction::SetFunctionToRndisHdc()
234{
235    int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_RNDIS_HDC);
236    if (status != 0) {
237        HDF_LOGE("%{public}s:add rndis hdc config error = %{public}d", __func__, status);
238        return HDF_FAILURE;
239    }
240    return HDF_SUCCESS;
241}
242
243int32_t UsbdFunction::SetFunctionToManufactureHdc()
244{
245    int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_MANUFACTURE_HDC);
246    if (status != 0) {
247        HDF_LOGE("%{public}s:add manufacture hdc config error = %{public}d", __func__, status);
248        return HDF_FAILURE;
249    }
250    return HDF_SUCCESS;
251}
252
253int32_t UsbdFunction::SetFunctionToStorageHdc()
254{
255    int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_STORAGE_HDC);
256    if (status != 0) {
257        HDF_LOGE("%{public}s:add storage hdc config error = %{public}d", __func__, status);
258        return HDF_FAILURE;
259    }
260    return HDF_SUCCESS;
261}
262
263int32_t UsbdFunction::SetFunctionToNone()
264{
265    uint32_t ddkFuns = currentFuncs_ & USB_DDK_FUNCTION_SUPPORT;
266    if (ddkFuns > 0) {
267        if ((ddkFuns & USB_FUNCTION_ACM) != 0) {
268            UsbdFunction::SendCmdToService(ACM_SERVICE_NAME, ACM_RELEASE, USB_FUNCTION_ACM);
269            UsbdUnregisterDevice(std::string(ACM_SERVICE_NAME));
270        }
271        if ((ddkFuns & USB_FUNCTION_ECM) != 0) {
272            UsbdFunction::SendCmdToService(ECM_SERVICE_NAME, ECM_RELEASE, USB_FUNCTION_ECM);
273            UsbdUnregisterDevice(std::string(ECM_SERVICE_NAME));
274        }
275        if ((ddkFuns & USB_FUNCTION_MTP) != 0 || (ddkFuns & USB_FUNCTION_PTP) != 0) {
276            if (ReleaseMtp() != HDF_SUCCESS) {
277                HDF_LOGE("%{public}s: release mtp failed", __func__);
278            }
279        }
280    }
281    UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT);
282    UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME));
283    int32_t ret = RemoveHdc();
284    if (ret != HDF_SUCCESS) {
285        HDF_LOGE("%{public}s: RemoveHdc error, ret = %{public}d", __func__, ret);
286        return ret;
287    }
288
289    ret = UsbdWaitToNone();
290    if (ret != HDF_SUCCESS) {
291        HDF_LOGE("%{public}s: UsbdWaitToNone error, ret = %{public}d", __func__, ret);
292        return ret;
293    }
294    currentFuncs_ = USB_FUNCTION_NONE;
295    return ret;
296}
297
298int32_t UsbdFunction::SetDDKFunction(uint32_t funcs)
299{
300    HDF_LOGD("%{public}s: SetDDKFunction funcs=%{public}d", __func__, funcs);
301    uint32_t ddkFuns = static_cast<uint32_t>(funcs) & USB_DDK_FUNCTION_SUPPORT;
302    if (ddkFuns == 0) {
303        HDF_LOGE("%{public}s: not use ddkfunction", __func__);
304        return HDF_SUCCESS;
305    }
306    int32_t ret = UsbdRegisterDevice(std::string(DEV_SERVICE_NAME));
307    if (ret != HDF_SUCCESS) {
308        HDF_LOGE("%{public}s: failed to register device", __func__);
309        return ret;
310    }
311    if (UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_ADD, ddkFuns)) {
312        HDF_LOGE("%{public}s: create dev error: %{public}d", __func__, ddkFuns);
313        return HDF_FAILURE;
314    }
315    return HDF_SUCCESS;
316}
317
318int32_t UsbdFunction::UsbdWriteUdc(char* udcName, size_t len)
319{
320    FILE *fpWrite = fopen(UDC_PATH, "w");
321    if (fpWrite == NULL) {
322        HDF_LOGE("%{public}s: fopen failed", __func__);
323        return HDF_ERR_BAD_FD;
324    }
325
326    size_t count = fwrite(udcName, len, 1, fpWrite);
327    if (count != 1) {
328        HDF_LOGE("%{public}s: fwrite failed, errno: %{public}d", __func__, errno);
329        (void)fclose(fpWrite);
330        return HDF_FAILURE;
331    }
332
333    if (ferror(fpWrite)) {
334        HDF_LOGW("%{public}s: fwrite failed, errno: %{public}d", __func__, errno);
335    }
336    if (fclose(fpWrite) == EOF) {
337        HDF_LOGE("%{public}s: flcose failed, errno: %{public}d", __func__, errno);
338        return HDF_FAILURE;
339    }
340    return HDF_SUCCESS;
341}
342int32_t UsbdFunction::UsbdReadUdc(char* udcName, size_t len)
343{
344    FILE *fpRead = fopen(UDC_PATH, "r");
345    if (fpRead == NULL) {
346        HDF_LOGE("%{public}s: fopen failed", __func__);
347        return HDF_ERR_BAD_FD;
348    }
349
350    size_t count = fread(udcName, len, 1, fpRead);
351    if (count != 1) {
352        if (feof(fpRead)) {
353            HDF_LOGI("%{public}s: fread end of file reached.", __func__);
354        } else if (ferror(fpRead)) {
355            HDF_LOGE("%{public}s: fread failed, errno: %{public}d", __func__, errno);
356        } else {
357            HDF_LOGW("%{public}s: fread len than expected", __func__);
358        }
359        (void)fclose(fpRead);
360        return HDF_FAILURE;
361    }
362
363    if (fclose(fpRead) == EOF) {
364        HDF_LOGW("%{public}s: flcose failed, errno: %{public}d", __func__, errno);
365    }
366    return HDF_SUCCESS;
367}
368
369int32_t UsbdFunction::UsbdEnableDevice(int32_t funcs)
370{
371    // get udc name
372    char udcName[UDC_NAME_MAX_LEN] = {0};
373    int32_t ret = GetParameter("sys.usb.controller", "invalid", udcName, UDC_NAME_MAX_LEN);
374    if (ret <= 0) {
375        HDF_LOGE("%{public}s: GetParameter failed", __func__);
376        return HDF_FAILURE;
377    }
378
379    char tmpName[UDC_NAME_MAX_LEN] = {0};
380    for (int32_t i = 0; i < WRITE_UDC_MAX_RETRY; i++) {
381        if (i != 0 && ret != HDF_SUCCESS) {
382            ret = SetDDKFunction(funcs);
383            if (ret != HDF_SUCCESS) {
384                UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT);
385                UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME));
386                usleep(WAIT_UDC_TIME);
387                continue;
388            }
389        }
390        ret = UsbdWriteUdc(udcName, strlen(udcName));
391        if (ret != HDF_SUCCESS) {
392            UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT);
393            UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME));
394            usleep(WAIT_UDC_TIME);
395            continue;
396        }
397
398        (void)memset_s(tmpName, UDC_NAME_MAX_LEN, 0, UDC_NAME_MAX_LEN);
399        ret = UsbdReadUdc(tmpName, strlen(udcName));
400        if (ret != HDF_SUCCESS) {
401            UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT);
402            UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME));
403            usleep(WAIT_UDC_TIME);
404            continue;
405        }
406
407        if (strcmp(udcName, tmpName) == 0) {
408            return HDF_SUCCESS;
409        }
410        HDF_LOGI("%{public}s:  tmpName: %{public}s", __func__, tmpName);
411        usleep(WAIT_UDC_TIME);
412    }
413
414    if (strcmp(udcName, tmpName) != 0) {
415        HDF_LOGE("%{public}s: strcmp failed", __func__);
416        return HDF_FAILURE;
417    }
418    return HDF_SUCCESS;
419}
420
421int32_t UsbdFunction::UsbdWaitUdc()
422{
423    // get udc name
424    char udcName[UDC_NAME_MAX_LEN] = {0};
425    int32_t ret = GetParameter("sys.usb.controller", "invalid", udcName, UDC_NAME_MAX_LEN - 1);
426    if (ret <= 0) {
427        HDF_LOGE("%{public}s: GetParameter failed", __func__);
428        return HDF_FAILURE;
429    }
430
431    char tmpName[UDC_NAME_MAX_LEN] = {0};
432    for (int32_t i = 0; i < WAIT_UDC_MAX_LOOP; i++) {
433        (void)memset_s(tmpName, UDC_NAME_MAX_LEN, 0, UDC_NAME_MAX_LEN);
434        ret = UsbdReadUdc(tmpName, strlen(udcName));
435        if (ret != HDF_SUCCESS) {
436            usleep(WAIT_UDC_TIME);
437            continue;
438        }
439
440        if (strcmp(udcName, tmpName) == 0) {
441            return HDF_SUCCESS;
442        }
443        HDF_LOGE("%{public}s: read UDC_PATH: %{public}s", __func__, tmpName);
444        usleep(WAIT_UDC_TIME);
445    }
446
447    if (strcmp(udcName, tmpName) != 0) {
448        HDF_LOGE("%{public}s: strcmp failed", __func__);
449        return HDF_FAILURE;
450    }
451
452    return HDF_SUCCESS;
453}
454
455int32_t UsbdFunction::UsbdWaitToNone()
456{
457    char stateName[UDC_NAME_MAX_LEN] = {0};
458    for (int32_t i = 0; i < WAIT_UDC_MAX_LOOP; i++) {
459        (void)memset_s(stateName, UDC_NAME_MAX_LEN, 0, UDC_NAME_MAX_LEN);
460        int32_t ret = GetParameter(SYS_USB_STATE, "invalid", stateName, UDC_NAME_MAX_LEN - 1);
461        if (ret <= 0) {
462            HDF_LOGE("%{public}s: GetParameter failed", __func__);
463            return HDF_FAILURE;
464        }
465        if (strcmp(stateName, HDC_CONFIG_OFF) == 0) {
466            return HDF_SUCCESS;
467        }
468        usleep(WAIT_UDC_TIME);
469    }
470
471    if (strcmp(stateName, HDC_CONFIG_OFF) != 0) {
472        HDF_LOGE("%{public}s: strcmp failed", __func__);
473        return HDF_FAILURE;
474    }
475
476    return HDF_SUCCESS;
477}
478
479int32_t UsbdFunction::UsbdInitDDKFunction(uint32_t funcs)
480{
481    int32_t ret;
482    if ((funcs & USB_FUNCTION_ACM) != 0) {
483        ret = UsbdRegisterDevice(std::string(ACM_SERVICE_NAME));
484        if (ret != HDF_SUCCESS) {
485            HDF_LOGE("%{public}s: failed to register device", __func__);
486            return HDF_FAILURE;
487        }
488        if (SendCmdToService(ACM_SERVICE_NAME, ACM_INIT, USB_FUNCTION_ACM) != 0) {
489            UsbdUnregisterDevice(std::string(ACM_SERVICE_NAME));
490            HDF_LOGE("%{public}s: acm init error", __func__);
491            return HDF_FAILURE;
492        }
493        currentFuncs_ |= USB_FUNCTION_ACM;
494    }
495    if ((funcs & USB_FUNCTION_ECM) != 0) {
496        ret = UsbdRegisterDevice(std::string(ECM_SERVICE_NAME));
497        if (ret != HDF_SUCCESS) {
498            HDF_LOGE("%{public}s: failed to register device", __func__);
499            return HDF_FAILURE;
500        }
501        if (SendCmdToService(ECM_SERVICE_NAME, ECM_INIT, USB_FUNCTION_ECM) != 0) {
502            UsbdUnregisterDevice(std::string(ECM_SERVICE_NAME));
503            HDF_LOGE("%{public}s: ecm init error", __func__);
504            return HDF_FAILURE;
505        }
506        currentFuncs_ |= USB_FUNCTION_ACM;
507    }
508    if ((funcs & USB_FUNCTION_MTP) != 0 || (funcs & USB_FUNCTION_PTP) != 0) {
509        ret = InitMtp();
510        if (ret != HDF_SUCCESS) {
511            HDF_LOGE("%{public}s: failed to init mtp", __func__);
512            return HDF_FAILURE;
513        }
514    }
515    return HDF_SUCCESS;
516}
517
518int32_t UsbdFunction::UsbdSetKernelFunction(int32_t kfuns, int32_t funcs)
519{
520    switch (kfuns) {
521        case USB_FUNCTION_HDC:
522            HDF_LOGI("%{public}s: set hdc", __func__);
523            return UsbdFunction::AddHdc();
524        case USB_FUNCTION_RNDIS:
525            HDF_LOGI("%{public}s: set rndis", __func__);
526            return UsbdFunction::SetFunctionToRndis();
527        case USB_FUNCTION_STORAGE:
528            HDF_LOGI("%{public}s: set mass_storage", __func__);
529            return UsbdFunction::SetFunctionToStorage();
530        case USB_FUNCTION_RNDIS | USB_FUNCTION_HDC:
531            HDF_LOGI("%{public}s: set rndis hdc", __func__);
532            return UsbdFunction::SetFunctionToRndisHdc();
533        case USB_FUNCTION_STORAGE | USB_FUNCTION_HDC:
534            HDF_LOGI("%{public}s: set storage hdc", __func__);
535            return UsbdFunction::SetFunctionToStorageHdc();
536        case USB_FUNCTION_MANUFACTURE | USB_FUNCTION_HDC:
537            HDF_LOGI("%{public}s: set manufacture hdc", __func__);
538            return UsbdFunction::SetFunctionToManufactureHdc();
539        default:
540            HDF_LOGI("%{public}s: enable device", __func__);
541            return UsbdEnableDevice(funcs);
542    }
543}
544
545int32_t UsbdFunction::UsbdSetFunction(uint32_t funcs)
546{
547    HDF_LOGI("%{public}s: UsbdSetFunction funcs=%{public}d", __func__, funcs);
548    if ((funcs | USB_FUNCTION_SUPPORT) != USB_FUNCTION_SUPPORT) {
549        HDF_LOGE("%{public}s: funcs invalid", __func__);
550        return HDF_FAILURE;
551    }
552
553    uint32_t kfuns = static_cast<uint32_t>(funcs) & (~USB_DDK_FUNCTION_SUPPORT);
554    if (UsbdFunction::SetFunctionToNone()) {
555        HDF_LOGW("%{public}s: setFunctionToNone error", __func__);
556    }
557
558    if (funcs == USB_FUNCTION_NONE) {
559        HDF_LOGW("%{public}s: setFunctionToNone", __func__);
560        return HDF_SUCCESS;
561    }
562
563    if (UsbdFunction::SetDDKFunction(funcs)) {
564        HDF_LOGE("%{public}s:SetDDKFunction error", __func__);
565        return HDF_FAILURE;
566    }
567
568    int32_t ret = UsbdSetKernelFunction(kfuns, funcs);
569    if (ret != HDF_SUCCESS) {
570        HDF_LOGE("%{public}s, set kernel func failed", __func__);
571        return HDF_FAILURE;
572    }
573    currentFuncs_ |= kfuns;
574    if (funcs == USB_FUNCTION_NONE) {
575        HDF_LOGI("%{public}s, none function", __func__);
576        return HDF_SUCCESS;
577    }
578
579    if (UsbdWaitUdc() != HDF_SUCCESS) {
580        HDF_LOGE("%{public}s, wait udc failed", __func__);
581        return HDF_FAILURE;
582    }
583    if (UsbdInitDDKFunction(funcs) != HDF_SUCCESS) {
584        HDF_LOGE("%{public}s, init ddk func failed", __func__);
585        UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT);
586        UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME));
587        return HDF_FAILURE;
588    }
589    currentFuncs_ = funcs;
590    return HDF_SUCCESS;
591}
592
593int32_t UsbdFunction::UsbdGetFunction(void)
594{
595    return currentFuncs_;
596}
597
598int32_t UsbdFunction::UsbdUpdateFunction(uint32_t funcs)
599{
600    if ((funcs | USB_FUNCTION_SUPPORT) != USB_FUNCTION_SUPPORT && funcs != (USB_FUNCTION_HDC + USB_FUNCTION_RNDIS) &&
601        funcs != (USB_FUNCTION_HDC + USB_FUNCTION_STORAGE)) {
602        HDF_LOGE("%{public}s: funcs invalid funcs is: %{public}d", __func__, funcs);
603        return HDF_FAILURE;
604    }
605    currentFuncs_ = funcs;
606    return HDF_SUCCESS;
607}
608
609int32_t UsbdFunction::UsbdRegisterDevice(const std::string &serviceName)
610{
611    int32_t ret;
612    OHOS::sptr<IDeviceManager> devMgr = IDeviceManager::Get();
613    if (devMgr == nullptr) {
614        HDF_LOGE("%{public}s: get IDeviceManager failed", __func__);
615        return HDF_FAILURE;
616    }
617    ret = devMgr->LoadDevice(serviceName);
618    if (ret != HDF_SUCCESS) {
619        HDF_LOGE("%{public}s, load %{public}s failed", __func__, serviceName.c_str());
620        return ret;
621    }
622    return ret;
623}
624
625void UsbdFunction::UsbdUnregisterDevice(const std::string &serviceName)
626{
627    int32_t ret;
628    OHOS::sptr<IDeviceManager> devMgr = IDeviceManager::Get();
629    if (devMgr == nullptr) {
630        HDF_LOGE("%{public}s: get devMgr object failed", __func__);
631        return;
632    }
633    ret = devMgr->UnloadDevice(serviceName);
634    if (ret != HDF_SUCCESS) {
635        HDF_LOGW("%{public}s, %{public}s unload  failed", __func__, serviceName.c_str());
636    }
637}
638} // namespace V1_0
639} // namespace Usb
640} // namespace HDI
641} // namespace OHOS
642