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