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