• 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         HDF_LOGE("%{public}s: init mtp device failed: %{public}d", __func__, ret);
102     }
103     HDF_LOGI("%{public}s: start Init done", __func__);
104     return ret;
105 }
106 
ReleaseMtp()107 int32_t UsbdFunction::ReleaseMtp()
108 {
109     auto serviceImpl = UsbfnMtpImpl::Get(true);
110     if (serviceImpl == nullptr) {
111         HDF_LOGE("%{public}s: failed to get of implement service", __func__);
112         return HDF_FAILURE;
113     }
114     int32_t ret = serviceImpl->Release();
115     if (ret != HDF_SUCCESS) {
116         HDF_LOGE("%{public}s: release mtp device failed: %{public}d", __func__, ret);
117     }
118     UsbdUnregisterDevice(MTP_PTP_SERVICE_NAME);
119     HDF_LOGI("%{public}s: release Mtp done", __func__);
120     return ret;
121 }
122 
RemoveHdc()123 int32_t UsbdFunction::RemoveHdc()
124 {
125     int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_OFF);
126     if (status != 0) {
127         HDF_LOGE("%{public}s:remove hdc config error = %{public}d", __func__, status);
128         return HDF_FAILURE;
129     }
130     return HDF_SUCCESS;
131 }
132 
AddHdc()133 int32_t UsbdFunction::AddHdc()
134 {
135     int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_ON);
136     if (status != 0) {
137         HDF_LOGE("%{public}s:add hdc config error = %{public}d", __func__, status);
138         return HDF_FAILURE;
139     }
140     return HDF_SUCCESS;
141 }
142 
SetFunctionToRndis()143 int32_t UsbdFunction::SetFunctionToRndis()
144 {
145     int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_RNDIS);
146     if (status != 0) {
147         HDF_LOGE("%{public}s:add rndis config error = %{public}d", __func__, status);
148         return HDF_FAILURE;
149     }
150     return HDF_SUCCESS;
151 }
152 
SetFunctionToStorage()153 int32_t UsbdFunction::SetFunctionToStorage()
154 {
155     int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_STORAGE);
156     if (status != 0) {
157         HDF_LOGE("%{public}s:add storage config error = %{public}d", __func__, status);
158         return HDF_FAILURE;
159     }
160     return HDF_SUCCESS;
161 }
162 
SetFunctionToRndisHdc()163 int32_t UsbdFunction::SetFunctionToRndisHdc()
164 {
165     int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_RNDIS_HDC);
166     if (status != 0) {
167         HDF_LOGE("%{public}s:add rndis hdc config error = %{public}d", __func__, status);
168         return HDF_FAILURE;
169     }
170     return HDF_SUCCESS;
171 }
172 
SetFunctionToStorageHdc()173 int32_t UsbdFunction::SetFunctionToStorageHdc()
174 {
175     int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_STORAGE_HDC);
176     if (status != 0) {
177         HDF_LOGE("%{public}s:add storage hdc config error = %{public}d", __func__, status);
178         return HDF_FAILURE;
179     }
180     return HDF_SUCCESS;
181 }
182 
SetFunctionToNone()183 int32_t UsbdFunction::SetFunctionToNone()
184 {
185     uint32_t ddkFuns = currentFuncs_ & USB_DDK_FUNCTION_SUPPORT;
186     if (ddkFuns > 0) {
187         if ((ddkFuns & USB_FUNCTION_ACM) != 0) {
188             UsbdFunction::SendCmdToService(ACM_SERVICE_NAME, ACM_RELEASE, USB_FUNCTION_ACM);
189             UsbdUnregisterDevice(std::string(ACM_SERVICE_NAME));
190         }
191         if ((ddkFuns & USB_FUNCTION_ECM) != 0) {
192             UsbdFunction::SendCmdToService(ECM_SERVICE_NAME, ECM_RELEASE, USB_FUNCTION_ECM);
193             UsbdUnregisterDevice(std::string(ECM_SERVICE_NAME));
194         }
195         if ((ddkFuns & USB_FUNCTION_MTP) != 0 || (ddkFuns & USB_FUNCTION_PTP) != 0) {
196             if (ReleaseMtp() != HDF_SUCCESS) {
197                 HDF_LOGE("%{public}s: release mtp failed", __func__);
198             }
199         }
200         UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT);
201         UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME));
202     }
203     int32_t ret = RemoveHdc();
204     if (ret != HDF_SUCCESS) {
205         HDF_LOGE("%{public}s: RemoveHdc error, ret = %{public}d", __func__, ret);
206         return ret;
207     }
208     currentFuncs_ = USB_FUNCTION_NONE;
209     return ret;
210 }
211 
SetDDKFunction(uint32_t funcs)212 int32_t UsbdFunction::SetDDKFunction(uint32_t funcs)
213 {
214     HDF_LOGD("%{public}s: SetDDKFunction funcs=%{public}d", __func__, funcs);
215     uint32_t ddkFuns = static_cast<uint32_t>(funcs) & USB_DDK_FUNCTION_SUPPORT;
216     if (ddkFuns == 0) {
217         HDF_LOGE("%{public}s: not use ddkfunction", __func__);
218         return HDF_SUCCESS;
219     }
220     int32_t ret = UsbdRegisterDevice(std::string(DEV_SERVICE_NAME));
221     if (ret != HDF_SUCCESS) {
222         HDF_LOGE("%{public}s: failed to register device", __func__);
223         return ret;
224     }
225     if (UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_ADD, ddkFuns)) {
226         HDF_LOGE("%{public}s: create dev error: %{public}d", __func__, ddkFuns);
227         return HDF_FAILURE;
228     }
229     return HDF_SUCCESS;
230 }
231 
UsbdEnableDevice()232 int32_t UsbdFunction::UsbdEnableDevice()
233 {
234     FILE *fp = fopen(UDC_PATH, "w");
235     if (fp == NULL) {
236         HDF_LOGE("%{public}s: fopen failed", __func__);
237         return HDF_ERR_BAD_FD;
238     }
239 
240     // get udc name
241     char udcName[UDC_NAME_MAX_LEN] = {0};
242     int32_t ret = GetParameter("sys.usb.controller", "invalid", udcName, UDC_NAME_MAX_LEN);
243     if (ret <= 0) {
244         HDF_LOGE("%{public}s: GetParameter failed", __func__);
245         (void)fclose(fp);
246         return HDF_FAILURE;
247     }
248 
249     size_t count = fwrite(udcName, strlen(udcName), 1, fp);
250     (void)fclose(fp);
251     if (count != 1) {
252         HDF_LOGE("%{public}s: fwrite failed", __func__);
253         return HDF_FAILURE;
254     }
255     return HDF_SUCCESS;
256 }
257 
UsbdWaitUdc()258 int32_t UsbdFunction::UsbdWaitUdc()
259 {
260     // get udc name
261     char udcName[UDC_NAME_MAX_LEN] = {0};
262     int32_t ret = GetParameter("sys.usb.controller", "invalid", udcName, UDC_NAME_MAX_LEN - 1);
263     if (ret <= 0) {
264         HDF_LOGE("%{public}s: GetParameter failed", __func__);
265         return HDF_FAILURE;
266     }
267 
268     char tmpName[UDC_NAME_MAX_LEN] = {0};
269     for (int32_t i = 0; i < WAIT_UDC_MAX_LOOP; i++) {
270         FILE *fp = fopen(UDC_PATH, "r");
271         if (fp == NULL) {
272             HDF_LOGE("%{public}s: fopen failed", __func__);
273             return HDF_ERR_BAD_FD;
274         }
275 
276         (void)memset_s(tmpName, UDC_NAME_MAX_LEN, 0, UDC_NAME_MAX_LEN);
277         if (fread(tmpName, strlen(udcName), 1, fp) != 1) {
278             HDF_LOGE("%{public}s: fread failed", __func__);
279         }
280         (void)fclose(fp);
281         if (strcmp(udcName, tmpName) == 0) {
282             return HDF_SUCCESS;
283         }
284         usleep(WAIT_UDC_TIME);
285     }
286 
287     if (strcmp(udcName, tmpName) != 0) {
288         HDF_LOGE("%{public}s: strcmp failed", __func__);
289         return HDF_FAILURE;
290     }
291 
292     return HDF_SUCCESS;
293 }
294 
UsbdInitDDKFunction(uint32_t funcs)295 int32_t UsbdFunction::UsbdInitDDKFunction(uint32_t funcs)
296 {
297     int32_t ret;
298     if ((funcs & USB_FUNCTION_ACM) != 0) {
299         ret = UsbdRegisterDevice(std::string(ACM_SERVICE_NAME));
300         if (ret != HDF_SUCCESS) {
301             HDF_LOGE("%{public}s: failed to register device", __func__);
302             return HDF_FAILURE;
303         }
304         if (SendCmdToService(ACM_SERVICE_NAME, ACM_INIT, USB_FUNCTION_ACM) != 0) {
305             HDF_LOGE("%{public}s: acm init error", __func__);
306             return HDF_FAILURE;
307         }
308     }
309     if ((funcs & USB_FUNCTION_ECM) != 0) {
310         ret = UsbdRegisterDevice(std::string(ECM_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(ECM_SERVICE_NAME, ECM_INIT, USB_FUNCTION_ECM) != 0) {
316             HDF_LOGE("%{public}s: ecm init error", __func__);
317             return HDF_FAILURE;
318         }
319     }
320     if ((funcs & USB_FUNCTION_MTP) != 0 || (funcs & USB_FUNCTION_PTP) != 0) {
321         ret = InitMtp();
322         if (ret != HDF_SUCCESS) {
323             HDF_LOGE("%{public}s: failed to init mtp", __func__);
324             return HDF_FAILURE;
325         }
326     }
327     return HDF_SUCCESS;
328 }
329 
UsbdSetKernelFunction(int32_t kfuns)330 int32_t UsbdFunction::UsbdSetKernelFunction(int32_t kfuns)
331 {
332     switch (kfuns) {
333         case USB_FUNCTION_HDC:
334             HDF_LOGI("%{public}s: set hdc", __func__);
335             return UsbdFunction::AddHdc();
336         case USB_FUNCTION_RNDIS:
337             HDF_LOGI("%{public}s: set rndis", __func__);
338             return UsbdFunction::SetFunctionToRndis();
339         case USB_FUNCTION_STORAGE:
340             HDF_LOGI("%{public}s: set mass_storage", __func__);
341             return UsbdFunction::SetFunctionToStorage();
342         case USB_FUNCTION_RNDIS | USB_FUNCTION_HDC:
343             HDF_LOGI("%{public}s: set rndis hdc", __func__);
344             return UsbdFunction::SetFunctionToRndisHdc();
345         case USB_FUNCTION_STORAGE | USB_FUNCTION_HDC:
346             HDF_LOGI("%{public}s: set storage hdc", __func__);
347             return UsbdFunction::SetFunctionToStorageHdc();
348         default:
349             HDF_LOGI("%{public}s: enable device", __func__);
350             return UsbdEnableDevice();
351     }
352 }
353 
UsbdSetFunction(uint32_t funcs)354 int32_t UsbdFunction::UsbdSetFunction(uint32_t funcs)
355 {
356     HDF_LOGI("%{public}s: UsbdSetFunction funcs=%{public}d", __func__, funcs);
357     if ((funcs | USB_FUNCTION_SUPPORT) != USB_FUNCTION_SUPPORT) {
358         HDF_LOGE("%{public}s: funcs invalid", __func__);
359         return HDF_FAILURE;
360     }
361 
362     uint32_t kfuns = static_cast<uint32_t>(funcs) & (~USB_DDK_FUNCTION_SUPPORT);
363     if (UsbdFunction::SetFunctionToNone()) {
364         HDF_LOGW("%{public}s: setFunctionToNone error", __func__);
365     }
366 
367     if (UsbdFunction::SetDDKFunction(funcs)) {
368         HDF_LOGE("%{public}s:SetDDKFunction error", __func__);
369         return HDF_FAILURE;
370     }
371 
372     int32_t ret = UsbdSetKernelFunction(kfuns);
373     if (ret != HDF_SUCCESS) {
374         HDF_LOGE("%{public}s, set kernel func failed", __func__);
375         return HDF_FAILURE;
376     }
377 
378     if (funcs == USB_FUNCTION_NONE) {
379         HDF_LOGI("%{public}s, none function", __func__);
380         return HDF_SUCCESS;
381     }
382 
383     if (UsbdWaitUdc() != HDF_SUCCESS) {
384         HDF_LOGE("%{public}s, wait udc failed", __func__);
385         return HDF_FAILURE;
386     }
387     if (UsbdInitDDKFunction(funcs) != HDF_SUCCESS) {
388         HDF_LOGE("%{public}s, init ddk func failed", __func__);
389         UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT);
390         UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME));
391         return HDF_FAILURE;
392     }
393     currentFuncs_ = funcs;
394     return HDF_SUCCESS;
395 }
396 
UsbdGetFunction(void)397 int32_t UsbdFunction::UsbdGetFunction(void)
398 {
399     return currentFuncs_;
400 }
401 
UsbdRegisterDevice(const std::string & serviceName)402 int32_t UsbdFunction::UsbdRegisterDevice(const std::string &serviceName)
403 {
404     int32_t ret;
405     OHOS::sptr<IDeviceManager> devMgr = IDeviceManager::Get();
406     if (devMgr == nullptr) {
407         HDF_LOGE("%{public}s: get IDeviceManager failed", __func__);
408         return HDF_FAILURE;
409     }
410     ret = devMgr->LoadDevice(serviceName);
411     if (ret != HDF_SUCCESS) {
412         HDF_LOGE("%{public}s, load %{public}s failed", __func__, serviceName.c_str());
413         return ret;
414     }
415     return ret;
416 }
417 
UsbdUnregisterDevice(const std::string & serviceName)418 void UsbdFunction::UsbdUnregisterDevice(const std::string &serviceName)
419 {
420     int32_t ret;
421     OHOS::sptr<IDeviceManager> devMgr = IDeviceManager::Get();
422     if (devMgr == nullptr) {
423         HDF_LOGE("%{public}s: get devMgr object failed", __func__);
424         return;
425     }
426     ret = devMgr->UnloadDevice(serviceName);
427     if (ret != HDF_SUCCESS) {
428         HDF_LOGW("%{public}s, %{public}s unload  failed", __func__, serviceName.c_str());
429     }
430 }
431 } // namespace V1_0
432 } // namespace Usb
433 } // namespace HDI
434 } // namespace OHOS
435