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 (at) 1.0-service.wahoo" 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 constexpr int BUFFER_SIZE = 512; 30 constexpr int MAX_FILE_PATH_LENGTH = 256; 31 constexpr int EPOLL_EVENTS = 10; 32 constexpr bool DEBUG = false; 33 constexpr int DISCONNECT_WAIT_US = 10000; 34 35 #define BUILD_TYPE "ro.build.type" 36 #define GADGET_PATH "/config/usb_gadget/g1/" 37 #define PULLUP_PATH GADGET_PATH "UDC" 38 #define GADGET_NAME "a800000.dwc3" 39 #define PERSISTENT_BOOT_MODE "ro.bootmode" 40 #define VENDOR_ID_PATH GADGET_PATH "idVendor" 41 #define PRODUCT_ID_PATH GADGET_PATH "idProduct" 42 #define DEVICE_CLASS_PATH GADGET_PATH "bDeviceClass" 43 #define DEVICE_SUB_CLASS_PATH GADGET_PATH "bDeviceSubClass" 44 #define DEVICE_PROTOCOL_PATH GADGET_PATH "bDeviceProtocol" 45 #define DESC_USE_PATH GADGET_PATH "os_desc/use" 46 #define OS_DESC_PATH GADGET_PATH "os_desc/b.1" 47 #define CONFIG_PATH GADGET_PATH "configs/b.1/" 48 #define FUNCTIONS_PATH GADGET_PATH "functions/" 49 #define FUNCTION_NAME "function" 50 #define FUNCTION_PATH CONFIG_PATH FUNCTION_NAME 51 #define RNDIS_PATH FUNCTIONS_PATH "gsi.rndis" 52 53 #define PERSISTENT_VENDOR_CONFIG "persist.vendor.usb.usbradio.config" 54 #define VENDOR_CONFIG "vendor.usb.config" 55 56 namespace android { 57 namespace hardware { 58 namespace usb { 59 namespace gadget { 60 namespace V1_0 { 61 namespace implementation { 62 63 volatile bool gadgetPullup; 64 65 // Used for debug. 66 static void displayInotifyEvent(struct inotify_event *i) { 67 ALOGE(" wd =%2d; ", i->wd); 68 if (i->cookie > 0) ALOGE("cookie =%4d; ", i->cookie); 69 70 ALOGE("mask = "); 71 if (i->mask & IN_ACCESS) ALOGE("IN_ACCESS "); 72 if (i->mask & IN_ATTRIB) ALOGE("IN_ATTRIB "); 73 if (i->mask & IN_CLOSE_NOWRITE) ALOGE("IN_CLOSE_NOWRITE "); 74 if (i->mask & IN_CLOSE_WRITE) ALOGE("IN_CLOSE_WRITE "); 75 if (i->mask & IN_CREATE) ALOGE("IN_CREATE "); 76 if (i->mask & IN_DELETE) ALOGE("IN_DELETE "); 77 if (i->mask & IN_DELETE_SELF) ALOGE("IN_DELETE_SELF "); 78 if (i->mask & IN_IGNORED) ALOGE("IN_IGNORED "); 79 if (i->mask & IN_ISDIR) ALOGE("IN_ISDIR "); 80 if (i->mask & IN_MODIFY) ALOGE("IN_MODIFY "); 81 if (i->mask & IN_MOVE_SELF) ALOGE("IN_MOVE_SELF "); 82 if (i->mask & IN_MOVED_FROM) ALOGE("IN_MOVED_FROM "); 83 if (i->mask & IN_MOVED_TO) ALOGE("IN_MOVED_TO "); 84 if (i->mask & IN_OPEN) ALOGE("IN_OPEN "); 85 if (i->mask & IN_Q_OVERFLOW) ALOGE("IN_Q_OVERFLOW "); 86 if (i->mask & IN_UNMOUNT) ALOGE("IN_UNMOUNT "); 87 ALOGE("\n"); 88 89 if (i->len > 0) ALOGE(" name = %s\n", i->name); 90 } 91 92 static void *monitorFfs(void *param) { 93 UsbGadget *usbGadget = (UsbGadget *)param; 94 char buf[BUFFER_SIZE]; 95 bool writeUdc = true, stopMonitor = false; 96 struct epoll_event events[EPOLL_EVENTS]; 97 98 bool descriptorWritten = true; 99 for (int i = 0; i < static_cast<int>(usbGadget->mEndpointList.size()); i++) { 100 if (access(usbGadget->mEndpointList.at(i).c_str(), R_OK)) { 101 descriptorWritten = false; 102 break; 103 } 104 } 105 106 // notify here if the endpoints are already present. 107 if (descriptorWritten && !!WriteStringToFile(GADGET_NAME, PULLUP_PATH)) { 108 lock_guard<mutex> lock(usbGadget->mLock); 109 usbGadget->mCurrentUsbFunctionsApplied = true; 110 gadgetPullup = true; 111 usbGadget->mCv.notify_all(); 112 } 113 114 while (!stopMonitor) { 115 int nrEvents = epoll_wait(usbGadget->mEpollFd, events, EPOLL_EVENTS, -1); 116 if (nrEvents <= 0) { 117 ALOGE("epoll wait did not return descriptor number"); 118 continue; 119 } 120 121 for (int i = 0; i < nrEvents; i++) { 122 ALOGI("event=%u on fd=%d\n", events[i].events, events[i].data.fd); 123 124 if (events[i].data.fd == usbGadget->mInotifyFd) { 125 // Process all of the events in buffer returned by read(). 126 int numRead = read(usbGadget->mInotifyFd, buf, BUFFER_SIZE); 127 for (char *p = buf; p < buf + numRead;) { 128 struct inotify_event *event = (struct inotify_event *)p; 129 if (DEBUG) displayInotifyEvent(event); 130 131 p += sizeof(struct inotify_event) + event->len; 132 133 bool descriptorPresent = true; 134 for (int j = 0; j < static_cast<int>(usbGadget->mEndpointList.size()); 135 j++) { 136 if (access(usbGadget->mEndpointList.at(j).c_str(), R_OK)) { 137 if (DEBUG) 138 ALOGI("%s absent", usbGadget->mEndpointList.at(j).c_str()); 139 descriptorPresent = false; 140 break; 141 } 142 } 143 144 if (!descriptorPresent && !writeUdc) { 145 if (DEBUG) ALOGI("endpoints not up"); 146 writeUdc = true; 147 } else if (descriptorPresent && writeUdc && 148 !!WriteStringToFile(GADGET_NAME, PULLUP_PATH)) { 149 lock_guard<mutex> lock(usbGadget->mLock); 150 usbGadget->mCurrentUsbFunctionsApplied = true; 151 ALOGI("GADGET pulled up"); 152 writeUdc = false; 153 gadgetPullup = true; 154 // notify the main thread to signal userspace. 155 usbGadget->mCv.notify_all(); 156 } 157 } 158 } else { 159 uint64_t flag; 160 read(usbGadget->mEventFd, &flag, sizeof(flag)); 161 if (flag == 100) { 162 stopMonitor = true; 163 break; 164 } 165 } 166 } 167 } 168 return NULL; 169 } 170 171 UsbGadget::UsbGadget() 172 : mMonitorCreated(false), mCurrentUsbFunctionsApplied(false) { 173 if (access(OS_DESC_PATH, R_OK) != 0) ALOGE("configfs setup not done yet"); 174 } 175 176 static int unlinkFunctions(const char *path) { 177 DIR *config = opendir(path); 178 struct dirent *function; 179 char filepath[MAX_FILE_PATH_LENGTH]; 180 int ret = 0; 181 182 if (config == NULL) return -1; 183 184 // d_type does not seems to be supported in /config 185 // so filtering by name. 186 while (((function = readdir(config)) != NULL)) { 187 if ((strstr(function->d_name, FUNCTION_NAME) == NULL)) continue; 188 // build the path for each file in the folder. 189 sprintf(filepath, "%s/%s", path, function->d_name); 190 ret = remove(filepath); 191 if (ret) { 192 ALOGE("Unable remove file %s errno:%d", filepath, errno); 193 break; 194 } 195 } 196 197 closedir(config); 198 return ret; 199 } 200 201 static int addEpollFd(const unique_fd &epfd, const unique_fd &fd) { 202 struct epoll_event event; 203 int ret; 204 205 event.data.fd = fd; 206 event.events = EPOLLIN; 207 208 ret = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event); 209 if (ret) ALOGE("epoll_ctl error %d", errno); 210 211 return ret; 212 } 213 214 Return<void> UsbGadget::getCurrentUsbFunctions( 215 const sp<V1_0::IUsbGadgetCallback> &callback) { 216 Return<void> ret = callback->getCurrentUsbFunctionsCb( 217 mCurrentUsbFunctions, mCurrentUsbFunctionsApplied 218 ? Status::FUNCTIONS_APPLIED 219 : Status::FUNCTIONS_NOT_APPLIED); 220 if (!ret.isOk()) 221 ALOGE("Call to getCurrentUsbFunctionsCb failed %s", 222 ret.description().c_str()); 223 224 return Void(); 225 } 226 227 V1_0::Status UsbGadget::tearDownGadget() { 228 ALOGI("setCurrentUsbFunctions None"); 229 230 if (!WriteStringToFile("none", PULLUP_PATH)) 231 ALOGI("Gadget cannot be pulled down"); 232 233 if (!WriteStringToFile("0", DEVICE_CLASS_PATH)) return Status::ERROR; 234 235 if (!WriteStringToFile("0", DEVICE_SUB_CLASS_PATH)) return Status::ERROR; 236 237 if (!WriteStringToFile("0", DEVICE_PROTOCOL_PATH)) return Status::ERROR; 238 239 if (!WriteStringToFile("0", DESC_USE_PATH)) return Status::ERROR; 240 241 if (unlinkFunctions(CONFIG_PATH)) return Status::ERROR; 242 243 if (mMonitorCreated) { 244 uint64_t flag = 100; 245 // Stop the monitor thread by writing into signal fd. 246 write(mEventFd, &flag, sizeof(flag)); 247 mMonitor->join(); 248 mMonitorCreated = false; 249 ALOGI("mMonitor destroyed"); 250 } else { 251 ALOGI("mMonitor not running"); 252 } 253 254 mInotifyFd.reset(-1); 255 mEventFd.reset(-1); 256 mEpollFd.reset(-1); 257 mEndpointList.clear(); 258 return Status::SUCCESS; 259 } 260 261 static int linkFunction(const char *function, int index) { 262 char functionPath[MAX_FILE_PATH_LENGTH]; 263 char link[MAX_FILE_PATH_LENGTH]; 264 265 sprintf(functionPath, "%s%s", FUNCTIONS_PATH, function); 266 sprintf(link, "%s%d", FUNCTION_PATH, index); 267 if (symlink(functionPath, link)) { 268 ALOGE("Cannot create symlink %s -> %s errno:%d", link, functionPath, errno); 269 return -1; 270 } 271 return 0; 272 } 273 274 static V1_0::Status setVidPid(const char *vid, const char *pid) { 275 if (!WriteStringToFile(vid, VENDOR_ID_PATH)) return Status::ERROR; 276 277 if (!WriteStringToFile(pid, PRODUCT_ID_PATH)) return Status::ERROR; 278 279 return Status::SUCCESS; 280 } 281 282 static std::string getVendorFunctions() { 283 if (GetProperty(BUILD_TYPE, "") == "user") return "user"; 284 285 std::string bootMode = GetProperty(PERSISTENT_BOOT_MODE, ""); 286 std::string persistVendorFunctions = 287 GetProperty(PERSISTENT_VENDOR_CONFIG, ""); 288 std::string vendorFunctions = GetProperty(VENDOR_CONFIG, ""); 289 std::string ret = ""; 290 291 if (vendorFunctions != "") { 292 ret = vendorFunctions; 293 } else if (bootMode == "usbradio") { 294 if (persistVendorFunctions != "") 295 ret = persistVendorFunctions; 296 else 297 ret = "diag"; 298 // vendor.usb.config will reflect the current configured functions 299 SetProperty(VENDOR_CONFIG, ret); 300 } 301 302 return ret; 303 } 304 305 static V1_0::Status validateAndSetVidPid(uint64_t functions) { 306 V1_0::Status ret = Status::SUCCESS; 307 std::string vendorFunctions = getVendorFunctions(); 308 309 switch (functions) { 310 case static_cast<uint64_t>(GadgetFunction::MTP): 311 if (vendorFunctions == "diag") { 312 ret = setVidPid("0x05C6", "0x901B"); 313 } else { 314 if (!(vendorFunctions == "user" || vendorFunctions == "")) 315 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); 316 ret = setVidPid("0x18d1", "0x4ee1"); 317 } 318 break; 319 case GadgetFunction::ADB | GadgetFunction::MTP: 320 if (vendorFunctions == "diag") { 321 ret = setVidPid("0x05C6", "0x903A"); 322 } else { 323 if (!(vendorFunctions == "user" || vendorFunctions == "")) 324 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); 325 ret = setVidPid("0x18d1", "0x4ee2"); 326 } 327 break; 328 case static_cast<uint64_t>(GadgetFunction::RNDIS): 329 if (vendorFunctions == "diag") { 330 ret = setVidPid("0x05C6", "0x902C"); 331 } else if (vendorFunctions == "serial_cdev,diag") { 332 ret = setVidPid("0x05C6", "0x90B5"); 333 } else { 334 if (!(vendorFunctions == "user" || vendorFunctions == "")) 335 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); 336 ret = setVidPid("0x18d1", "0x4ee3"); 337 } 338 break; 339 case GadgetFunction::ADB | GadgetFunction::RNDIS: 340 if (vendorFunctions == "diag") { 341 ret = setVidPid("0x05C6", "0x902D"); 342 } else if (vendorFunctions == "serial_cdev,diag") { 343 ret = setVidPid("0x05C6", "0x90B6"); 344 } else { 345 if (!(vendorFunctions == "user" || vendorFunctions == "")) 346 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); 347 ret = setVidPid("0x18d1", "0x4ee4"); 348 } 349 break; 350 case static_cast<uint64_t>(GadgetFunction::PTP): 351 if (!(vendorFunctions == "user" || vendorFunctions == "")) 352 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); 353 ret = setVidPid("0x18d1", "0x4ee5"); 354 break; 355 case GadgetFunction::ADB | GadgetFunction::PTP: 356 if (!(vendorFunctions == "user" || vendorFunctions == "")) 357 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); 358 ret = setVidPid("0x18d1", "0x4ee6"); 359 break; 360 case static_cast<uint64_t>(GadgetFunction::ADB): 361 if (vendorFunctions == "diag") { 362 ret = setVidPid("0x05C6", "0x901D"); 363 } else if (vendorFunctions == "diag,serial_cdev,rmnet_gsi") { 364 ret = setVidPid("0x05C6", "0x9091"); 365 } else if (vendorFunctions == "diag,serial_cdev") { 366 ret = setVidPid("0x05C6", "0x901F"); 367 } else { 368 if (!(vendorFunctions == "user" || vendorFunctions == "")) 369 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); 370 ret = setVidPid("0x18d1", "0x4ee7"); 371 } 372 break; 373 case static_cast<uint64_t>(GadgetFunction::MIDI): 374 if (!(vendorFunctions == "user" || vendorFunctions == "")) 375 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); 376 ret = setVidPid("0x18d1", "0x4ee8"); 377 break; 378 case GadgetFunction::ADB | GadgetFunction::MIDI: 379 if (!(vendorFunctions == "user" || vendorFunctions == "")) 380 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); 381 ret = setVidPid("0x18d1", "0x4ee9"); 382 break; 383 case static_cast<uint64_t>(GadgetFunction::ACCESSORY): 384 if (!(vendorFunctions == "user" || vendorFunctions == "")) 385 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); 386 ret = setVidPid("0x18d1", "0x2d00"); 387 break; 388 case GadgetFunction::ADB | GadgetFunction::ACCESSORY: 389 if (!(vendorFunctions == "user" || vendorFunctions == "")) 390 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); 391 ret = setVidPid("0x18d1", "0x2d01"); 392 break; 393 case static_cast<uint64_t>(GadgetFunction::AUDIO_SOURCE): 394 if (!(vendorFunctions == "user" || vendorFunctions == "")) 395 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); 396 ret = setVidPid("0x18d1", "0x2d02"); 397 break; 398 case GadgetFunction::ADB | GadgetFunction::AUDIO_SOURCE: 399 if (!(vendorFunctions == "user" || vendorFunctions == "")) 400 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); 401 ret = setVidPid("0x18d1", "0x2d03"); 402 break; 403 case GadgetFunction::ACCESSORY | GadgetFunction::AUDIO_SOURCE: 404 if (!(vendorFunctions == "user" || vendorFunctions == "")) 405 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); 406 ret = setVidPid("0x18d1", "0x2d04"); 407 break; 408 case GadgetFunction::ADB | GadgetFunction::ACCESSORY | 409 GadgetFunction::AUDIO_SOURCE: 410 if (!(vendorFunctions == "user" || vendorFunctions == "")) 411 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); 412 ret = setVidPid("0x18d1", "0x2d05"); 413 break; 414 default: 415 ALOGE("Combination not supported"); 416 ret = Status::CONFIGURATION_NOT_SUPPORTED; 417 } 418 return ret; 419 } 420 421 V1_0::Status UsbGadget::setupFunctions( 422 uint64_t functions, const sp<V1_0::IUsbGadgetCallback> &callback, 423 uint64_t timeout) { 424 std::unique_lock<std::mutex> lk(mLock); 425 426 unique_fd inotifyFd(inotify_init()); 427 if (inotifyFd < 0) { 428 ALOGE("inotify init failed"); 429 return Status::ERROR; 430 } 431 432 bool ffsEnabled = false; 433 int i = 0; 434 std::string bootMode = GetProperty(PERSISTENT_BOOT_MODE, ""); 435 436 if (((functions & GadgetFunction::MTP) != 0)) { 437 ffsEnabled = true; 438 ALOGI("setCurrentUsbFunctions mtp"); 439 if (!WriteStringToFile("1", DESC_USE_PATH)) return Status::ERROR; 440 441 if (inotify_add_watch(inotifyFd, "/dev/usb-ffs/mtp/", IN_ALL_EVENTS) == -1) 442 return Status::ERROR; 443 444 if (linkFunction("ffs.mtp", i++)) return Status::ERROR; 445 446 // Add endpoints to be monitored. 447 mEndpointList.push_back("/dev/usb-ffs/mtp/ep1"); 448 mEndpointList.push_back("/dev/usb-ffs/mtp/ep2"); 449 mEndpointList.push_back("/dev/usb-ffs/mtp/ep3"); 450 } else if (((functions & GadgetFunction::PTP) != 0)) { 451 ffsEnabled = true; 452 ALOGI("setCurrentUsbFunctions ptp"); 453 if (!WriteStringToFile("1", DESC_USE_PATH)) return Status::ERROR; 454 455 if (inotify_add_watch(inotifyFd, "/dev/usb-ffs/ptp/", IN_ALL_EVENTS) == -1) 456 return Status::ERROR; 457 458 459 if (linkFunction("ffs.ptp", i++)) return Status::ERROR; 460 461 // Add endpoints to be monitored. 462 mEndpointList.push_back("/dev/usb-ffs/ptp/ep1"); 463 mEndpointList.push_back("/dev/usb-ffs/ptp/ep2"); 464 mEndpointList.push_back("/dev/usb-ffs/ptp/ep3"); 465 } 466 467 if ((functions & GadgetFunction::MIDI) != 0) { 468 ALOGI("setCurrentUsbFunctions MIDI"); 469 if (linkFunction("midi.gs5", i++)) return Status::ERROR; 470 } 471 472 if ((functions & GadgetFunction::ACCESSORY) != 0) { 473 ALOGI("setCurrentUsbFunctions Accessory"); 474 if (linkFunction("accessory.gs2", i++)) return Status::ERROR; 475 } 476 477 if ((functions & GadgetFunction::AUDIO_SOURCE) != 0) { 478 ALOGI("setCurrentUsbFunctions Audio Source"); 479 if (linkFunction("audio_source.gs3", i++)) return Status::ERROR; 480 } 481 482 if ((functions & GadgetFunction::RNDIS) != 0) { 483 ALOGI("setCurrentUsbFunctions rndis"); 484 if (linkFunction("gsi.rndis", i++)) return Status::ERROR; 485 } 486 487 std::string vendorFunctions = getVendorFunctions(); 488 if (vendorFunctions != "") { 489 ALOGI("enable usbradio debug functions"); 490 char *function = strtok(const_cast<char *>(vendorFunctions.c_str()), ","); 491 while (function != NULL) { 492 if (string(function) == "diag" && linkFunction("diag.diag", i++)) 493 return Status::ERROR; 494 if (string(function) == "serial_cdev" && linkFunction("cser.dun.0", i++)) 495 return Status::ERROR; 496 if (string(function) == "rmnet_gsi" && linkFunction("gsi.rmnet", i++)) 497 return Status::ERROR; 498 function = strtok(NULL, ","); 499 } 500 } 501 502 if ((functions & GadgetFunction::ADB) != 0) { 503 ffsEnabled = true; 504 ALOGI("setCurrentUsbFunctions Adb"); 505 if (inotify_add_watch(inotifyFd, "/dev/usb-ffs/adb/", IN_ALL_EVENTS) == -1) 506 return Status::ERROR; 507 508 if (linkFunction("ffs.adb", i++)) return Status::ERROR; 509 mEndpointList.push_back("/dev/usb-ffs/adb/ep1"); 510 mEndpointList.push_back("/dev/usb-ffs/adb/ep2"); 511 ALOGI("Service started"); 512 } 513 514 // Pull up the gadget right away when there are no ffs functions. 515 if (!ffsEnabled) { 516 if (!WriteStringToFile(GADGET_NAME, PULLUP_PATH)) return Status::ERROR; 517 mCurrentUsbFunctionsApplied = true; 518 if (callback) 519 callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS); 520 return Status::SUCCESS; 521 } 522 523 unique_fd eventFd(eventfd(0, 0)); 524 if (eventFd == -1) { 525 ALOGE("mEventFd failed to create %d", errno); 526 return Status::ERROR; 527 } 528 529 unique_fd epollFd(epoll_create(2)); 530 if (epollFd == -1) { 531 ALOGE("mEpollFd failed to create %d", errno); 532 return Status::ERROR; 533 } 534 535 if (addEpollFd(epollFd, inotifyFd) == -1) return Status::ERROR; 536 537 if (addEpollFd(epollFd, eventFd) == -1) return Status::ERROR; 538 539 mEpollFd = move(epollFd); 540 mInotifyFd = move(inotifyFd); 541 mEventFd = move(eventFd); 542 gadgetPullup = false; 543 544 // Monitors the ffs paths to pull up the gadget when descriptors are written. 545 // Also takes of the pulling up the gadget again if the userspace process 546 // dies and restarts. 547 mMonitor = unique_ptr<thread>(new thread(monitorFfs, this)); 548 mMonitorCreated = true; 549 if (DEBUG) ALOGI("Mainthread in Cv"); 550 551 if (callback) { 552 if (mCv.wait_for(lk, timeout * 1ms, [] { return gadgetPullup; })) { 553 ALOGI("monitorFfs signalled true"); 554 } else { 555 ALOGI("monitorFfs signalled error"); 556 // continue monitoring as the descriptors might be written at a later 557 // point. 558 } 559 Return<void> ret = callback->setCurrentUsbFunctionsCb( 560 functions, gadgetPullup ? Status::SUCCESS : Status::ERROR); 561 if (!ret.isOk()) 562 ALOGE("setCurrentUsbFunctionsCb error %s", ret.description().c_str()); 563 } 564 565 return Status::SUCCESS; 566 } 567 568 Return<void> UsbGadget::setCurrentUsbFunctions( 569 uint64_t functions, const sp<V1_0::IUsbGadgetCallback> &callback, 570 uint64_t timeout) { 571 std::unique_lock<std::mutex> lk(mLockSetCurrentFunction); 572 573 mCurrentUsbFunctions = functions; 574 mCurrentUsbFunctionsApplied = false; 575 576 // Unlink the gadget and stop the monitor if running. 577 V1_0::Status status = tearDownGadget(); 578 if (status != Status::SUCCESS) { 579 goto error; 580 } 581 582 // Leave the gadget pulled down to give time for the host to sense disconnect. 583 usleep(DISCONNECT_WAIT_US); 584 585 if (functions == static_cast<uint64_t>(GadgetFunction::NONE)) { 586 if (callback == NULL) return Void(); 587 Return<void> ret = 588 callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS); 589 if (!ret.isOk()) 590 ALOGE("Error while calling setCurrentUsbFunctionsCb %s", 591 ret.description().c_str()); 592 return Void(); 593 } 594 595 status = validateAndSetVidPid(functions); 596 597 if (status != Status::SUCCESS) { 598 goto error; 599 } 600 601 status = setupFunctions(functions, callback, timeout); 602 if (status != Status::SUCCESS) { 603 goto error; 604 } 605 606 ALOGI("Usb Gadget setcurrent functions called successfully"); 607 return Void(); 608 609 error: 610 ALOGI("Usb Gadget setcurrent functions failed"); 611 if (callback == NULL) return Void(); 612 Return<void> ret = callback->setCurrentUsbFunctionsCb(functions, status); 613 if (!ret.isOk()) 614 ALOGE("Error while calling setCurrentUsbFunctionsCb %s", 615 ret.description().c_str()); 616 return Void(); 617 } 618 } // namespace implementation 619 } // namespace V1_0 620 } // namespace gadget 621 } // namespace usb 622 } // namespace hardware 623 } // namespace android 624