1/* 2 * Copyright (C) 2007 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 TRACE_TAG TRACE_USB 18 19#include "sysdeps.h" 20 21#include <CoreFoundation/CoreFoundation.h> 22 23#include <IOKit/IOKitLib.h> 24#include <IOKit/IOCFPlugIn.h> 25#include <IOKit/usb/IOUSBLib.h> 26#include <IOKit/IOMessage.h> 27#include <mach/mach_port.h> 28 29#include <inttypes.h> 30#include <stdio.h> 31 32#include "adb.h" 33#include "transport.h" 34 35#define DBG D 36 37static IONotificationPortRef notificationPort = 0; 38static io_iterator_t notificationIterator; 39 40struct usb_handle 41{ 42 UInt8 bulkIn; 43 UInt8 bulkOut; 44 IOUSBInterfaceInterface **interface; 45 io_object_t usbNotification; 46 unsigned int zero_mask; 47}; 48 49static CFRunLoopRef currentRunLoop = 0; 50static pthread_mutex_t start_lock; 51static pthread_cond_t start_cond; 52 53 54static void AndroidInterfaceAdded(void *refCon, io_iterator_t iterator); 55static void AndroidInterfaceNotify(void *refCon, io_iterator_t iterator, 56 natural_t messageType, 57 void *messageArgument); 58static usb_handle* CheckInterface(IOUSBInterfaceInterface **iface, 59 UInt16 vendor, UInt16 product); 60 61static int 62InitUSB() 63{ 64 CFMutableDictionaryRef matchingDict; 65 CFRunLoopSourceRef runLoopSource; 66 67 //* To set up asynchronous notifications, create a notification port and 68 //* add its run loop event source to the program's run loop 69 notificationPort = IONotificationPortCreate(kIOMasterPortDefault); 70 runLoopSource = IONotificationPortGetRunLoopSource(notificationPort); 71 CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode); 72 73 //* Create our matching dictionary to find the Android device's 74 //* adb interface 75 //* IOServiceAddMatchingNotification consumes the reference, so we do 76 //* not need to release this 77 matchingDict = IOServiceMatching(kIOUSBInterfaceClassName); 78 79 if (!matchingDict) { 80 DBG("ERR: Couldn't create USB matching dictionary.\n"); 81 return -1; 82 } 83 84 //* We have to get notifications for all potential candidates and test them 85 //* at connection time because the matching rules don't allow for a 86 //* USB interface class of 0xff for class+subclass+protocol matches 87 //* See https://developer.apple.com/library/mac/qa/qa1076/_index.html 88 IOServiceAddMatchingNotification( 89 notificationPort, 90 kIOFirstMatchNotification, 91 matchingDict, 92 AndroidInterfaceAdded, 93 NULL, 94 ¬ificationIterator); 95 96 //* Iterate over set of matching interfaces to access already-present 97 //* devices and to arm the notification 98 AndroidInterfaceAdded(NULL, notificationIterator); 99 100 return 0; 101} 102 103static void 104AndroidInterfaceAdded(void *refCon, io_iterator_t iterator) 105{ 106 kern_return_t kr; 107 io_service_t usbDevice; 108 io_service_t usbInterface; 109 IOCFPlugInInterface **plugInInterface = NULL; 110 IOUSBInterfaceInterface220 **iface = NULL; 111 IOUSBDeviceInterface197 **dev = NULL; 112 HRESULT result; 113 SInt32 score; 114 UInt32 locationId; 115 UInt8 if_class, subclass, protocol; 116 UInt16 vendor; 117 UInt16 product; 118 UInt8 serialIndex; 119 char serial[256]; 120 char devpathBuf[64]; 121 char *devpath = NULL; 122 123 while ((usbInterface = IOIteratorNext(iterator))) { 124 //* Create an intermediate interface plugin 125 kr = IOCreatePlugInInterfaceForService(usbInterface, 126 kIOUSBInterfaceUserClientTypeID, 127 kIOCFPlugInInterfaceID, 128 &plugInInterface, &score); 129 IOObjectRelease(usbInterface); 130 if ((kIOReturnSuccess != kr) || (!plugInInterface)) { 131 DBG("ERR: Unable to create an interface plug-in (%08x)\n", kr); 132 continue; 133 } 134 135 //* This gets us the interface object 136 result = (*plugInInterface)->QueryInterface( 137 plugInInterface, 138 CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID*)&iface); 139 //* We only needed the plugin to get the interface, so discard it 140 (*plugInInterface)->Release(plugInInterface); 141 if (result || !iface) { 142 DBG("ERR: Couldn't query the interface (%08x)\n", (int) result); 143 continue; 144 } 145 146 kr = (*iface)->GetInterfaceClass(iface, &if_class); 147 kr = (*iface)->GetInterfaceSubClass(iface, &subclass); 148 kr = (*iface)->GetInterfaceProtocol(iface, &protocol); 149 if(if_class != ADB_CLASS || subclass != ADB_SUBCLASS || protocol != ADB_PROTOCOL) { 150 // Ignore non-ADB devices. 151 DBG("Ignoring interface with incorrect class/subclass/protocol - %d, %d, %d\n", if_class, subclass, protocol); 152 (*iface)->Release(iface); 153 continue; 154 } 155 156 //* this gets us an ioservice, with which we will find the actual 157 //* device; after getting a plugin, and querying the interface, of 158 //* course. 159 //* Gotta love OS X 160 kr = (*iface)->GetDevice(iface, &usbDevice); 161 if (kIOReturnSuccess != kr || !usbDevice) { 162 DBG("ERR: Couldn't grab device from interface (%08x)\n", kr); 163 continue; 164 } 165 166 plugInInterface = NULL; 167 score = 0; 168 //* create an intermediate device plugin 169 kr = IOCreatePlugInInterfaceForService(usbDevice, 170 kIOUSBDeviceUserClientTypeID, 171 kIOCFPlugInInterfaceID, 172 &plugInInterface, &score); 173 //* only needed this to find the plugin 174 (void)IOObjectRelease(usbDevice); 175 if ((kIOReturnSuccess != kr) || (!plugInInterface)) { 176 DBG("ERR: Unable to create a device plug-in (%08x)\n", kr); 177 continue; 178 } 179 180 result = (*plugInInterface)->QueryInterface(plugInInterface, 181 CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*)&dev); 182 //* only needed this to query the plugin 183 (*plugInInterface)->Release(plugInInterface); 184 if (result || !dev) { 185 DBG("ERR: Couldn't create a device interface (%08x)\n", 186 (int) result); 187 continue; 188 } 189 190 //* Now after all that, we actually have a ref to the device and 191 //* the interface that matched our criteria 192 kr = (*dev)->GetDeviceVendor(dev, &vendor); 193 kr = (*dev)->GetDeviceProduct(dev, &product); 194 kr = (*dev)->GetLocationID(dev, &locationId); 195 if (kr == 0) { 196 snprintf(devpathBuf, sizeof(devpathBuf), "usb:%" PRIu32 "X", 197 (unsigned int)locationId); 198 devpath = devpathBuf; 199 } 200 kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex); 201 202 if (serialIndex > 0) { 203 IOUSBDevRequest req; 204 UInt16 buffer[256]; 205 UInt16 languages[128]; 206 207 memset(languages, 0, sizeof(languages)); 208 209 req.bmRequestType = 210 USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); 211 req.bRequest = kUSBRqGetDescriptor; 212 req.wValue = (kUSBStringDesc << 8) | 0; 213 req.wIndex = 0; 214 req.pData = languages; 215 req.wLength = sizeof(languages); 216 kr = (*dev)->DeviceRequest(dev, &req); 217 218 if (kr == kIOReturnSuccess && req.wLenDone > 0) { 219 220 int langCount = (req.wLenDone - 2) / 2, lang; 221 222 for (lang = 1; lang <= langCount; lang++) { 223 224 memset(buffer, 0, sizeof(buffer)); 225 memset(&req, 0, sizeof(req)); 226 227 req.bmRequestType = 228 USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); 229 req.bRequest = kUSBRqGetDescriptor; 230 req.wValue = (kUSBStringDesc << 8) | serialIndex; 231 req.wIndex = languages[lang]; 232 req.pData = buffer; 233 req.wLength = sizeof(buffer); 234 kr = (*dev)->DeviceRequest(dev, &req); 235 236 if (kr == kIOReturnSuccess && req.wLenDone > 0) { 237 int i, count; 238 239 // skip first word, and copy the rest to the serial string, 240 // changing shorts to bytes. 241 count = (req.wLenDone - 1) / 2; 242 for (i = 0; i < count; i++) 243 serial[i] = buffer[i + 1]; 244 serial[i] = 0; 245 break; 246 } 247 } 248 } 249 } 250 (*dev)->Release(dev); 251 252 DBG("INFO: Found vid=%04x pid=%04x serial=%s\n", vendor, product, 253 serial); 254 255 usb_handle* handle = CheckInterface((IOUSBInterfaceInterface**)iface, 256 vendor, product); 257 if (handle == NULL) { 258 DBG("ERR: Could not find device interface: %08x\n", kr); 259 (*iface)->Release(iface); 260 continue; 261 } 262 263 DBG("AndroidDeviceAdded calling register_usb_transport\n"); 264 register_usb_transport(handle, (serial[0] ? serial : NULL), devpath, 1); 265 266 // Register for an interest notification of this device being removed. 267 // Pass the reference to our private data as the refCon for the 268 // notification. 269 kr = IOServiceAddInterestNotification(notificationPort, 270 usbInterface, 271 kIOGeneralInterest, 272 AndroidInterfaceNotify, 273 handle, 274 &handle->usbNotification); 275 276 if (kIOReturnSuccess != kr) { 277 DBG("ERR: Unable to create interest notification (%08x)\n", kr); 278 } 279 } 280} 281 282static void 283AndroidInterfaceNotify(void *refCon, io_service_t service, natural_t messageType, void *messageArgument) 284{ 285 usb_handle *handle = (usb_handle *)refCon; 286 287 if (messageType == kIOMessageServiceIsTerminated) { 288 if (!handle) { 289 DBG("ERR: NULL handle\n"); 290 return; 291 } 292 DBG("AndroidInterfaceNotify\n"); 293 IOObjectRelease(handle->usbNotification); 294 usb_kick(handle); 295 } 296} 297 298//* TODO: simplify this further since we only register to get ADB interface 299//* subclass+protocol events 300static usb_handle* 301CheckInterface(IOUSBInterfaceInterface **interface, UInt16 vendor, UInt16 product) 302{ 303 usb_handle* handle = NULL; 304 IOReturn kr; 305 UInt8 interfaceNumEndpoints, interfaceClass, interfaceSubClass, interfaceProtocol; 306 UInt8 endpoint; 307 308 309 //* Now open the interface. This will cause the pipes associated with 310 //* the endpoints in the interface descriptor to be instantiated 311 kr = (*interface)->USBInterfaceOpen(interface); 312 if (kr != kIOReturnSuccess) { 313 DBG("ERR: Could not open interface: (%08x)\n", kr); 314 return NULL; 315 } 316 317 //* Get the number of endpoints associated with this interface 318 kr = (*interface)->GetNumEndpoints(interface, &interfaceNumEndpoints); 319 if (kr != kIOReturnSuccess) { 320 DBG("ERR: Unable to get number of endpoints: (%08x)\n", kr); 321 goto err_get_num_ep; 322 } 323 324 //* Get interface class, subclass and protocol 325 if ((*interface)->GetInterfaceClass(interface, &interfaceClass) != kIOReturnSuccess || 326 (*interface)->GetInterfaceSubClass(interface, &interfaceSubClass) != kIOReturnSuccess || 327 (*interface)->GetInterfaceProtocol(interface, &interfaceProtocol) != kIOReturnSuccess) { 328 DBG("ERR: Unable to get interface class, subclass and protocol\n"); 329 goto err_get_interface_class; 330 } 331 332 //* check to make sure interface class, subclass and protocol match ADB 333 //* avoid opening mass storage endpoints 334 if (!is_adb_interface(vendor, product, interfaceClass, 335 interfaceSubClass, interfaceProtocol)) 336 goto err_bad_adb_interface; 337 338 handle = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle))); 339 if (handle == nullptr) goto err_bad_adb_interface; 340 341 //* Iterate over the endpoints for this interface and find the first 342 //* bulk in/out pipes available. These will be our read/write pipes. 343 for (endpoint = 0; endpoint <= interfaceNumEndpoints; endpoint++) { 344 UInt8 transferType; 345 UInt16 maxPacketSize; 346 UInt8 interval; 347 UInt8 number; 348 UInt8 direction; 349 350 kr = (*interface)->GetPipeProperties(interface, endpoint, &direction, 351 &number, &transferType, &maxPacketSize, &interval); 352 353 if (kIOReturnSuccess == kr) { 354 if (kUSBBulk != transferType) 355 continue; 356 357 if (kUSBIn == direction) 358 handle->bulkIn = endpoint; 359 360 if (kUSBOut == direction) 361 handle->bulkOut = endpoint; 362 363 handle->zero_mask = maxPacketSize - 1; 364 } else { 365 DBG("ERR: FindDeviceInterface - could not get pipe properties\n"); 366 goto err_get_pipe_props; 367 } 368 } 369 370 handle->interface = interface; 371 return handle; 372 373err_get_pipe_props: 374 free(handle); 375err_bad_adb_interface: 376err_get_interface_class: 377err_get_num_ep: 378 (*interface)->USBInterfaceClose(interface); 379 return NULL; 380} 381 382 383void* RunLoopThread(void* unused) 384{ 385 InitUSB(); 386 387 currentRunLoop = CFRunLoopGetCurrent(); 388 389 // Signal the parent that we are running 390 adb_mutex_lock(&start_lock); 391 adb_cond_signal(&start_cond); 392 adb_mutex_unlock(&start_lock); 393 394 CFRunLoopRun(); 395 currentRunLoop = 0; 396 397 IOObjectRelease(notificationIterator); 398 IONotificationPortDestroy(notificationPort); 399 400 DBG("RunLoopThread done\n"); 401 return NULL; 402} 403 404 405static int initialized = 0; 406void usb_init() 407{ 408 if (!initialized) 409 { 410 adb_thread_t tid; 411 412 adb_mutex_init(&start_lock, NULL); 413 adb_cond_init(&start_cond, NULL); 414 415 if(adb_thread_create(&tid, RunLoopThread, NULL)) 416 fatal_errno("cannot create input thread"); 417 418 // Wait for initialization to finish 419 adb_mutex_lock(&start_lock); 420 adb_cond_wait(&start_cond, &start_lock); 421 adb_mutex_unlock(&start_lock); 422 423 adb_mutex_destroy(&start_lock); 424 adb_cond_destroy(&start_cond); 425 426 initialized = 1; 427 } 428} 429 430void usb_cleanup() 431{ 432 DBG("usb_cleanup\n"); 433 close_usb_devices(); 434 if (currentRunLoop) 435 CFRunLoopStop(currentRunLoop); 436} 437 438int usb_write(usb_handle *handle, const void *buf, int len) 439{ 440 IOReturn result; 441 442 if (!len) 443 return 0; 444 445 if (!handle) 446 return -1; 447 448 if (NULL == handle->interface) { 449 DBG("ERR: usb_write interface was null\n"); 450 return -1; 451 } 452 453 if (0 == handle->bulkOut) { 454 DBG("ERR: bulkOut endpoint not assigned\n"); 455 return -1; 456 } 457 458 result = 459 (*handle->interface)->WritePipe( 460 handle->interface, handle->bulkOut, (void *)buf, len); 461 462 if ((result == 0) && (handle->zero_mask)) { 463 /* we need 0-markers and our transfer */ 464 if(!(len & handle->zero_mask)) { 465 result = 466 (*handle->interface)->WritePipe( 467 handle->interface, handle->bulkOut, (void *)buf, 0); 468 } 469 } 470 471 if (0 == result) 472 return 0; 473 474 DBG("ERR: usb_write failed with status %d\n", result); 475 return -1; 476} 477 478int usb_read(usb_handle *handle, void *buf, int len) 479{ 480 IOReturn result; 481 UInt32 numBytes = len; 482 483 if (!len) { 484 return 0; 485 } 486 487 if (!handle) { 488 return -1; 489 } 490 491 if (NULL == handle->interface) { 492 DBG("ERR: usb_read interface was null\n"); 493 return -1; 494 } 495 496 if (0 == handle->bulkIn) { 497 DBG("ERR: bulkIn endpoint not assigned\n"); 498 return -1; 499 } 500 501 result = (*handle->interface)->ReadPipe(handle->interface, handle->bulkIn, buf, &numBytes); 502 503 if (kIOUSBPipeStalled == result) { 504 DBG(" Pipe stalled, clearing stall.\n"); 505 (*handle->interface)->ClearPipeStall(handle->interface, handle->bulkIn); 506 result = (*handle->interface)->ReadPipe(handle->interface, handle->bulkIn, buf, &numBytes); 507 } 508 509 if (kIOReturnSuccess == result) 510 return 0; 511 else { 512 DBG("ERR: usb_read failed with status %x\n", result); 513 } 514 515 return -1; 516} 517 518int usb_close(usb_handle *handle) 519{ 520 return 0; 521} 522 523void usb_kick(usb_handle *handle) 524{ 525 /* release the interface */ 526 if (!handle) 527 return; 528 529 if (handle->interface) 530 { 531 (*handle->interface)->USBInterfaceClose(handle->interface); 532 (*handle->interface)->Release(handle->interface); 533 handle->interface = 0; 534 } 535} 536