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