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.coral"
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 ==
155                        "diag,diag_mdm,qdss,qdss_mdm,serial_cdev,dpl_gsi,rmnet_gsi") {
156                 ret = setVidPid("0x05C6", "0x90E5");
157             } else {
158                 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
159                     ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
160                     ret = Status::CONFIGURATION_NOT_SUPPORTED;
161                 } else {
162                     ret = setVidPid("0x18d1", "0x4ee7");
163                 }
164             }
165             break;
166         case static_cast<uint64_t>(GadgetFunction::MIDI):
167             if (!(vendorFunctions == "user" || vendorFunctions == "")) {
168                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
169                 ret = Status::CONFIGURATION_NOT_SUPPORTED;
170             } else {
171                 ret = setVidPid("0x18d1", "0x4ee8");
172             }
173             break;
174         case GadgetFunction::ADB | GadgetFunction::MIDI:
175             if (!(vendorFunctions == "user" || vendorFunctions == "")) {
176                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
177                 ret = Status::CONFIGURATION_NOT_SUPPORTED;
178             } else {
179                 ret = setVidPid("0x18d1", "0x4ee9");
180             }
181             break;
182         case static_cast<uint64_t>(GadgetFunction::ACCESSORY):
183             if (!(vendorFunctions == "user" || vendorFunctions == ""))
184                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
185             ret = setVidPid("0x18d1", "0x2d00");
186             break;
187         case GadgetFunction::ADB | GadgetFunction::ACCESSORY:
188             if (!(vendorFunctions == "user" || vendorFunctions == ""))
189                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
190             ret = setVidPid("0x18d1", "0x2d01");
191             break;
192         case static_cast<uint64_t>(GadgetFunction::AUDIO_SOURCE):
193             if (!(vendorFunctions == "user" || vendorFunctions == ""))
194                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
195             ret = setVidPid("0x18d1", "0x2d02");
196             break;
197         case GadgetFunction::ADB | GadgetFunction::AUDIO_SOURCE:
198             if (!(vendorFunctions == "user" || vendorFunctions == ""))
199                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
200             ret = setVidPid("0x18d1", "0x2d03");
201             break;
202         case GadgetFunction::ACCESSORY | GadgetFunction::AUDIO_SOURCE:
203             if (!(vendorFunctions == "user" || vendorFunctions == ""))
204                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
205             ret = setVidPid("0x18d1", "0x2d04");
206             break;
207         case GadgetFunction::ADB | GadgetFunction::ACCESSORY | GadgetFunction::AUDIO_SOURCE:
208             if (!(vendorFunctions == "user" || vendorFunctions == ""))
209                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
210             ret = setVidPid("0x18d1", "0x2d05");
211             break;
212         default:
213             ALOGE("Combination not supported");
214             ret = Status::CONFIGURATION_NOT_SUPPORTED;
215     }
216     return ret;
217 }
218 
reset()219 Return<Status> UsbGadget::reset() {
220     if (!WriteStringToFile("none", PULLUP_PATH)) {
221         ALOGI("Gadget cannot be pulled down");
222         return Status::ERROR;
223     }
224 
225     return Status::SUCCESS;
226 }
227 
setupFunctions(uint64_t functions,const sp<V1_0::IUsbGadgetCallback> & callback,uint64_t timeout)228 V1_0::Status UsbGadget::setupFunctions(uint64_t functions,
229                                        const sp<V1_0::IUsbGadgetCallback> &callback,
230                                        uint64_t timeout) {
231     bool ffsEnabled = false;
232     int i = 0;
233 
234     if (addGenericAndroidFunctions(&monitorFfs, functions, &ffsEnabled, &i) != Status::SUCCESS)
235         return Status::ERROR;
236 
237     std::string vendorFunctions = getVendorFunctions();
238 
239     if (vendorFunctions != "") {
240         ALOGI("enable usbradio debug functions");
241         char *function = strtok(const_cast<char *>(vendorFunctions.c_str()), ",");
242         while (function != NULL) {
243             if (string(function) == "diag" && linkFunction("diag.diag", i++))
244                 return Status::ERROR;
245             if (string(function) == "diag_mdm" && linkFunction("diag.diag_mdm", i++))
246                 return Status::ERROR;
247             if (string(function) == "qdss" && linkFunction("qdss.qdss", i++))
248                 return Status::ERROR;
249             if (string(function) == "qdss_mdm" && linkFunction("qdss.qdss_mdm", i++))
250                 return Status::ERROR;
251             if (string(function) == "serial_cdev" && linkFunction("cser.dun.0", i++))
252                 return Status::ERROR;
253             if (string(function) == "dpl_gsi" && linkFunction("gsi.dpl", i++))
254                 return Status::ERROR;
255             if (string(function) == "rmnet_gsi" && linkFunction("gsi.rmnet", i++))
256                 return Status::ERROR;
257             function = strtok(NULL, ",");
258         }
259     }
260 
261     if ((functions & GadgetFunction::ADB) != 0) {
262         ffsEnabled = true;
263         if (addAdb(&monitorFfs, &i) != Status::SUCCESS)
264             return Status::ERROR;
265     }
266 
267     // Pull up the gadget right away when there are no ffs functions.
268     if (!ffsEnabled) {
269         if (!WriteStringToFile(kGadgetName, PULLUP_PATH))
270             return Status::ERROR;
271         mCurrentUsbFunctionsApplied = true;
272         if (callback)
273             callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS);
274         return Status::SUCCESS;
275     }
276 
277     monitorFfs.registerFunctionsAppliedCallback(&currentFunctionsAppliedCallback, this);
278     // Monitors the ffs paths to pull up the gadget when descriptors are written.
279     // Also takes of the pulling up the gadget again if the userspace process
280     // dies and restarts.
281     monitorFfs.startMonitor();
282 
283     if (kDebug)
284         ALOGI("Mainthread in Cv");
285 
286     if (callback) {
287         bool pullup = monitorFfs.waitForPullUp(timeout);
288         Return<void> ret = callback->setCurrentUsbFunctionsCb(
289             functions, pullup ? Status::SUCCESS : Status::ERROR);
290         if (!ret.isOk())
291             ALOGE("setCurrentUsbFunctionsCb error %s", ret.description().c_str());
292     }
293 
294     return Status::SUCCESS;
295 }
296 
setCurrentUsbFunctions(uint64_t functions,const sp<V1_0::IUsbGadgetCallback> & callback,uint64_t timeout)297 Return<void> UsbGadget::setCurrentUsbFunctions(uint64_t functions,
298                                                const sp<V1_0::IUsbGadgetCallback> &callback,
299                                                uint64_t timeout) {
300     std::unique_lock<std::mutex> lk(mLockSetCurrentFunction);
301 
302     mCurrentUsbFunctions = functions;
303     mCurrentUsbFunctionsApplied = false;
304 
305     // Unlink the gadget and stop the monitor if running.
306     V1_0::Status status = tearDownGadget();
307     if (status != Status::SUCCESS) {
308         goto error;
309     }
310 
311     ALOGI("Returned from tearDown gadget");
312 
313     // Leave the gadget pulled down to give time for the host to sense disconnect.
314     usleep(kDisconnectWaitUs);
315 
316     if (functions == static_cast<uint64_t>(GadgetFunction::NONE)) {
317         if (callback == NULL)
318             return Void();
319         Return<void> ret = callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS);
320         if (!ret.isOk())
321             ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.description().c_str());
322         return Void();
323     }
324 
325     status = validateAndSetVidPid(functions);
326 
327     if (status != Status::SUCCESS) {
328         goto error;
329     }
330 
331     status = setupFunctions(functions, callback, timeout);
332     if (status != Status::SUCCESS) {
333         goto error;
334     }
335 
336     ALOGI("Usb Gadget setcurrent functions called successfully");
337     return Void();
338 
339 error:
340     ALOGI("Usb Gadget setcurrent functions failed");
341     if (callback == NULL)
342         return Void();
343     Return<void> ret = callback->setCurrentUsbFunctionsCb(functions, status);
344     if (!ret.isOk())
345         ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.description().c_str());
346     return Void();
347 }
348 }  // namespace implementation
349 }  // namespace V1_1
350 }  // namespace gadget
351 }  // namespace usb
352 }  // namespace hardware
353 }  // namespace android
354