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