• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/corennnnn


Commit MetaInfo

Revision3fd82b8861aa410fab7785074941b459d92220c1 (tree)
Zeit2009-05-10 04:49:54
AutorDima Zavin <dima@andr...>
CommiterDima Zavin

Log Message

adb: osx: Match devices based on interface subclass and protocol

Enumerating all vendor+product id combinations is not practical.
This modifies the matching algorithm to use the adb interface
subclass/protocol instead (0x42/0x1).

Signed-off-by: Dima Zavin <dima@android.com>

Ändern Zusammenfassung

Diff

--- a/adb/adb.h
+++ b/adb/adb.h
@@ -359,17 +359,10 @@ typedef enum {
359359
360360 // Google's USB Vendor ID
361361 #define VENDOR_ID_GOOGLE 0x18d1
362+
362363 // HTC's USB Vendor ID
363364 #define VENDOR_ID_HTC 0x0bb4
364365
365-// products for VENDOR_ID_GOOGLE
366-#define PRODUCT_ID_SOONER 0xd00d // Sooner bootloader
367-#define PRODUCT_ID_SOONER_COMP 0xdeed // Sooner composite device
368-
369-// products for VENDOR_ID_HTC
370-#define PRODUCT_ID_DREAM 0x0c01 // Dream bootloader
371-#define PRODUCT_ID_DREAM_COMP 0x0c02 // Dream composite device
372-
373366 void local_init();
374367 int local_connect(int port);
375368
--- a/adb/usb_osx.c
+++ b/adb/usb_osx.c
@@ -31,21 +31,17 @@
3131
3232 #define DBG D
3333
34-typedef struct {
35- int vid;
36- int pid;
37-} VendorProduct;
38-
39-#define kSupportedDeviceCount 4
40-VendorProduct kSupportedDevices[kSupportedDeviceCount] = {
41- { VENDOR_ID_GOOGLE, PRODUCT_ID_SOONER },
42- { VENDOR_ID_GOOGLE, PRODUCT_ID_SOONER_COMP },
43- { VENDOR_ID_HTC, PRODUCT_ID_DREAM },
44- { VENDOR_ID_HTC, PRODUCT_ID_DREAM_COMP },
34+#define ADB_SUBCLASS 0x42
35+#define ADB_PROTOCOL 0x1
36+
37+int vendorIds[] = {
38+ VENDOR_ID_GOOGLE,
39+ VENDOR_ID_HTC,
4540 };
41+#define NUM_VENDORS (sizeof(vendorIds)/sizeof(vendorIds[0]))
4642
4743 static IONotificationPortRef notificationPort = 0;
48-static io_iterator_t notificationIterators[kSupportedDeviceCount];
44+static io_iterator_t notificationIterators[NUM_VENDORS];
4945
5046 struct usb_handle
5147 {
@@ -61,17 +57,20 @@ static pthread_mutex_t start_lock;
6157 static pthread_cond_t start_cond;
6258
6359
64-static void AndroidDeviceAdded(void *refCon, io_iterator_t iterator);
65-static void AndroidDeviceNotify(void *refCon, io_iterator_t iterator, natural_t messageType, void *messageArgument);
66-static usb_handle* FindDeviceInterface(IOUSBDeviceInterface **dev, UInt16 vendor, UInt16 product);
60+static void AndroidInterfaceAdded(void *refCon, io_iterator_t iterator);
61+static void AndroidInterfaceNotify(void *refCon, io_iterator_t iterator,
62+ natural_t messageType,
63+ void *messageArgument);
64+static usb_handle* CheckInterface(IOUSBInterfaceInterface **iface,
65+ UInt16 vendor, UInt16 product);
6766
6867 static int
6968 InitUSB()
7069 {
7170 CFMutableDictionaryRef matchingDict;
7271 CFRunLoopSourceRef runLoopSource;
73- SInt32 vendor, product;
74- int i;
72+ SInt32 vendor, if_subclass, if_protocol;
73+ unsigned i;
7574
7675 //* To set up asynchronous notifications, create a notification port and
7776 //* add its run loop event source to the program's run loop
@@ -81,51 +80,57 @@ InitUSB()
8180
8281 memset(notificationIterators, 0, sizeof(notificationIterators));
8382
84- //* loop through all supported vendor/product pairs
85- for (i = 0; i < kSupportedDeviceCount; i++) {
86- //* Create our matching dictionary to find the Android device
87- //* IOServiceAddMatchingNotification consumes the reference, so we do not need to release this
88- matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
83+ //* loop through all supported vendors
84+ for (i = 0; i < NUM_VENDORS; i++) {
85+ //* Create our matching dictionary to find the Android device's
86+ //* adb interface
87+ //* IOServiceAddMatchingNotification consumes the reference, so we do
88+ //* not need to release this
89+ matchingDict = IOServiceMatching(kIOUSBInterfaceClassName);
8990
9091 if (!matchingDict) {
9192 DBG("ERR: Couldn't create USB matching dictionary.\n");
9293 return -1;
9394 }
9495
95- //* Set up two matching dictionaries, one for each product ID we support.
96- //* This will cause the kernel to notify us only if the vendor and product IDs match.
97- vendor = kSupportedDevices[i].vid;
98- product = kSupportedDevices[i].pid;
99- CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vendor));
100- CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &product));
101-
102- //* Now set up two notifications: one to be called when a raw device
103- //* is first matched by the I/O Kit and another to be called when the
104- //* device is terminated.
105- //* we need to do this with each matching dictionary.
96+ //* Match based on vendor id, interface subclass and protocol
97+ vendor = vendorIds[i];
98+ if_subclass = ADB_SUBCLASS;
99+ if_protocol = ADB_PROTOCOL;
100+ CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID),
101+ CFNumberCreate(kCFAllocatorDefault,
102+ kCFNumberSInt32Type, &vendor));
103+ CFDictionarySetValue(matchingDict, CFSTR(kUSBInterfaceSubClass),
104+ CFNumberCreate(kCFAllocatorDefault,
105+ kCFNumberSInt32Type, &if_subclass));
106+ CFDictionarySetValue(matchingDict, CFSTR(kUSBInterfaceProtocol),
107+ CFNumberCreate(kCFAllocatorDefault,
108+ kCFNumberSInt32Type, &if_protocol));
106109 IOServiceAddMatchingNotification(
107110 notificationPort,
108111 kIOFirstMatchNotification,
109112 matchingDict,
110- AndroidDeviceAdded,
113+ AndroidInterfaceAdded,
111114 NULL,
112115 &notificationIterators[i]);
113116
114- //* Iterate over set of matching devices to access already-present devices
115- //* and to arm the notification
116- AndroidDeviceAdded(NULL, notificationIterators[i]);
117+ //* Iterate over set of matching interfaces to access already-present
118+ //* devices and to arm the notification
119+ AndroidInterfaceAdded(NULL, notificationIterators[i]);
117120 }
118121
119122 return 0;
120123 }
121124
122125 static void
123-AndroidDeviceAdded(void *refCon, io_iterator_t iterator)
126+AndroidInterfaceAdded(void *refCon, io_iterator_t iterator)
124127 {
125128 kern_return_t kr;
126129 io_service_t usbDevice;
130+ io_service_t usbInterface;
127131 IOCFPlugInInterface **plugInInterface = NULL;
128- IOUSBDeviceInterface182 **dev = NULL;
132+ IOUSBInterfaceInterface220 **iface = NULL;
133+ IOUSBDeviceInterface197 **dev = NULL;
129134 HRESULT result;
130135 SInt32 score;
131136 UInt16 vendor;
@@ -133,28 +138,66 @@ AndroidDeviceAdded(void *refCon, io_iterator_t iterator)
133138 UInt8 serialIndex;
134139 char serial[256];
135140
136- while ((usbDevice = IOIteratorNext(iterator))) {
137- //* Create an intermediate plugin
141+ while ((usbInterface = IOIteratorNext(iterator))) {
142+ //* Create an intermediate interface plugin
143+ kr = IOCreatePlugInInterfaceForService(usbInterface,
144+ kIOUSBInterfaceUserClientTypeID,
145+ kIOCFPlugInInterfaceID,
146+ &plugInInterface, &score);
147+ IOObjectRelease(usbInterface);
148+ if ((kIOReturnSuccess != kr) || (!plugInInterface)) {
149+ DBG("ERR: Unable to create an interface plug-in (%08x)\n", kr);
150+ continue;
151+ }
152+
153+ //* This gets us the interface object
154+ result = (*plugInInterface)->QueryInterface(plugInInterface,
155+ CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID)
156+ &iface);
157+ //* We only needed the plugin to get the interface, so discard it
158+ (*plugInInterface)->Release(plugInInterface);
159+ if (result || !iface) {
160+ DBG("ERR: Couldn't query the interface (%08x)\n", (int) result);
161+ continue;
162+ }
163+
164+ //* this gets us an ioservice, with which we will find the actual
165+ //* device; after getting a plugin, and querying the interface, of
166+ //* course.
167+ //* Gotta love OS X
168+ kr = (*iface)->GetDevice(iface, &usbDevice);
169+ if (kIOReturnSuccess != kr || !usbDevice) {
170+ DBG("ERR: Couldn't grab device from interface (%08x)\n", kr);
171+ continue;
172+ }
173+
174+ plugInInterface = NULL;
175+ score = 0;
176+ //* create an intermediate device plugin
138177 kr = IOCreatePlugInInterfaceForService(usbDevice,
139178 kIOUSBDeviceUserClientTypeID,
140179 kIOCFPlugInInterfaceID,
141180 &plugInInterface, &score);
142-
181+ //* only needed this to find the plugin
182+ (void)IOObjectRelease(usbDevice);
143183 if ((kIOReturnSuccess != kr) || (!plugInInterface)) {
144- DBG("ERR: Unable to create a plug-in (%08x)\n", kr);
145- goto continue1;
184+ DBG("ERR: Unable to create a device plug-in (%08x)\n", kr);
185+ continue;
146186 }
147187
148- //* Now create the device interface
149188 result = (*plugInInterface)->QueryInterface(plugInInterface,
150189 CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID) &dev);
151-
190+ //* only needed this to query the plugin
191+ (*plugInInterface)->Release(plugInInterface);
152192 if (result || !dev) {
153- DBG("ERR: Couldn't create a device interface (%08x)\n", (int) result);
154- goto continue2;
193+ DBG("ERR: Couldn't create a device interface (%08x)\n",
194+ (int) result);
195+ continue;
155196 }
156197
157- //* Check the device to see if it's ours
198+ //* Now after all that, we actually have a ref to the device and
199+ //* the interface that matched our criteria
200+
158201 kr = (*dev)->GetDeviceVendor(dev, &vendor);
159202 kr = (*dev)->GetDeviceProduct(dev, &product);
160203 kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex);
@@ -163,7 +206,8 @@ AndroidDeviceAdded(void *refCon, io_iterator_t iterator)
163206 IOUSBDevRequest req;
164207 UInt16 buffer[256];
165208
166- req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
209+ req.bmRequestType =
210+ USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
167211 req.bRequest = kUSBRqGetDescriptor;
168212 req.wValue = (kUSBStringDesc << 8) | serialIndex;
169213 req.wIndex = 0;
@@ -174,219 +218,149 @@ AndroidDeviceAdded(void *refCon, io_iterator_t iterator)
174218 if (kr == kIOReturnSuccess && req.wLenDone > 0) {
175219 int i, count;
176220
177- // skip first word, and copy the rest to the serial string, changing shorts to bytes.
221+ // skip first word, and copy the rest to the serial string,
222+ // changing shorts to bytes.
178223 count = (req.wLenDone - 1) / 2;
179224 for (i = 0; i < count; i++)
180225 serial[i] = buffer[i + 1];
181226 serial[i] = 0;
182227 }
183228 }
229+ (*dev)->Release(dev);
184230
185- usb_handle* handle = NULL;
186-
187- //* Open the device
188- kr = (*dev)->USBDeviceOpen(dev);
189-
190- if (kr != kIOReturnSuccess) {
191- DBG("ERR: Could not open device: %08x\n", kr);
192- goto continue3;
193- } else {
194- //* Find an interface for the device
195- handle = FindDeviceInterface((IOUSBDeviceInterface**)dev, vendor, product);
196- }
231+ DBG("INFO: Found vid=%04x pid=%04x serial=%s\n", vendor, product,
232+ serial);
197233
234+ usb_handle* handle = CheckInterface((IOUSBInterfaceInterface**)iface,
235+ vendor, product);
198236 if (handle == NULL) {
199237 DBG("ERR: Could not find device interface: %08x\n", kr);
200- (*dev)->USBDeviceClose(dev);
201- goto continue3;
238+ (*iface)->Release(iface);
239+ continue;
202240 }
203241
204242 DBG("AndroidDeviceAdded calling register_usb_transport\n");
205243 register_usb_transport(handle, (serial[0] ? serial : NULL));
206244
207- // Register for an interest notification of this device being removed. Pass the reference to our
208- // private data as the refCon for the notification.
245+ // Register for an interest notification of this device being removed.
246+ // Pass the reference to our private data as the refCon for the
247+ // notification.
209248 kr = IOServiceAddInterestNotification(notificationPort,
210- usbDevice,
249+ usbInterface,
211250 kIOGeneralInterest,
212- AndroidDeviceNotify,
251+ AndroidInterfaceNotify,
213252 handle,
214253 &handle->usbNotification);
254+
215255 if (kIOReturnSuccess != kr) {
216256 DBG("ERR: Unable to create interest notification (%08x)\n", kr);
217257 }
218-
219-continue3:
220- (void)(*dev)->Release(dev);
221-continue2:
222- IODestroyPlugInInterface(plugInInterface);
223-continue1:
224- IOObjectRelease(usbDevice);
225258 }
226259 }
227260
228261 static void
229-AndroidDeviceNotify(void *refCon, io_service_t service, natural_t messageType, void *messageArgument)
262+AndroidInterfaceNotify(void *refCon, io_service_t service, natural_t messageType, void *messageArgument)
230263 {
231264 usb_handle *handle = (usb_handle *)refCon;
232265
233266 if (messageType == kIOMessageServiceIsTerminated) {
234- DBG("AndroidDeviceNotify\n");
267+ if (!handle) {
268+ DBG("ERR: NULL handle\n");
269+ return;
270+ }
271+ DBG("AndroidInterfaceNotify\n");
235272 IOObjectRelease(handle->usbNotification);
236273 usb_kick(handle);
237274 }
238275 }
239276
277+//* TODO: simplify this further since we only register to get ADB interface
278+//* subclass+protocol events
240279 static usb_handle*
241-FindDeviceInterface(IOUSBDeviceInterface **dev, UInt16 vendor, UInt16 product)
280+CheckInterface(IOUSBInterfaceInterface **interface, UInt16 vendor, UInt16 product)
242281 {
243282 usb_handle* handle = NULL;
244283 IOReturn kr;
245- IOUSBFindInterfaceRequest request;
246- io_iterator_t iterator;
247- io_service_t usbInterface;
248- IOCFPlugInInterface **plugInInterface;
249- IOUSBInterfaceInterface **interface = NULL;
250- HRESULT result;
251- SInt32 score;
252284 UInt8 interfaceNumEndpoints, interfaceClass, interfaceSubClass, interfaceProtocol;
253- UInt8 endpoint, configuration;
285+ UInt8 endpoint;
254286
255- //* Placing the constant KIOUSBFindInterfaceDontCare into the following
256- //* fields of the IOUSBFindInterfaceRequest structure will allow us to
257- //* find all of the interfaces
258- request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
259- request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
260- request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
261- request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
262-
263- //* SetConfiguration will kill an existing UMS connection, so let's not do this if not necessary.
264- configuration = 0;
265- (*dev)->GetConfiguration(dev, &configuration);
266- if (configuration != 1)
267- (*dev)->SetConfiguration(dev, 1);
268-
269- //* Get an iterator for the interfaces on the device
270- kr = (*dev)->CreateInterfaceIterator(dev, &request, &iterator);
271287
288+ //* Now open the interface. This will cause the pipes associated with
289+ //* the endpoints in the interface descriptor to be instantiated
290+ kr = (*interface)->USBInterfaceOpen(interface);
272291 if (kr != kIOReturnSuccess) {
273- DBG("ERR: Couldn't create a device interface iterator: (%08x)\n", kr);
292+ DBG("ERR: Could not open interface: (%08x)\n", kr);
274293 return NULL;
275294 }
276295
277- while ((usbInterface = IOIteratorNext(iterator))) {
278- //* Create an intermediate plugin
279- kr = IOCreatePlugInInterfaceForService(
280- usbInterface,
281- kIOUSBInterfaceUserClientTypeID,
282- kIOCFPlugInInterfaceID,
283- &plugInInterface,
284- &score);
285-
286- //* No longer need the usbInterface object now that we have the plugin
287- (void) IOObjectRelease(usbInterface);
288-
289- if ((kr != kIOReturnSuccess) || (!plugInInterface)) {
290- DBG("ERR: Unable to create plugin (%08x)\n", kr);
291- break;
292- }
293-
294- //* Now create the interface interface for the interface
295- result = (*plugInInterface)->QueryInterface(
296- plugInInterface,
297- CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID),
298- (LPVOID) &interface);
299-
300- //* No longer need the intermediate plugin
301- (*plugInInterface)->Release(plugInInterface);
302-
303- if (result || !interface) {
304- DBG("ERR: Couldn't create interface interface: (%08x)\n",
305- (unsigned int) result);
306- break;
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-
313- if (kr != kIOReturnSuccess)
314- {
315- DBG("ERR: Could not open interface: (%08x)\n", kr);
316- (void) (*interface)->Release(interface);
317- //* continue so we can try the next interface
318- continue;
319- }
320-
321- //* Get the number of endpoints associated with this interface
322- kr = (*interface)->GetNumEndpoints(interface, &interfaceNumEndpoints);
323-
324- if (kr != kIOReturnSuccess) {
325- DBG("ERR: Unable to get number of endpoints: (%08x)\n", kr);
326- goto next_interface;
327- }
296+ //* Get the number of endpoints associated with this interface
297+ kr = (*interface)->GetNumEndpoints(interface, &interfaceNumEndpoints);
298+ if (kr != kIOReturnSuccess) {
299+ DBG("ERR: Unable to get number of endpoints: (%08x)\n", kr);
300+ goto err_get_num_ep;
301+ }
328302
329- //* Get interface class, subclass and protocol
330- if ((*interface)->GetInterfaceClass(interface, &interfaceClass) != kIOReturnSuccess ||
303+ //* Get interface class, subclass and protocol
304+ if ((*interface)->GetInterfaceClass(interface, &interfaceClass) != kIOReturnSuccess ||
331305 (*interface)->GetInterfaceSubClass(interface, &interfaceSubClass) != kIOReturnSuccess ||
332- (*interface)->GetInterfaceProtocol(interface, &interfaceProtocol) != kIOReturnSuccess)
333- {
306+ (*interface)->GetInterfaceProtocol(interface, &interfaceProtocol) != kIOReturnSuccess) {
334307 DBG("ERR: Unable to get interface class, subclass and protocol\n");
335- goto next_interface;
336- }
337-
338- //* check to make sure interface class, subclass and protocol match ADB
339- //* avoid opening mass storage endpoints
340- if (is_adb_interface(vendor, product, interfaceClass, interfaceSubClass, interfaceProtocol)) {
341- handle = calloc(1, sizeof(usb_handle));
308+ goto err_get_interface_class;
309+ }
342310
343- //* Iterate over the endpoints for this interface and find the first
344- //* bulk in/out pipes available. These will be our read/write pipes.
345- for (endpoint = 0; endpoint <= interfaceNumEndpoints; endpoint++) {
346- UInt8 transferType;
347- UInt16 maxPacketSize;
348- UInt8 interval;
349- UInt8 number;
350- UInt8 direction;
311+ //* check to make sure interface class, subclass and protocol match ADB
312+ //* avoid opening mass storage endpoints
313+ if (!is_adb_interface(vendor, product, interfaceClass,
314+ interfaceSubClass, interfaceProtocol))
315+ goto err_bad_adb_interface;
351316
352- kr = (*interface)->GetPipeProperties(interface, endpoint, &direction,
353- &number, &transferType, &maxPacketSize, &interval);
317+ handle = calloc(1, sizeof(usb_handle));
354318
355- if (kIOReturnSuccess == kr) {
356- if (kUSBBulk != transferType)
357- continue;
319+ //* Iterate over the endpoints for this interface and find the first
320+ //* bulk in/out pipes available. These will be our read/write pipes.
321+ for (endpoint = 0; endpoint <= interfaceNumEndpoints; endpoint++) {
322+ UInt8 transferType;
323+ UInt16 maxPacketSize;
324+ UInt8 interval;
325+ UInt8 number;
326+ UInt8 direction;
358327
359- if (kUSBIn == direction)
360- handle->bulkIn = endpoint;
328+ kr = (*interface)->GetPipeProperties(interface, endpoint, &direction,
329+ &number, &transferType, &maxPacketSize, &interval);
361330
362- if (kUSBOut == direction)
363- handle->bulkOut = endpoint;
331+ if (kIOReturnSuccess == kr) {
332+ if (kUSBBulk != transferType)
333+ continue;
364334
365- if (interfaceProtocol == 0x01) {
366- handle->zero_mask = maxPacketSize - 1;
367- }
335+ if (kUSBIn == direction)
336+ handle->bulkIn = endpoint;
368337
369- } else {
370- DBG("ERR: FindDeviceInterface - could not get pipe properties\n");
371- }
372- }
338+ if (kUSBOut == direction)
339+ handle->bulkOut = endpoint;
373340
374- handle->interface = interface;
375- break;
341+ handle->zero_mask = maxPacketSize - 1;
342+ } else {
343+ DBG("ERR: FindDeviceInterface - could not get pipe properties\n");
344+ goto err_get_pipe_props;
376345 }
377-
378-next_interface:
379- (*interface)->USBInterfaceClose(interface);
380- (*interface)->Release(interface);
381346 }
382347
348+ handle->interface = interface;
383349 return handle;
350+
351+err_get_pipe_props:
352+ free(handle);
353+err_bad_adb_interface:
354+err_get_interface_class:
355+err_get_num_ep:
356+ (*interface)->USBInterfaceClose(interface);
357+ return NULL;
384358 }
385359
386360
387361 void* RunLoopThread(void* unused)
388362 {
389- int i;
363+ unsigned i;
390364
391365 InitUSB();
392366
@@ -400,7 +374,7 @@ void* RunLoopThread(void* unused)
400374 CFRunLoopRun();
401375 currentRunLoop = 0;
402376
403- for (i = 0; i < kSupportedDeviceCount; i++) {
377+ for (i = 0; i < NUM_VENDORS; i++) {
404378 IOObjectRelease(notificationIterators[i]);
405379 }
406380 IONotificationPortDestroy(notificationPort);
@@ -527,6 +501,9 @@ int usb_close(usb_handle *handle)
527501 void usb_kick(usb_handle *handle)
528502 {
529503 /* release the interface */
504+ if (!handle)
505+ return;
506+
530507 if (handle->interface)
531508 {
532509 (*handle->interface)->USBInterfaceClose(handle->interface);