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