• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
38 namespace OHOS {
39 namespace HDI {
40 namespace Usb {
41 namespace V1_2 {
42 uint32_t UsbdFunction::currentFuncs_ = USB_FUNCTION_HDC;
43 
44 using OHOS::HDI::DeviceManager::V1_0::IDeviceManager;
45 using OHOS::HDI::ServiceManager::V1_0::IServiceManager;
46 using OHOS::HDI::Usb::Gadget::Mtp::V1_0::IUsbfnMtpInterface;
47 using GetMtpImplFunc = void*(*)();
48 
49 constexpr uint32_t UDC_NAME_MAX_LEN = 32;
50 constexpr int32_t WAIT_UDC_MAX_LOOP = 30;
51 constexpr uint32_t WAIT_UDC_TIME = 100000;
52 constexpr int32_t WRITE_UDC_MAX_RETRY = 5;
53 /* mtp and ptp use same driver and same service */
54 static std::string MTP_PTP_SERVICE_NAME {"usbfn_mtp_interface_service"};
55 #define UDC_PATH "/config/usb_gadget/g1/UDC"
56 
57 static void *g_libHandle = nullptr;
58 static GetMtpImplFunc g_getMtpImpl = nullptr;
59 
InitGetMtpImpl()60 static 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 
ReleaseGetMtpImpl()83 static void ReleaseGetMtpImpl()
84 {
85     g_getMtpImpl = nullptr;
86     if (g_libHandle != nullptr) {
87         dlclose(g_libHandle);
88         g_libHandle = nullptr;
89     }
90 }
91 
GetUsbfnMtpImpl()92 static 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 
SendCmdToService(const char * name,int32_t cmd,unsigned char funcMask)106 int32_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 
InitMtp()142 int32_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 
ReleaseMtp()163 int32_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 
RemoveHdc()181 int32_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 
AddHdc()191 int32_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 
SetFunctionToRndis()207 int32_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 
SetFunctionToStorage()217 int32_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 
SetFunctionToRndisHdc()233 int32_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 
SetFunctionToManufactureHdc()243 int32_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 
SetFunctionToStorageHdc()253 int32_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 
SetFunctionToUsbAccessory()263 int32_t UsbdFunction::SetFunctionToUsbAccessory()
264 {
265     HDF_LOGD("%{public}s enter", __func__);
266     int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_AOA);
267     if (status != 0) {
268         HDF_LOGE("%{public}s:add aoa config error = %{public}d", __func__, status);
269         return HDF_FAILURE;
270     }
271     return HDF_SUCCESS;
272 }
273 
SetFunctionToNcm()274 int32_t UsbdFunction::SetFunctionToNcm()
275 {
276     HDF_LOGD("%{public}s enter", __func__);
277     int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_NCM);
278     if (status != 0) {
279         HDF_LOGE("%{public}s:add ncm config error = %{public}d", __func__, status);
280         return HDF_FAILURE;
281     }
282     return HDF_SUCCESS;
283 }
284 
SetFunctionToNcmHdc()285 int32_t UsbdFunction::SetFunctionToNcmHdc()
286 {
287     HDF_LOGD("%{public}s enter", __func__);
288     int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_NCM_HDC);
289     if (status != 0) {
290         HDF_LOGE("%{public}s:add ncm hdc config error = %{public}d", __func__, status);
291         return HDF_FAILURE;
292     }
293     return HDF_SUCCESS;
294 }
295 
SetFunctionToNone()296 int32_t UsbdFunction::SetFunctionToNone()
297 {
298     uint32_t ddkFuns = currentFuncs_ & USB_DDK_FUNCTION_SUPPORT;
299     if (ddkFuns > 0) {
300         if ((ddkFuns & USB_FUNCTION_ACM) != 0) {
301             UsbdFunction::SendCmdToService(ACM_SERVICE_NAME, ACM_RELEASE, USB_FUNCTION_ACM);
302             UsbdUnregisterDevice(std::string(ACM_SERVICE_NAME));
303         }
304         if ((ddkFuns & USB_FUNCTION_ECM) != 0) {
305             UsbdFunction::SendCmdToService(ECM_SERVICE_NAME, ECM_RELEASE, USB_FUNCTION_ECM);
306             UsbdUnregisterDevice(std::string(ECM_SERVICE_NAME));
307         }
308         if ((ddkFuns & USB_FUNCTION_MTP) != 0 || (ddkFuns & USB_FUNCTION_PTP) != 0) {
309             if (ReleaseMtp() != HDF_SUCCESS) {
310                 HDF_LOGE("%{public}s: release mtp failed", __func__);
311             }
312         }
313     }
314     UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT);
315     UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME));
316     int32_t ret = RemoveHdc();
317     if (ret != HDF_SUCCESS) {
318         HDF_LOGE("%{public}s: RemoveHdc error, ret = %{public}d", __func__, ret);
319         return ret;
320     }
321 
322     ret = UsbdWaitToNone();
323     if (ret != HDF_SUCCESS) {
324         HDF_LOGE("%{public}s: UsbdWaitToNone error, ret = %{public}d", __func__, ret);
325         return ret;
326     }
327     currentFuncs_ = USB_FUNCTION_NONE;
328     return ret;
329 }
330 
SetDDKFunction(uint32_t funcs)331 int32_t UsbdFunction::SetDDKFunction(uint32_t funcs)
332 {
333     HDF_LOGD("%{public}s: SetDDKFunction funcs=%{public}d", __func__, funcs);
334     uint32_t ddkFuns = static_cast<uint32_t>(funcs) & USB_DDK_FUNCTION_SUPPORT;
335     if (ddkFuns == 0) {
336         HDF_LOGE("%{public}s: not use ddkfunction", __func__);
337         return HDF_SUCCESS;
338     }
339     int32_t ret = UsbdRegisterDevice(std::string(DEV_SERVICE_NAME));
340     if (ret != HDF_SUCCESS) {
341         HDF_LOGE("%{public}s: failed to register device", __func__);
342         return ret;
343     }
344     if (UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_ADD, ddkFuns)) {
345         HDF_LOGE("%{public}s: create dev error: %{public}d", __func__, ddkFuns);
346         return HDF_FAILURE;
347     }
348     return HDF_SUCCESS;
349 }
350 
UsbdWriteUdc(char * udcName,size_t len)351 int32_t UsbdFunction::UsbdWriteUdc(char* udcName, size_t len)
352 {
353     FILE *fpWrite = fopen(UDC_PATH, "w");
354     if (fpWrite == NULL) {
355         HDF_LOGE("%{public}s: fopen failed", __func__);
356         return HDF_ERR_BAD_FD;
357     }
358 
359     size_t count = fwrite(udcName, len, 1, fpWrite);
360     if (count != 1) {
361         HDF_LOGE("%{public}s: fwrite failed, errno: %{public}d", __func__, errno);
362         (void)fclose(fpWrite);
363         return HDF_FAILURE;
364     }
365 
366     if (ferror(fpWrite)) {
367         HDF_LOGW("%{public}s: fwrite failed, errno: %{public}d", __func__, errno);
368     }
369     if (fclose(fpWrite) == EOF) {
370         HDF_LOGE("%{public}s: flcose failed, errno: %{public}d", __func__, errno);
371         return HDF_FAILURE;
372     }
373     return HDF_SUCCESS;
374 }
UsbdReadUdc(char * udcName,size_t len)375 int32_t UsbdFunction::UsbdReadUdc(char* udcName, size_t len)
376 {
377     FILE *fpRead = fopen(UDC_PATH, "r");
378     if (fpRead == NULL) {
379         HDF_LOGE("%{public}s: fopen failed", __func__);
380         return HDF_ERR_BAD_FD;
381     }
382 
383     size_t count = fread(udcName, len, 1, fpRead);
384     if (count != 1) {
385         if (feof(fpRead)) {
386             HDF_LOGI("%{public}s: fread end of file reached.", __func__);
387         } else if (ferror(fpRead)) {
388             HDF_LOGE("%{public}s: fread failed, errno: %{public}d", __func__, errno);
389         } else {
390             HDF_LOGW("%{public}s: fread len than expected", __func__);
391         }
392         (void)fclose(fpRead);
393         return HDF_FAILURE;
394     }
395 
396     if (fclose(fpRead) == EOF) {
397         HDF_LOGW("%{public}s: flcose failed, errno: %{public}d", __func__, errno);
398     }
399     return HDF_SUCCESS;
400 }
401 
UsbdEnableDevice(int32_t funcs)402 int32_t UsbdFunction::UsbdEnableDevice(int32_t funcs)
403 {
404     // get udc name
405     char udcName[UDC_NAME_MAX_LEN] = {0};
406     int32_t ret = GetParameter("sys.usb.controller", "invalid", udcName, UDC_NAME_MAX_LEN);
407     if (ret <= 0) {
408         HDF_LOGE("%{public}s: GetParameter failed", __func__);
409         return HDF_FAILURE;
410     }
411 
412     char tmpName[UDC_NAME_MAX_LEN] = {0};
413     for (int32_t i = 0; i < WRITE_UDC_MAX_RETRY; i++) {
414         if (i != 0 && ret != HDF_SUCCESS) {
415             ret = SetDDKFunction(funcs);
416             if (ret != HDF_SUCCESS) {
417                 UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT);
418                 UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME));
419                 usleep(WAIT_UDC_TIME);
420                 continue;
421             }
422         }
423         ret = UsbdWriteUdc(udcName, strlen(udcName));
424         if (ret != HDF_SUCCESS) {
425             UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT);
426             UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME));
427             usleep(WAIT_UDC_TIME);
428             continue;
429         }
430 
431         (void)memset_s(tmpName, UDC_NAME_MAX_LEN, 0, UDC_NAME_MAX_LEN);
432         ret = UsbdReadUdc(tmpName, strlen(udcName));
433         if (ret != HDF_SUCCESS) {
434             UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT);
435             UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME));
436             usleep(WAIT_UDC_TIME);
437             continue;
438         }
439 
440         if (strcmp(udcName, tmpName) == 0) {
441             return HDF_SUCCESS;
442         }
443         HDF_LOGI("%{public}s:  tmpName: %{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     return HDF_SUCCESS;
452 }
453 
UsbdWaitUdc()454 int32_t UsbdFunction::UsbdWaitUdc()
455 {
456     // get udc name
457     char udcName[UDC_NAME_MAX_LEN] = {0};
458     int32_t ret = GetParameter("sys.usb.controller", "invalid", udcName, UDC_NAME_MAX_LEN - 1);
459     if (ret <= 0) {
460         HDF_LOGE("%{public}s: GetParameter failed", __func__);
461         return HDF_FAILURE;
462     }
463 
464     char tmpName[UDC_NAME_MAX_LEN] = {0};
465     for (int32_t i = 0; i < WAIT_UDC_MAX_LOOP; i++) {
466         (void)memset_s(tmpName, UDC_NAME_MAX_LEN, 0, UDC_NAME_MAX_LEN);
467         ret = UsbdReadUdc(tmpName, strlen(udcName));
468         if (ret != HDF_SUCCESS) {
469             usleep(WAIT_UDC_TIME);
470             continue;
471         }
472 
473         if (strcmp(udcName, tmpName) == 0) {
474             return HDF_SUCCESS;
475         }
476         HDF_LOGE("%{public}s: read UDC_PATH: %{public}s", __func__, tmpName);
477         usleep(WAIT_UDC_TIME);
478     }
479 
480     if (strcmp(udcName, tmpName) != 0) {
481         HDF_LOGE("%{public}s: strcmp failed", __func__);
482         return HDF_FAILURE;
483     }
484 
485     return HDF_SUCCESS;
486 }
487 
UsbdWaitToNone()488 int32_t UsbdFunction::UsbdWaitToNone()
489 {
490     char stateName[UDC_NAME_MAX_LEN] = {0};
491     for (int32_t i = 0; i < WAIT_UDC_MAX_LOOP; i++) {
492         (void)memset_s(stateName, UDC_NAME_MAX_LEN, 0, UDC_NAME_MAX_LEN);
493         int32_t ret = GetParameter(SYS_USB_STATE, "invalid", stateName, UDC_NAME_MAX_LEN - 1);
494         if (ret <= 0) {
495             HDF_LOGE("%{public}s: GetParameter failed", __func__);
496             return HDF_FAILURE;
497         }
498         if (strcmp(stateName, HDC_CONFIG_OFF) == 0) {
499             return HDF_SUCCESS;
500         }
501         usleep(WAIT_UDC_TIME);
502     }
503 
504     if (strcmp(stateName, HDC_CONFIG_OFF) != 0) {
505         HDF_LOGE("%{public}s: strcmp failed", __func__);
506         return HDF_FAILURE;
507     }
508 
509     return HDF_SUCCESS;
510 }
511 
UsbdInitDDKFunction(uint32_t funcs)512 int32_t UsbdFunction::UsbdInitDDKFunction(uint32_t funcs)
513 {
514     int32_t ret;
515     if ((funcs & USB_FUNCTION_ACM) != 0) {
516         ret = UsbdRegisterDevice(std::string(ACM_SERVICE_NAME));
517         if (ret != HDF_SUCCESS) {
518             HDF_LOGE("%{public}s: failed to register device", __func__);
519             return HDF_FAILURE;
520         }
521         if (SendCmdToService(ACM_SERVICE_NAME, ACM_INIT, USB_FUNCTION_ACM) != 0) {
522             UsbdUnregisterDevice(std::string(ACM_SERVICE_NAME));
523             HDF_LOGE("%{public}s: acm init error", __func__);
524             return HDF_FAILURE;
525         }
526         currentFuncs_ |= USB_FUNCTION_ACM;
527     }
528     if ((funcs & USB_FUNCTION_ECM) != 0) {
529         ret = UsbdRegisterDevice(std::string(ECM_SERVICE_NAME));
530         if (ret != HDF_SUCCESS) {
531             HDF_LOGE("%{public}s: failed to register device", __func__);
532             return HDF_FAILURE;
533         }
534         if (SendCmdToService(ECM_SERVICE_NAME, ECM_INIT, USB_FUNCTION_ECM) != 0) {
535             UsbdUnregisterDevice(std::string(ECM_SERVICE_NAME));
536             HDF_LOGE("%{public}s: ecm init error", __func__);
537             return HDF_FAILURE;
538         }
539         currentFuncs_ |= USB_FUNCTION_ACM;
540     }
541     if ((funcs & USB_FUNCTION_MTP) != 0 || (funcs & USB_FUNCTION_PTP) != 0) {
542         ret = InitMtp();
543         if (ret != HDF_SUCCESS) {
544             HDF_LOGE("%{public}s: failed to init mtp", __func__);
545             return HDF_FAILURE;
546         }
547     }
548     return HDF_SUCCESS;
549 }
550 
UsbdSetKernelFunction(int32_t kfuns,int32_t funcs)551 int32_t UsbdFunction::UsbdSetKernelFunction(int32_t kfuns, int32_t funcs)
552 {
553     switch (kfuns) {
554         case USB_FUNCTION_HDC:
555             HDF_LOGI("%{public}s: set hdc", __func__);
556             return UsbdFunction::AddHdc();
557         case USB_FUNCTION_RNDIS:
558             HDF_LOGI("%{public}s: set rndis", __func__);
559             return UsbdFunction::SetFunctionToRndis();
560         case USB_FUNCTION_STORAGE:
561             HDF_LOGI("%{public}s: set mass_storage", __func__);
562             return UsbdFunction::SetFunctionToStorage();
563         case USB_FUNCTION_RNDIS | USB_FUNCTION_HDC:
564             HDF_LOGI("%{public}s: set rndis hdc", __func__);
565             return UsbdFunction::SetFunctionToRndisHdc();
566         case USB_FUNCTION_STORAGE | USB_FUNCTION_HDC:
567             HDF_LOGI("%{public}s: set storage hdc", __func__);
568             return UsbdFunction::SetFunctionToStorageHdc();
569         case USB_FUNCTION_MANUFACTURE | USB_FUNCTION_HDC:
570             HDF_LOGI("%{public}s: set manufacture hdc", __func__);
571             return UsbdFunction::SetFunctionToManufactureHdc();
572         case USB_FUNCTION_ACCESSORY:
573             HDF_LOGI("%{public}s: set usb accessory", __func__);
574             return UsbdFunction::SetFunctionToUsbAccessory();
575         case USB_FUNCTION_NCM:
576             HDF_LOGI("%{public}s: set ncm", __func__);
577             return UsbdFunction::SetFunctionToNcm();
578         case USB_FUNCTION_NCM | USB_FUNCTION_HDC:
579             HDF_LOGI("%{public}s: set ncm hdc", __func__);
580             return UsbdFunction::SetFunctionToNcmHdc();
581         default:
582             HDF_LOGI("%{public}s: enable device", __func__);
583             return UsbdEnableDevice(funcs);
584     }
585 }
586 
UsbdSetFunction(uint32_t funcs)587 int32_t UsbdFunction::UsbdSetFunction(uint32_t funcs)
588 {
589     HDF_LOGI("%{public}s: UsbdSetFunction funcs=%{public}d", __func__, funcs);
590     if ((funcs | USB_FUNCTION_SUPPORT) != USB_FUNCTION_SUPPORT) {
591         HDF_LOGE("%{public}s: funcs invalid", __func__);
592         return HDF_ERR_NOT_SUPPORT;
593     }
594 
595     uint32_t kfuns = static_cast<uint32_t>(funcs) & (~USB_DDK_FUNCTION_SUPPORT);
596     if (UsbdFunction::SetFunctionToNone()) {
597         HDF_LOGW("%{public}s: setFunctionToNone error", __func__);
598     }
599 
600     if (funcs == USB_FUNCTION_NONE) {
601         HDF_LOGW("%{public}s: setFunctionToNone", __func__);
602         return HDF_SUCCESS;
603     }
604 
605     if (UsbdFunction::SetDDKFunction(funcs)) {
606         HDF_LOGE("%{public}s:SetDDKFunction error", __func__);
607         SetFunctionToStorage();
608         return HDF_FAILURE;
609     }
610 
611     int32_t ret = UsbdSetKernelFunction(kfuns, funcs);
612     if (ret != HDF_SUCCESS) {
613         HDF_LOGE("%{public}s, set kernel func failed", __func__);
614         SetFunctionToStorage();
615         return HDF_FAILURE;
616     }
617     currentFuncs_ |= kfuns;
618     if (funcs == USB_FUNCTION_NONE) {
619         HDF_LOGI("%{public}s, none function", __func__);
620         return HDF_SUCCESS;
621     }
622 
623     if (UsbdWaitUdc() != HDF_SUCCESS) {
624         HDF_LOGE("%{public}s, wait udc failed", __func__);
625         SetFunctionToStorage();
626         return HDF_FAILURE;
627     }
628     if (UsbdInitDDKFunction(funcs) != HDF_SUCCESS) {
629         HDF_LOGE("%{public}s, init ddk func failed", __func__);
630         UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT);
631         UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME));
632         SetFunctionToStorage();
633         return HDF_FAILURE;
634     }
635     currentFuncs_ = funcs;
636     return HDF_SUCCESS;
637 }
638 
UsbdGetFunction(void)639 int32_t UsbdFunction::UsbdGetFunction(void)
640 {
641     return currentFuncs_;
642 }
643 
UsbdUpdateFunction(uint32_t funcs)644 int32_t UsbdFunction::UsbdUpdateFunction(uint32_t funcs)
645 {
646     if ((funcs | USB_FUNCTION_SUPPORT) != USB_FUNCTION_SUPPORT && funcs != (USB_FUNCTION_HDC + USB_FUNCTION_RNDIS) &&
647         funcs != (USB_FUNCTION_HDC + USB_FUNCTION_STORAGE)) {
648         HDF_LOGE("%{public}s: funcs invalid funcs is: %{public}d", __func__, funcs);
649         return HDF_FAILURE;
650     }
651     currentFuncs_ = funcs;
652     return HDF_SUCCESS;
653 }
654 
UsbdRegisterDevice(const std::string & serviceName)655 int32_t UsbdFunction::UsbdRegisterDevice(const std::string &serviceName)
656 {
657     int32_t ret;
658     OHOS::sptr<IDeviceManager> devMgr = IDeviceManager::Get();
659     if (devMgr == nullptr) {
660         HDF_LOGE("%{public}s: get IDeviceManager failed", __func__);
661         return HDF_FAILURE;
662     }
663     ret = devMgr->LoadDevice(serviceName);
664     if (ret != HDF_SUCCESS) {
665         HDF_LOGE("%{public}s, load %{public}s failed", __func__, serviceName.c_str());
666         return ret;
667     }
668     return ret;
669 }
670 
UsbdUnregisterDevice(const std::string & serviceName)671 void UsbdFunction::UsbdUnregisterDevice(const std::string &serviceName)
672 {
673     int32_t ret;
674     OHOS::sptr<IDeviceManager> devMgr = IDeviceManager::Get();
675     if (devMgr == nullptr) {
676         HDF_LOGE("%{public}s: get devMgr object failed", __func__);
677         return;
678     }
679     ret = devMgr->UnloadDevice(serviceName);
680     if (ret != HDF_SUCCESS) {
681         HDF_LOGW("%{public}s, %{public}s unload  failed", __func__, serviceName.c_str());
682     }
683 }
684 } // namespace V1_0
685 } // namespace Usb
686 } // namespace HDI
687 } // namespace OHOS
688