1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "android.hardware.usb.gadget@1.1-service.barbet"
18
19 #include "UsbGadget.h"
20 #include <dirent.h>
21 #include <fcntl.h>
22 #include <stdio.h>
23 #include <sys/inotify.h>
24 #include <sys/mount.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28
29 namespace android {
30 namespace hardware {
31 namespace usb {
32 namespace gadget {
33 namespace V1_1 {
34 namespace implementation {
35
UsbGadget()36 UsbGadget::UsbGadget() {
37 if (access(OS_DESC_PATH, R_OK) != 0) {
38 ALOGE("configfs setup not done yet");
39 abort();
40 }
41 }
42
currentFunctionsAppliedCallback(bool functionsApplied,void * payload)43 void currentFunctionsAppliedCallback(bool functionsApplied, void *payload) {
44 UsbGadget *gadget = (UsbGadget *)payload;
45 gadget->mCurrentUsbFunctionsApplied = functionsApplied;
46 }
47
getCurrentUsbFunctions(const sp<V1_0::IUsbGadgetCallback> & callback)48 Return<void> UsbGadget::getCurrentUsbFunctions(const sp<V1_0::IUsbGadgetCallback> &callback) {
49 Return<void> ret = callback->getCurrentUsbFunctionsCb(
50 mCurrentUsbFunctions,
51 mCurrentUsbFunctionsApplied ? Status::FUNCTIONS_APPLIED : Status::FUNCTIONS_NOT_APPLIED);
52 if (!ret.isOk())
53 ALOGE("Call to getCurrentUsbFunctionsCb failed %s", ret.description().c_str());
54
55 return Void();
56 }
57
tearDownGadget()58 V1_0::Status UsbGadget::tearDownGadget() {
59 if (resetGadget() != Status::SUCCESS)
60 return Status::ERROR;
61
62 if (monitorFfs.isMonitorRunning()) {
63 monitorFfs.reset();
64 } else {
65 ALOGI("mMonitor not running");
66 }
67 return Status::SUCCESS;
68 }
69
validateAndSetVidPid(uint64_t functions)70 static V1_0::Status validateAndSetVidPid(uint64_t functions) {
71 V1_0::Status ret = Status::SUCCESS;
72 std::string vendorFunctions = getVendorFunctions();
73
74 switch (functions) {
75 case static_cast<uint64_t>(GadgetFunction::MTP):
76 if (vendorFunctions == "diag") {
77 ret = setVidPid("0x05C6", "0x901B");
78 } else {
79 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
80 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
81 ret = Status::CONFIGURATION_NOT_SUPPORTED;
82 } else {
83 ret = setVidPid("0x18d1", "0x4ee1");
84 }
85 }
86 break;
87 case GadgetFunction::ADB | GadgetFunction::MTP:
88 if (vendorFunctions == "diag") {
89 ret = setVidPid("0x05C6", "0x903A");
90 } else {
91 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
92 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
93 ret = Status::CONFIGURATION_NOT_SUPPORTED;
94 } else {
95 ret = setVidPid("0x18d1", "0x4ee2");
96 }
97 }
98 break;
99 case static_cast<uint64_t>(GadgetFunction::RNDIS):
100 if (vendorFunctions == "diag") {
101 ret = setVidPid("0x05C6", "0x902C");
102 } else if (vendorFunctions == "serial_cdev,diag") {
103 ret = setVidPid("0x05C6", "0x90B5");
104 } else if (vendorFunctions == "diag,diag_mdm,qdss,qdss_mdm,serial_cdev,dpl_gsi") {
105 ret = setVidPid("0x05C6", "0x90E6");
106 } else {
107 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
108 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
109 ret = Status::CONFIGURATION_NOT_SUPPORTED;
110 } else {
111 ret = setVidPid("0x18d1", "0x4ee3");
112 }
113 }
114 break;
115 case GadgetFunction::ADB | GadgetFunction::RNDIS:
116 if (vendorFunctions == "diag") {
117 ret = setVidPid("0x05C6", "0x902D");
118 } else if (vendorFunctions == "serial_cdev,diag") {
119 ret = setVidPid("0x05C6", "0x90B6");
120 } else if (vendorFunctions == "diag,diag_mdm,qdss,qdss_mdm,serial_cdev,dpl_gsi") {
121 ret = setVidPid("0x05C6", "0x90E7");
122 } else {
123 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
124 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
125 ret = Status::CONFIGURATION_NOT_SUPPORTED;
126 } else {
127 ret = setVidPid("0x18d1", "0x4ee4");
128 }
129 }
130 break;
131 case static_cast<uint64_t>(GadgetFunction::PTP):
132 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
133 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
134 ret = Status::CONFIGURATION_NOT_SUPPORTED;
135 } else {
136 ret = setVidPid("0x18d1", "0x4ee5");
137 }
138 break;
139 case GadgetFunction::ADB | GadgetFunction::PTP:
140 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
141 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
142 ret = Status::CONFIGURATION_NOT_SUPPORTED;
143 } else {
144 ret = setVidPid("0x18d1", "0x4ee6");
145 }
146 break;
147 case static_cast<uint64_t>(GadgetFunction::ADB):
148 if (vendorFunctions == "diag") {
149 ret = setVidPid("0x05C6", "0x901D");
150 } else if (vendorFunctions == "diag,serial_cdev,rmnet_gsi") {
151 ret = setVidPid("0x05C6", "0x9091");
152 } else if (vendorFunctions == "diag,serial_cdev") {
153 ret = setVidPid("0x05C6", "0x901F");
154 } else if (vendorFunctions == "diag,serial_cdev,rmnet_gsi,dpl_gsi,qdss") {
155 ret = setVidPid("0x05C6", "0x90DB");
156 } else if (vendorFunctions ==
157 "diag,diag_mdm,qdss,qdss_mdm,serial_cdev,dpl_gsi,rmnet_gsi") {
158 ret = setVidPid("0x05C6", "0x90E5");
159 } else {
160 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
161 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
162 ret = Status::CONFIGURATION_NOT_SUPPORTED;
163 } else {
164 ret = setVidPid("0x18d1", "0x4ee7");
165 }
166 }
167 break;
168 case static_cast<uint64_t>(GadgetFunction::MIDI):
169 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
170 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
171 ret = Status::CONFIGURATION_NOT_SUPPORTED;
172 } else {
173 ret = setVidPid("0x18d1", "0x4ee8");
174 }
175 break;
176 case GadgetFunction::ADB | GadgetFunction::MIDI:
177 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
178 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
179 ret = Status::CONFIGURATION_NOT_SUPPORTED;
180 } else {
181 ret = setVidPid("0x18d1", "0x4ee9");
182 }
183 break;
184 case static_cast<uint64_t>(GadgetFunction::ACCESSORY):
185 if (!(vendorFunctions == "user" || vendorFunctions == ""))
186 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
187 ret = setVidPid("0x18d1", "0x2d00");
188 break;
189 case GadgetFunction::ADB | GadgetFunction::ACCESSORY:
190 if (!(vendorFunctions == "user" || vendorFunctions == ""))
191 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
192 ret = setVidPid("0x18d1", "0x2d01");
193 break;
194 case static_cast<uint64_t>(GadgetFunction::AUDIO_SOURCE):
195 if (!(vendorFunctions == "user" || vendorFunctions == ""))
196 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
197 ret = setVidPid("0x18d1", "0x2d02");
198 break;
199 case GadgetFunction::ADB | GadgetFunction::AUDIO_SOURCE:
200 if (!(vendorFunctions == "user" || vendorFunctions == ""))
201 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
202 ret = setVidPid("0x18d1", "0x2d03");
203 break;
204 case GadgetFunction::ACCESSORY | GadgetFunction::AUDIO_SOURCE:
205 if (!(vendorFunctions == "user" || vendorFunctions == ""))
206 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
207 ret = setVidPid("0x18d1", "0x2d04");
208 break;
209 case GadgetFunction::ADB | GadgetFunction::ACCESSORY | GadgetFunction::AUDIO_SOURCE:
210 if (!(vendorFunctions == "user" || vendorFunctions == ""))
211 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
212 ret = setVidPid("0x18d1", "0x2d05");
213 break;
214 default:
215 ALOGE("Combination not supported");
216 ret = Status::CONFIGURATION_NOT_SUPPORTED;
217 }
218 return ret;
219 }
220
reset()221 Return<Status> UsbGadget::reset() {
222 ALOGI("USB Gadget reset");
223
224 if (!WriteStringToFile("none", PULLUP_PATH)) {
225 ALOGI("Gadget cannot be pulled down");
226 return Status::ERROR;
227 }
228
229 usleep(kDisconnectWaitUs);
230
231 if (!WriteStringToFile(kGadgetName, PULLUP_PATH)) {
232 ALOGI("Gadget cannot be pulled up");
233 return Status::ERROR;
234 }
235
236 return Status::SUCCESS;
237 }
238
setupFunctions(uint64_t functions,const sp<V1_0::IUsbGadgetCallback> & callback,uint64_t timeout)239 V1_0::Status UsbGadget::setupFunctions(uint64_t functions,
240 const sp<V1_0::IUsbGadgetCallback> &callback,
241 uint64_t timeout) {
242 bool ffsEnabled = false;
243 int i = 0;
244
245 if (addGenericAndroidFunctions(&monitorFfs, functions, &ffsEnabled, &i) != Status::SUCCESS)
246 return Status::ERROR;
247
248 std::string vendorFunctions = getVendorFunctions();
249
250 if (vendorFunctions != "") {
251 ALOGI("enable usbradio debug functions");
252 char *function = strtok(const_cast<char *>(vendorFunctions.c_str()), ",");
253 while (function != NULL) {
254 if (string(function) == "diag" && linkFunction("diag.diag", i++))
255 return Status::ERROR;
256 if (string(function) == "diag_mdm" && linkFunction("diag.diag_mdm", i++))
257 return Status::ERROR;
258 if (string(function) == "qdss" && linkFunction("qdss.qdss", i++))
259 return Status::ERROR;
260 if (string(function) == "qdss_mdm" && linkFunction("qdss.qdss_mdm", i++))
261 return Status::ERROR;
262 if (string(function) == "serial_cdev" && linkFunction("cser.dun.0", i++))
263 return Status::ERROR;
264 if (string(function) == "dpl_gsi" && linkFunction("gsi.dpl", i++))
265 return Status::ERROR;
266 if (string(function) == "rmnet_gsi" && linkFunction("gsi.rmnet", i++))
267 return Status::ERROR;
268 function = strtok(NULL, ",");
269 }
270 }
271
272 if ((functions & GadgetFunction::ADB) != 0) {
273 ffsEnabled = true;
274 if (addAdb(&monitorFfs, &i) != Status::SUCCESS)
275 return Status::ERROR;
276 }
277
278 // Pull up the gadget right away when there are no ffs functions.
279 if (!ffsEnabled) {
280 if (!WriteStringToFile(kGadgetName, PULLUP_PATH))
281 return Status::ERROR;
282 mCurrentUsbFunctionsApplied = true;
283 if (callback)
284 callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS);
285 return Status::SUCCESS;
286 }
287
288 monitorFfs.registerFunctionsAppliedCallback(¤tFunctionsAppliedCallback, this);
289 // Monitors the ffs paths to pull up the gadget when descriptors are written.
290 // Also takes of the pulling up the gadget again if the userspace process
291 // dies and restarts.
292 monitorFfs.startMonitor();
293
294 if (kDebug)
295 ALOGI("Mainthread in Cv");
296
297 if (callback) {
298 bool pullup = monitorFfs.waitForPullUp(timeout);
299 Return<void> ret = callback->setCurrentUsbFunctionsCb(
300 functions, pullup ? Status::SUCCESS : Status::ERROR);
301 if (!ret.isOk())
302 ALOGE("setCurrentUsbFunctionsCb error %s", ret.description().c_str());
303 }
304
305 return Status::SUCCESS;
306 }
307
setCurrentUsbFunctions(uint64_t functions,const sp<V1_0::IUsbGadgetCallback> & callback,uint64_t timeout)308 Return<void> UsbGadget::setCurrentUsbFunctions(uint64_t functions,
309 const sp<V1_0::IUsbGadgetCallback> &callback,
310 uint64_t timeout) {
311 std::unique_lock<std::mutex> lk(mLockSetCurrentFunction);
312
313 mCurrentUsbFunctions = functions;
314 mCurrentUsbFunctionsApplied = false;
315
316 // Unlink the gadget and stop the monitor if running.
317 V1_0::Status status = tearDownGadget();
318 if (status != Status::SUCCESS) {
319 goto error;
320 }
321
322 ALOGI("Returned from tearDown gadget");
323
324 // Leave the gadget pulled down to give time for the host to sense disconnect.
325 usleep(kDisconnectWaitUs);
326
327 if (functions == static_cast<uint64_t>(GadgetFunction::NONE)) {
328 if (callback == NULL)
329 return Void();
330 Return<void> ret = callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS);
331 if (!ret.isOk())
332 ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.description().c_str());
333 return Void();
334 }
335
336 status = validateAndSetVidPid(functions);
337
338 if (status != Status::SUCCESS) {
339 goto error;
340 }
341
342 status = setupFunctions(functions, callback, timeout);
343 if (status != Status::SUCCESS) {
344 goto error;
345 }
346
347 ALOGI("Usb Gadget setcurrent functions called successfully");
348 return Void();
349
350 error:
351 ALOGI("Usb Gadget setcurrent functions failed");
352 if (callback == NULL)
353 return Void();
354 Return<void> ret = callback->setCurrentUsbFunctionsCb(functions, status);
355 if (!ret.isOk())
356 ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.description().c_str());
357 return Void();
358 }
359 } // namespace implementation
360 } // namespace V1_1
361 } // namespace gadget
362 } // namespace usb
363 } // namespace hardware
364 } // namespace android
365