• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <winsock2.h>
18 #include <windows.h>
19 #include <winerror.h>
20 #include <errno.h>
21 #include <usb100.h>
22 #include <adb_api.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 
26 #include "sysdeps.h"
27 
28 #define   TRACE_TAG  TRACE_USB
29 #include "adb.h"
30 
31 /** Structure usb_handle describes our connection to the usb device via
32   AdbWinApi.dll. This structure is returned from usb_open() routine and
33   is expected in each subsequent call that is accessing the device.
34 */
35 struct usb_handle {
36   /// Previous entry in the list of opened usb handles
37   usb_handle *prev;
38 
39   /// Next entry in the list of opened usb handles
40   usb_handle *next;
41 
42   /// Handle to USB interface
43   ADBAPIHANDLE  adb_interface;
44 
45   /// Handle to USB read pipe (endpoint)
46   ADBAPIHANDLE  adb_read_pipe;
47 
48   /// Handle to USB write pipe (endpoint)
49   ADBAPIHANDLE  adb_write_pipe;
50 
51   /// Interface name
52   char*         interface_name;
53 
54   /// Mask for determining when to use zero length packets
55   unsigned zero_mask;
56 };
57 
58 /// Class ID assigned to the device by androidusb.sys
59 static const GUID usb_class_id = ANDROID_USB_CLASS_ID;
60 
61 /// List of opened usb handles
62 static usb_handle handle_list = {
63   .prev = &handle_list,
64   .next = &handle_list,
65 };
66 
67 /// Locker for the list of opened usb handles
68 ADB_MUTEX_DEFINE( usb_lock );
69 
70 /// Checks if there is opened usb handle in handle_list for this device.
71 int known_device(const char* dev_name);
72 
73 /// Checks if there is opened usb handle in handle_list for this device.
74 /// usb_lock mutex must be held before calling this routine.
75 int known_device_locked(const char* dev_name);
76 
77 /// Registers opened usb handle (adds it to handle_list).
78 int register_new_device(usb_handle* handle);
79 
80 /// Checks if interface (device) matches certain criteria
81 int recognized_device(usb_handle* handle);
82 
83 /// Enumerates present and available interfaces (devices), opens new ones and
84 /// registers usb transport for them.
85 void find_devices();
86 
87 /// Entry point for thread that polls (every second) for new usb interfaces.
88 /// This routine calls find_devices in infinite loop.
89 void* device_poll_thread(void* unused);
90 
91 /// Initializes this module
92 void usb_init();
93 
94 /// Cleans up this module
95 void usb_cleanup();
96 
97 /// Opens usb interface (device) by interface (device) name.
98 usb_handle* do_usb_open(const wchar_t* interface_name);
99 
100 /// Writes data to the opened usb handle
101 int usb_write(usb_handle* handle, const void* data, int len);
102 
103 /// Reads data using the opened usb handle
104 int usb_read(usb_handle *handle, void* data, int len);
105 
106 /// Cleans up opened usb handle
107 void usb_cleanup_handle(usb_handle* handle);
108 
109 /// Cleans up (but don't close) opened usb handle
110 void usb_kick(usb_handle* handle);
111 
112 /// Closes opened usb handle
113 int usb_close(usb_handle* handle);
114 
115 /// Gets interface (device) name for an opened usb handle
116 const char *usb_name(usb_handle* handle);
117 
known_device_locked(const char * dev_name)118 int known_device_locked(const char* dev_name) {
119   usb_handle* usb;
120 
121   if (NULL != dev_name) {
122     // Iterate through the list looking for the name match.
123     for(usb = handle_list.next; usb != &handle_list; usb = usb->next) {
124       // In Windows names are not case sensetive!
125       if((NULL != usb->interface_name) &&
126          (0 == stricmp(usb->interface_name, dev_name))) {
127         return 1;
128       }
129     }
130   }
131 
132   return 0;
133 }
134 
known_device(const char * dev_name)135 int known_device(const char* dev_name) {
136   int ret = 0;
137 
138   if (NULL != dev_name) {
139     adb_mutex_lock(&usb_lock);
140     ret = known_device_locked(dev_name);
141     adb_mutex_unlock(&usb_lock);
142   }
143 
144   return ret;
145 }
146 
register_new_device(usb_handle * handle)147 int register_new_device(usb_handle* handle) {
148   if (NULL == handle)
149     return 0;
150 
151   adb_mutex_lock(&usb_lock);
152 
153   // Check if device is already in the list
154   if (known_device_locked(handle->interface_name)) {
155     adb_mutex_unlock(&usb_lock);
156     return 0;
157   }
158 
159   // Not in the list. Add this handle to the list.
160   handle->next = &handle_list;
161   handle->prev = handle_list.prev;
162   handle->prev->next = handle;
163   handle->next->prev = handle;
164 
165   adb_mutex_unlock(&usb_lock);
166 
167   return 1;
168 }
169 
device_poll_thread(void * unused)170 void* device_poll_thread(void* unused) {
171   D("Created device thread\n");
172 
173   while(1) {
174     find_devices();
175     adb_sleep_ms(1000);
176   }
177 
178   return NULL;
179 }
180 
usb_init()181 void usb_init() {
182   adb_thread_t tid;
183 
184   if(adb_thread_create(&tid, device_poll_thread, NULL)) {
185     fatal_errno("cannot create input thread");
186   }
187 }
188 
usb_cleanup()189 void usb_cleanup() {
190 }
191 
do_usb_open(const wchar_t * interface_name)192 usb_handle* do_usb_open(const wchar_t* interface_name) {
193   // Allocate our handle
194   usb_handle* ret = (usb_handle*)malloc(sizeof(usb_handle));
195   if (NULL == ret)
196     return NULL;
197 
198   // Set linkers back to the handle
199   ret->next = ret;
200   ret->prev = ret;
201 
202   // Create interface.
203   ret->adb_interface = AdbCreateInterfaceByName(interface_name);
204 
205   if (NULL == ret->adb_interface) {
206     free(ret);
207     errno = GetLastError();
208     return NULL;
209   }
210 
211   // Open read pipe (endpoint)
212   ret->adb_read_pipe =
213     AdbOpenDefaultBulkReadEndpoint(ret->adb_interface,
214                                    AdbOpenAccessTypeReadWrite,
215                                    AdbOpenSharingModeReadWrite);
216   if (NULL != ret->adb_read_pipe) {
217     // Open write pipe (endpoint)
218     ret->adb_write_pipe =
219       AdbOpenDefaultBulkWriteEndpoint(ret->adb_interface,
220                                       AdbOpenAccessTypeReadWrite,
221                                       AdbOpenSharingModeReadWrite);
222     if (NULL != ret->adb_write_pipe) {
223       // Save interface name
224       unsigned long name_len = 0;
225 
226       // First get expected name length
227       AdbGetInterfaceName(ret->adb_interface,
228                           NULL,
229                           &name_len,
230                           true);
231       if (0 != name_len) {
232         ret->interface_name = (char*)malloc(name_len);
233 
234         if (NULL != ret->interface_name) {
235           // Now save the name
236           if (AdbGetInterfaceName(ret->adb_interface,
237                                   ret->interface_name,
238                                   &name_len,
239                                   true)) {
240             // We're done at this point
241             return ret;
242           }
243         } else {
244           SetLastError(ERROR_OUTOFMEMORY);
245         }
246       }
247     }
248   }
249 
250   // Something went wrong.
251   int saved_errno = GetLastError();
252   usb_cleanup_handle(ret);
253   free(ret);
254   SetLastError(saved_errno);
255 
256   return NULL;
257 }
258 
usb_write(usb_handle * handle,const void * data,int len)259 int usb_write(usb_handle* handle, const void* data, int len) {
260   unsigned long time_out = 5000;
261   unsigned long written = 0;
262   int ret;
263 
264   D("usb_write %d\n", len);
265   if (NULL != handle) {
266     // Perform write
267     ret = AdbWriteEndpointSync(handle->adb_write_pipe,
268                                (void*)data,
269                                (unsigned long)len,
270                                &written,
271                                time_out);
272     int saved_errno = GetLastError();
273 
274     if (ret) {
275       // Make sure that we've written what we were asked to write
276       D("usb_write got: %ld, expected: %d\n", written, len);
277       if (written == (unsigned long)len) {
278         if(handle->zero_mask && (len & handle->zero_mask) == 0) {
279           // Send a zero length packet
280           AdbWriteEndpointSync(handle->adb_write_pipe,
281                                (void*)data,
282                                0,
283                                &written,
284                                time_out);
285         }
286         return 0;
287       }
288     } else {
289       // assume ERROR_INVALID_HANDLE indicates we are disconnected
290       if (saved_errno == ERROR_INVALID_HANDLE)
291         usb_kick(handle);
292     }
293     errno = saved_errno;
294   } else {
295     D("usb_write NULL handle\n");
296     SetLastError(ERROR_INVALID_HANDLE);
297   }
298 
299   D("usb_write failed: %d\n", errno);
300 
301   return -1;
302 }
303 
usb_read(usb_handle * handle,void * data,int len)304 int usb_read(usb_handle *handle, void* data, int len) {
305   unsigned long time_out = 0;
306   unsigned long read = 0;
307   int ret;
308 
309   D("usb_read %d\n", len);
310   if (NULL != handle) {
311     while (len > 0) {
312       int xfer = (len > 4096) ? 4096 : len;
313 
314       ret = AdbReadEndpointSync(handle->adb_read_pipe,
315                                   data,
316                                   (unsigned long)xfer,
317                                   &read,
318                                   time_out);
319       int saved_errno = GetLastError();
320       D("usb_write got: %ld, expected: %d, errno: %d\n", read, xfer, saved_errno);
321       if (ret) {
322         data = (char *)data + read;
323         len -= read;
324 
325         if (len == 0)
326           return 0;
327       } else {
328         // assume ERROR_INVALID_HANDLE indicates we are disconnected
329         if (saved_errno == ERROR_INVALID_HANDLE)
330           usb_kick(handle);
331         break;
332       }
333       errno = saved_errno;
334     }
335   } else {
336     D("usb_read NULL handle\n");
337     SetLastError(ERROR_INVALID_HANDLE);
338   }
339 
340   D("usb_read failed: %d\n", errno);
341 
342   return -1;
343 }
344 
usb_cleanup_handle(usb_handle * handle)345 void usb_cleanup_handle(usb_handle* handle) {
346   if (NULL != handle) {
347     if (NULL != handle->interface_name)
348       free(handle->interface_name);
349     if (NULL != handle->adb_write_pipe)
350       AdbCloseHandle(handle->adb_write_pipe);
351     if (NULL != handle->adb_read_pipe)
352       AdbCloseHandle(handle->adb_read_pipe);
353     if (NULL != handle->adb_interface)
354       AdbCloseHandle(handle->adb_interface);
355 
356     handle->interface_name = NULL;
357     handle->adb_write_pipe = NULL;
358     handle->adb_read_pipe = NULL;
359     handle->adb_interface = NULL;
360   }
361 }
362 
usb_kick(usb_handle * handle)363 void usb_kick(usb_handle* handle) {
364   if (NULL != handle) {
365     adb_mutex_lock(&usb_lock);
366 
367     usb_cleanup_handle(handle);
368 
369     adb_mutex_unlock(&usb_lock);
370   } else {
371     SetLastError(ERROR_INVALID_HANDLE);
372     errno = ERROR_INVALID_HANDLE;
373   }
374 }
375 
usb_close(usb_handle * handle)376 int usb_close(usb_handle* handle) {
377   D("usb_close\n");
378 
379   if (NULL != handle) {
380     // Remove handle from the list
381     adb_mutex_lock(&usb_lock);
382 
383     if ((handle->next != handle) && (handle->prev != handle)) {
384       handle->next->prev = handle->prev;
385       handle->prev->next = handle->next;
386       handle->prev = handle;
387       handle->next = handle;
388     }
389 
390     adb_mutex_unlock(&usb_lock);
391 
392     // Cleanup handle
393     usb_cleanup_handle(handle);
394     free(handle);
395   }
396 
397   return 0;
398 }
399 
usb_name(usb_handle * handle)400 const char *usb_name(usb_handle* handle) {
401   if (NULL == handle) {
402     SetLastError(ERROR_INVALID_HANDLE);
403     errno = ERROR_INVALID_HANDLE;
404     return NULL;
405   }
406 
407   return (const char*)handle->interface_name;
408 }
409 
recognized_device(usb_handle * handle)410 int recognized_device(usb_handle* handle) {
411   if (NULL == handle)
412     return 0;
413 
414   // Check vendor and product id first
415   USB_DEVICE_DESCRIPTOR device_desc;
416 
417   if (!AdbGetUsbDeviceDescriptor(handle->adb_interface,
418                                  &device_desc)) {
419     return 0;
420   }
421 
422   // Then check interface properties
423   USB_INTERFACE_DESCRIPTOR interf_desc;
424 
425   if (!AdbGetUsbInterfaceDescriptor(handle->adb_interface,
426                                     &interf_desc)) {
427     return 0;
428   }
429 
430   // Must have two endpoints
431   if (2 != interf_desc.bNumEndpoints) {
432     return 0;
433   }
434 
435   if (is_adb_interface(device_desc.idVendor, device_desc.idProduct,
436       interf_desc.bInterfaceClass, interf_desc.bInterfaceSubClass, interf_desc.bInterfaceProtocol)) {
437 
438     if(interf_desc.bInterfaceProtocol == 0x01) {
439       AdbEndpointInformation endpoint_info;
440       // assuming zero is a valid bulk endpoint ID
441       if (AdbGetEndpointInformation(handle->adb_interface, 0, &endpoint_info)) {
442         handle->zero_mask = endpoint_info.max_packet_size - 1;
443       }
444     }
445 
446     return 1;
447   }
448 
449   return 0;
450 }
451 
find_devices()452 void find_devices() {
453         usb_handle* handle = NULL;
454   char entry_buffer[2048];
455   char interf_name[2048];
456   AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]);
457   unsigned long entry_buffer_size = sizeof(entry_buffer);
458   char* copy_name;
459 
460   // Enumerate all present and active interfaces.
461   ADBAPIHANDLE enum_handle =
462     AdbEnumInterfaces(usb_class_id, true, true, true);
463 
464   if (NULL == enum_handle)
465     return;
466 
467   while (AdbNextInterface(enum_handle, next_interface, &entry_buffer_size)) {
468     // TODO: FIXME - temp hack converting wchar_t into char.
469     // It would be better to change AdbNextInterface so it will return
470     // interface name as single char string.
471     const wchar_t* wchar_name = next_interface->device_name;
472     for(copy_name = interf_name;
473         L'\0' != *wchar_name;
474         wchar_name++, copy_name++) {
475       *copy_name = (char)(*wchar_name);
476     }
477     *copy_name = '\0';
478 
479     // Lets see if we already have this device in the list
480     if (!known_device(interf_name)) {
481       // This seems to be a new device. Open it!
482         handle = do_usb_open(next_interface->device_name);
483         if (NULL != handle) {
484         // Lets see if this interface (device) belongs to us
485         if (recognized_device(handle)) {
486           D("adding a new device %s\n", interf_name);
487           char serial_number[512];
488           unsigned long serial_number_len = sizeof(serial_number);
489           if (AdbGetSerialNumber(handle->adb_interface,
490                                 serial_number,
491                                 &serial_number_len,
492                                 true)) {
493             // Lets make sure that we don't duplicate this device
494             if (register_new_device(handle)) {
495               register_usb_transport(handle, serial_number, NULL, 1);
496             } else {
497               D("register_new_device failed for %s\n", interf_name);
498               usb_cleanup_handle(handle);
499               free(handle);
500             }
501           } else {
502             D("cannot get serial number\n");
503             usb_cleanup_handle(handle);
504             free(handle);
505           }
506         } else {
507           usb_cleanup_handle(handle);
508           free(handle);
509         }
510       }
511     }
512 
513     entry_buffer_size = sizeof(entry_buffer);
514   }
515 
516   AdbCloseHandle(enum_handle);
517 }
518