• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&currentFunctionsAppliedCallback, 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