• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "iservmgr_hdi.h"
25 #include "message_option.h"
26 #include "message_parcel.h"
27 #include "osal_time.h"
28 #include "parameter.h"
29 #include "securec.h"
30 #include "string_ex.h"
31 #include "usbd_type.h"
32 
33 namespace OHOS {
34 namespace HDI {
35 namespace Usb {
36 namespace V1_0 {
37 uint32_t UsbdFunction::currentFuncs_ = USB_FUNCTION_HDC;
38 
39 using OHOS::HDI::ServiceManager::V1_0::IServiceManager;
40 constexpr uint32_t UDC_NAME_MAX_LEN = 32;
41 constexpr int32_t WAIT_UDC_MAX_LOOP = 30;
42 constexpr uint32_t WAIT_UDC_TIME = 100000;
43 #define UDC_PATH "/config/usb_gadget/g1/UDC"
44 
SendCmdToService(const char * name,int32_t cmd,unsigned char funcMask)45 int32_t UsbdFunction::SendCmdToService(const char *name, int32_t cmd, unsigned char funcMask)
46 {
47     auto servMgr = IServiceManager::Get();
48     if (servMgr == nullptr) {
49         HDF_LOGE("%{public}s: get IServiceManager failed", __func__);
50         return HDF_FAILURE;
51     }
52 
53     sptr<IRemoteObject> remote = servMgr->GetService(name);
54     if (remote == nullptr) {
55         HDF_LOGE("%{public}s: get remote object failed: %{public}s", __func__, name);
56         return HDF_FAILURE;
57     }
58 
59     OHOS::MessageParcel data;
60     OHOS::MessageParcel reply;
61     OHOS::MessageOption option;
62 
63     if (!data.WriteInterfaceToken(Str8ToStr16(HDF_USB_USBFN_DESC))) {
64         HDF_LOGE("%{public}s: WriteInterfaceToken failed", __func__);
65         return HDF_FAILURE;
66     }
67 
68     if (!data.WriteUint8(funcMask)) {
69         HDF_LOGE("%{public}s: WriteInt8 failed: %{public}d", __func__, funcMask);
70         return HDF_FAILURE;
71     }
72 
73     int32_t ret = remote->SendRequest(cmd, data, reply, option);
74     if (ret != HDF_SUCCESS) {
75         HDF_LOGE("%{public}s: send request to %{public}s failed, ret=%{public}d", __func__, name, ret);
76         return ret;
77     }
78     return HDF_SUCCESS;
79 }
80 
RemoveHdc()81 int32_t UsbdFunction::RemoveHdc()
82 {
83     int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_OFF);
84     if (status != 0) {
85         HDF_LOGE("%{public}s:remove hdc config error = %{public}d", __func__, status);
86         return HDF_FAILURE;
87     }
88     return HDF_SUCCESS;
89 }
90 
AddHdc()91 int32_t UsbdFunction::AddHdc()
92 {
93     int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_ON);
94     if (status != 0) {
95         HDF_LOGE("%{public}s:add hdc config error = %{public}d", __func__, status);
96         return HDF_FAILURE;
97     }
98     return HDF_SUCCESS;
99 }
100 
SetFunctionToRndis()101 int32_t UsbdFunction::SetFunctionToRndis()
102 {
103     int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_RNDIS);
104     if (status != 0) {
105         HDF_LOGE("%{public}s:add rndis config error = %{public}d", __func__, status);
106         return HDF_FAILURE;
107     }
108     return HDF_SUCCESS;
109 }
110 
SetFunctionToStorage()111 int32_t UsbdFunction::SetFunctionToStorage()
112 {
113     int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_STORAGE);
114     if (status != 0) {
115         HDF_LOGE("%{public}s:add storage config error = %{public}d", __func__, status);
116         return HDF_FAILURE;
117     }
118     return HDF_SUCCESS;
119 }
120 
SetFunctionToRndisHdc()121 int32_t UsbdFunction::SetFunctionToRndisHdc()
122 {
123     int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_RNDIS_HDC);
124     if (status != 0) {
125         HDF_LOGE("%{public}s:add rndis hdc config error = %{public}d", __func__, status);
126         return HDF_FAILURE;
127     }
128     return HDF_SUCCESS;
129 }
130 
SetFunctionToStorageHdc()131 int32_t UsbdFunction::SetFunctionToStorageHdc()
132 {
133     int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_STORAGE_HDC);
134     if (status != 0) {
135         HDF_LOGE("%{public}s:add storage hdc config error = %{public}d", __func__, status);
136         return HDF_FAILURE;
137     }
138     return HDF_SUCCESS;
139 }
140 
SetFunctionToNone()141 int32_t UsbdFunction::SetFunctionToNone()
142 {
143     UsbdFunction::SendCmdToService(ACM_SERVICE_NAME, ACM_RELEASE, USB_FUNCTION_ACM);
144     UsbdFunction::SendCmdToService(ECM_SERVICE_NAME, ECM_RELEASE, USB_FUNCTION_ECM);
145     UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT);
146     int32_t ret = RemoveHdc();
147     if (ret != HDF_SUCCESS) {
148         HDF_LOGE("%{public}s: RemoveHdc error, ret = %{public}d", __func__, ret);
149         return HDF_FAILURE;
150     }
151     currentFuncs_ = USB_FUNCTION_NONE;
152     return HDF_SUCCESS;
153 }
154 
SetDDKFunction(uint32_t funcs)155 int32_t UsbdFunction::SetDDKFunction(uint32_t funcs)
156 {
157     uint32_t ddkFuns = static_cast<uint32_t>(funcs) & USB_DDK_FUNCTION_SUPPORT;
158     if (ddkFuns == 0) {
159         HDF_LOGE("%{public}s: not use ddkfunction", __func__);
160         return HDF_SUCCESS;
161     }
162     if (UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_ADD, ddkFuns)) {
163         HDF_LOGE("%{public}s: create dev error: %{public}d", __func__, ddkFuns);
164         return HDF_FAILURE;
165     }
166     return HDF_SUCCESS;
167 }
168 
UsbdEnableDevice()169 int32_t UsbdFunction::UsbdEnableDevice()
170 {
171     FILE *fp = fopen(UDC_PATH, "w");
172     if (fp == NULL) {
173         HDF_LOGE("%{public}s: fopen failed", __func__);
174         return HDF_ERR_BAD_FD;
175     }
176 
177     // get udc name
178     char udcName[UDC_NAME_MAX_LEN] = {0};
179     int32_t ret = GetParameter("sys.usb.controller", "invalid", udcName, UDC_NAME_MAX_LEN);
180     if (ret <= 0) {
181         HDF_LOGE("%{public}s: GetParameter failed", __func__);
182         (void)fclose(fp);
183         return HDF_FAILURE;
184     }
185 
186     size_t count = fwrite(udcName, strlen(udcName), 1, fp);
187     (void)fclose(fp);
188     if (count != 1) {
189         HDF_LOGE("%{public}s: fwrite failed", __func__);
190         return HDF_FAILURE;
191     }
192     return HDF_SUCCESS;
193 }
194 
UsbdWaitUdc()195 int32_t UsbdFunction::UsbdWaitUdc()
196 {
197     // get udc name
198     char udcName[UDC_NAME_MAX_LEN] = {0};
199     int32_t ret = GetParameter("sys.usb.controller", "invalid", udcName, UDC_NAME_MAX_LEN - 1);
200     if (ret <= 0) {
201         HDF_LOGE("%{public}s: GetParameter failed", __func__);
202         return HDF_FAILURE;
203     }
204 
205     char tmpName[UDC_NAME_MAX_LEN] = {0};
206     for (int32_t i = 0; i < WAIT_UDC_MAX_LOOP; i++) {
207         FILE *fp = fopen(UDC_PATH, "r");
208         if (fp == NULL) {
209             HDF_LOGE("%{public}s: fopen failed", __func__);
210             return HDF_ERR_BAD_FD;
211         }
212 
213         (void)memset_s(tmpName, UDC_NAME_MAX_LEN, 0, UDC_NAME_MAX_LEN);
214         if (fread(tmpName, strlen(udcName), 1, fp) != 1) {
215             HDF_LOGE("%{public}s: fread failed", __func__);
216         }
217         (void)fclose(fp);
218         if (strcmp(udcName, tmpName) == 0) {
219             return HDF_SUCCESS;
220         }
221         usleep(WAIT_UDC_TIME);
222     }
223 
224     if (strcmp(udcName, tmpName) != 0) {
225         HDF_LOGE("%{public}s: strcmp failed", __func__);
226         return HDF_FAILURE;
227     }
228 
229     return HDF_SUCCESS;
230 }
231 
UsbdInitDDKFunction(uint32_t funcs)232 int32_t UsbdFunction::UsbdInitDDKFunction(uint32_t funcs)
233 {
234     if ((funcs & USB_FUNCTION_ACM) && UsbdFunction::SendCmdToService(ACM_SERVICE_NAME, ACM_INIT, USB_FUNCTION_ACM)) {
235         HDF_LOGE("%{public}s: acm init error", __func__);
236         return HDF_FAILURE;
237     }
238     if ((funcs & USB_FUNCTION_ECM) && UsbdFunction::SendCmdToService(ECM_SERVICE_NAME, ECM_INIT, USB_FUNCTION_ECM)) {
239         HDF_LOGE("%{public}s: ecm init error", __func__);
240         return HDF_FAILURE;
241     }
242     return HDF_SUCCESS;
243 }
244 
UsbdSetKernelFunction(int32_t kfuns)245 int32_t UsbdFunction::UsbdSetKernelFunction(int32_t kfuns)
246 {
247     switch (kfuns) {
248         case USB_FUNCTION_HDC:
249             HDF_LOGI("%{public}s: set hdc", __func__);
250             return UsbdFunction::AddHdc();
251             break;
252         case USB_FUNCTION_RNDIS:
253             HDF_LOGI("%{public}s: set rndis", __func__);
254             return UsbdFunction::SetFunctionToRndis();
255             break;
256         case USB_FUNCTION_STORAGE:
257             HDF_LOGI("%{public}s: set mass_storage", __func__);
258             return UsbdFunction::SetFunctionToStorage();
259             break;
260         case USB_FUNCTION_RNDIS | USB_FUNCTION_HDC:
261             HDF_LOGI("%{public}s: set rndis hdc", __func__);
262             return UsbdFunction::SetFunctionToRndisHdc();
263             break;
264         case USB_FUNCTION_STORAGE | USB_FUNCTION_HDC:
265             HDF_LOGI("%{public}s: set storage hdc", __func__);
266             return UsbdFunction::SetFunctionToStorageHdc();
267             break;
268         default:
269             HDF_LOGI("%{public}s: enable device", __func__);
270             return UsbdEnableDevice();
271             break;
272     }
273     return HDF_SUCCESS;
274 }
275 
UsbdSetFunction(uint32_t funcs)276 int32_t UsbdFunction::UsbdSetFunction(uint32_t funcs)
277 {
278     HDF_LOGI("%{public}s: UsbdSetFunction funcs=%{public}d", __func__, funcs);
279     if ((funcs | USB_FUNCTION_SUPPORT) != USB_FUNCTION_SUPPORT) {
280         HDF_LOGE("%{public}s: funcs invalid", __func__);
281         return HDF_FAILURE;
282     }
283 
284     uint32_t kfuns = static_cast<uint32_t>(funcs) & (~USB_DDK_FUNCTION_SUPPORT);
285     if (UsbdFunction::SetFunctionToNone()) {
286         HDF_LOGW("%{public}s: setFunctionToNone error", __func__);
287     }
288 
289     if (UsbdFunction::SetDDKFunction(funcs)) {
290         HDF_LOGE("%{public}s:SetDDKFunction error", __func__);
291         return HDF_FAILURE;
292     }
293 
294     int32_t ret = UsbdSetKernelFunction(kfuns);
295     if (ret != HDF_SUCCESS) {
296         HDF_LOGE("%{public}s, set kernel func failed", __func__);
297         return HDF_FAILURE;
298     }
299 
300     if (funcs == USB_FUNCTION_NONE) {
301         HDF_LOGI("%{public}s, none function", __func__);
302         return HDF_SUCCESS;
303     }
304 
305     if (UsbdWaitUdc() != HDF_SUCCESS) {
306         HDF_LOGE("%{public}s, wait udc failed", __func__);
307         return HDF_FAILURE;
308     }
309     if (UsbdInitDDKFunction(funcs) != HDF_SUCCESS) {
310         HDF_LOGE("%{public}s, init ddk func failed", __func__);
311         return HDF_FAILURE;
312     }
313     currentFuncs_ = funcs;
314     return HDF_SUCCESS;
315 }
316 
UsbdGetFunction(void)317 int32_t UsbdFunction::UsbdGetFunction(void)
318 {
319     return currentFuncs_;
320 }
321 } // namespace V1_0
322 } // namespace Usb
323 } // namespace HDI
324 } // namespace OHOS
325