1 /*
2 * Copyright (c) 2021 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 #include "usbd_function.h"
16
17 #include <hdf_sbuf.h>
18 #include <servmgr_hdi.h>
19 #include "devmgr_hdi.h"
20 #include "hdf_log.h"
21 #include "hdf_remote_service.h"
22 #include "osal_time.h"
23 #include "parameter.h"
24 #include "securec.h"
25
26 #define DEV_SERVICE_NAME "usbfn_master"
27 #define ACM_SERVICE_NAME "usbfn_cdcacm"
28 #define ECM_SERVICE_NAME "usbfn_cdcecm"
29
30 #define SYS_USB_CONFIGFS "sys.usb.configfs"
31 #define SYS_USB_CONFIG "sys.usb.config"
32 #define HDC_CONFIG_OFF "none"
33 #define HDC_CONFIG_ON "hdc"
34 #define HDC_CONFIGFS_OFF "0"
35 #define HDC_CONFIGFS_ON "1"
36
37 #define FUNCTION_ADD 1
38 #define FUNCTION_DEL 2
39
40 #define ACM_INIT 100
41 #define ACM_RELEASE 101
42 #define ECM_INIT 100
43 #define ECM_RELEASE 101
44
45 #define USB_FUNCTION_ACM_ECM 3
46 #define FUNCTIONS_MAX 7
47
48 static uint8_t currentFuncs = USB_FUNCTION_HDC;
49 static uint8_t WAIT_SLEEP_TIME = 10;
50
SendCmdToService(const char * name,int32_t cmd,unsigned char funcMask)51 static int32_t SendCmdToService(const char *name, int32_t cmd, unsigned char funcMask)
52 {
53 struct HdfRemoteService *service = NULL;
54 struct HdfSBuf *data = NULL;
55 struct HdfSBuf *reply = NULL;
56 struct HDIServiceManager *servmgr = NULL;
57 servmgr = HDIServiceManagerGet();
58 if (servmgr == NULL) {
59 HDF_LOGE("%{public}s:%{public}d HDIServiceManagerGet err\n", __func__, __LINE__);
60 return HDF_FAILURE;
61 }
62 service = servmgr->GetService(servmgr, name);
63 HDIServiceManagerRelease(servmgr);
64 if (service == NULL) {
65 HDF_LOGE("%{public}s:%{public}d GetService err\n", __func__, __LINE__);
66 return HDF_FAILURE;
67 }
68
69 if (HdfRemoteServiceSetInterfaceDesc(service, HDF_USB_USBFN_DESC) == false) {
70 HDF_LOGE("%{public}s:%{public}d set desc fail\n", __func__, __LINE__);
71 return HDF_FAILURE;
72 }
73
74 data = HdfSbufTypedObtain(SBUF_IPC);
75 reply = HdfSbufTypedObtain(SBUF_IPC);
76 if (data == NULL || reply == NULL) {
77 HDF_LOGE("%{public}s:%{public}d data or reply err\n", __func__, __LINE__);
78 HdfRemoteServiceRecycle(service);
79 return HDF_FAILURE;
80 }
81
82 if (HdfRemoteServiceWriteInterfaceToken(service, data) == false) {
83 HDF_LOGE("%{public}s:%{public}d write interface token fail\n", __func__, __LINE__);
84 HdfSbufRecycle(data);
85 HdfSbufRecycle(reply);
86 HdfRemoteServiceRecycle(service);
87 return HDF_FAILURE;
88 }
89
90 if (!HdfSbufWriteInt8(data, funcMask)) {
91 HDF_LOGE("%{public}s:%{public}d HdfSbufWriteInt8 error\n", __func__, __LINE__);
92 HdfSbufRecycle(data);
93 HdfSbufRecycle(reply);
94 HdfRemoteServiceRecycle(service);
95 return HDF_FAILURE;
96 }
97 int32_t status = service->dispatcher->Dispatch(service, cmd, data, reply);
98 if (status) {
99 HDF_LOGW("%{public}s:%{public}d serice %{public}s dispatch cmd : %{public}d error\n", __func__, __LINE__, name,
100 cmd);
101 }
102 HdfSbufRecycle(data);
103 HdfSbufRecycle(reply);
104 HdfRemoteServiceRecycle(service);
105 return status;
106 }
107
RemoveHdc()108 static int32_t RemoveHdc()
109 {
110 uint8_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_OFF);
111 if (status) {
112 HDF_LOGE("%{public}s:%{public}d remove hdc config error = %{public}d\n", __func__, __LINE__, status);
113 return HDF_FAILURE;
114 }
115 status = SetParameter(SYS_USB_CONFIGFS, HDC_CONFIGFS_OFF);
116 if (status) {
117 HDF_LOGE("%{public}s:%{public}d remove hdc configs error = %{public}d\n", __func__, __LINE__, status);
118 return HDF_FAILURE;
119 }
120 return HDF_SUCCESS;
121 }
122
AddHdc()123 static int32_t AddHdc()
124 {
125 uint8_t status = SetParameter(SYS_USB_CONFIGFS, HDC_CONFIGFS_ON);
126 if (status) {
127 HDF_LOGE("%{public}s:%{public}d add hdc configfs error = %{public}d\n", __func__, __LINE__, status);
128 return HDF_FAILURE;
129 }
130 status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_ON);
131 if (status) {
132 HDF_LOGE("%{public}s:%{public}d add hdc config error = %{public}d\n", __func__, __LINE__, status);
133 return HDF_FAILURE;
134 }
135 return HDF_SUCCESS;
136 }
137
SetFunctionToNone()138 static int32_t SetFunctionToNone()
139 {
140 if (RemoveHdc()) {
141 HDF_LOGE("%{public}s:%{public}d RemoveHdc error ", __func__, __LINE__);
142 return HDF_FAILURE;
143 }
144 SendCmdToService(ACM_SERVICE_NAME, ACM_RELEASE, USB_FUNCTION_ACM);
145 SendCmdToService(ECM_SERVICE_NAME, ECM_RELEASE, USB_FUNCTION_ECM);
146 SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_FUNCTION_ACM_ECM);
147 currentFuncs = USB_FUNCTION_NONE;
148 return HDF_SUCCESS;
149 }
150
SetFunctionToACM()151 static int32_t SetFunctionToACM()
152 {
153 if (SendCmdToService(DEV_SERVICE_NAME, FUNCTION_ADD, USB_FUNCTION_ACM)) {
154 HDF_LOGE("%{public}s:%{public}d create acm dev error ", __func__, __LINE__);
155 return HDF_FAILURE;
156 }
157
158 if (SendCmdToService(ACM_SERVICE_NAME, ACM_INIT, USB_FUNCTION_ACM)) {
159 HDF_LOGE("%{public}s:%{public}d acm init error ", __func__, __LINE__);
160 return HDF_FAILURE;
161 }
162 return HDF_SUCCESS;
163 }
164
SetFunctionToECM()165 static int32_t SetFunctionToECM()
166 {
167 if (SendCmdToService(DEV_SERVICE_NAME, FUNCTION_ADD, USB_FUNCTION_ECM)) {
168 HDF_LOGE("%{public}s:%{public}d create ecm dev error ", __func__, __LINE__);
169 return HDF_FAILURE;
170 }
171
172 if (SendCmdToService(ECM_SERVICE_NAME, ECM_INIT, USB_FUNCTION_ECM)) {
173 HDF_LOGE("%{public}s:%{public}d ecm init error ", __func__, __LINE__);
174 return HDF_FAILURE;
175 }
176 return HDF_SUCCESS;
177 }
178
SetFunctionToACMECM()179 static int32_t SetFunctionToACMECM()
180 {
181 if (SendCmdToService(DEV_SERVICE_NAME, FUNCTION_ADD, USB_FUNCTION_ACM_ECM)) {
182 HDF_LOGE("%{public}s:%{public}d create acm&ecm dev error ", __func__, __LINE__);
183 return HDF_FAILURE;
184 }
185
186 if (SendCmdToService(ACM_SERVICE_NAME, ACM_INIT, USB_FUNCTION_ACM)) {
187 HDF_LOGE("%{public}s:%{public}d acm init error ", __func__, __LINE__);
188 return HDF_FAILURE;
189 }
190
191 if (SendCmdToService(ECM_SERVICE_NAME, ECM_INIT, USB_FUNCTION_ECM)) {
192 HDF_LOGE("%{public}s:%{public}d ecm init dev error ", __func__, __LINE__);
193 return HDF_FAILURE;
194 }
195 return HDF_SUCCESS;
196 }
197
UsbdSetFunction(int funcs)198 int32_t UsbdSetFunction(int funcs)
199 {
200 uint8_t _acm_ecm = funcs & USB_FUNCTION_ACM_ECM;
201 if (funcs < USB_FUNCTION_NONE || funcs >= FUNCTIONS_MAX) {
202 HDF_LOGI("%{public}s:%{public}d funcs invalid \n", __func__, __LINE__);
203 return HDF_FAILURE;
204 }
205
206 if (SetFunctionToNone()) {
207 HDF_LOGI("%{public}s:%{public}d setFunctionToNone error \n", __func__, __LINE__);
208 }
209
210 if (funcs & USB_FUNCTION_HDC) {
211 if (AddHdc()) {
212 HDF_LOGE("%{public}s:%{public}d AddHdc error ", __func__, __LINE__);
213 return HDF_FAILURE;
214 }
215 }
216
217 if (_acm_ecm == USB_FUNCTION_ACM) {
218 if (SetFunctionToACM()) {
219 HDF_LOGE("%{public}s:%{public}d set function to acm error ", __func__, __LINE__);
220 return HDF_FAILURE;
221 }
222 } else if (_acm_ecm == USB_FUNCTION_ECM) {
223 if (SetFunctionToECM()) {
224 HDF_LOGE("%{public}s:%{public}d set function to ecm error ", __func__, __LINE__);
225 return HDF_FAILURE;
226 }
227 } else if (_acm_ecm == USB_FUNCTION_ACM_ECM) {
228 if (SetFunctionToACMECM()) {
229 HDF_LOGE("%{public}s:%{public}d set function to acm&ecm error ", __func__, __LINE__);
230 return HDF_FAILURE;
231 }
232 }
233 OsalMSleep(WAIT_SLEEP_TIME);
234 currentFuncs = funcs;
235 return HDF_SUCCESS;
236 }
237
UsbdGetFunction(void)238 int32_t UsbdGetFunction(void)
239 {
240 return currentFuncs;
241 }
242