2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
26 #define TRACE_TAG TRACE_USB
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.
34 /// Previous entry in the list of opened usb handles
37 /// Next entry in the list of opened usb handles
40 /// Handle to USB interface
41 SDBAPIHANDLE sdb_interface;
43 /// Handle to USB read pipe (endpoint)
44 SDBAPIHANDLE sdb_read_pipe;
46 /// Handle to USB write pipe (endpoint)
47 SDBAPIHANDLE sdb_write_pipe;
52 /// Mask for determining when to use zero length packets
56 /// Class ID assigned to the device by androidusb.sys
57 static const GUID usb_class_id = ANDROID_USB_CLASS_ID;
59 /// List of opened usb handles
60 static usb_handle handle_list = {
65 /// Locker for the list of opened usb handles
66 SDB_MUTEX_DEFINE( usb_lock );
68 /// Checks if there is opened usb handle in handle_list for this device.
69 int known_device(const char* dev_name);
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);
75 /// Registers opened usb handle (adds it to handle_list).
76 int register_new_device(usb_handle* handle);
78 /// Checks if interface (device) matches certain criteria
79 int recognized_device(usb_handle* handle);
81 /// Enumerates present and available interfaces (devices), opens new ones and
82 /// registers usb transport for them.
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);
89 /// Initializes this module
92 /// Cleans up this module
95 /// Opens usb interface (device) by interface (device) name.
96 usb_handle* do_usb_open(const wchar_t* interface_name);
98 /// Writes data to the opened usb handle
99 int usb_write(usb_handle* handle, const void* data, int len);
101 /// Reads data using the opened usb handle
102 int usb_read(usb_handle *handle, void* data, int len);
104 /// Cleans up opened usb handle
105 void usb_cleanup_handle(usb_handle* handle);
107 /// Cleans up (but don't close) opened usb handle
108 void usb_kick(usb_handle* handle);
110 /// Closes opened usb handle
111 int usb_close(usb_handle* handle);
113 /// Gets interface (device) name for an opened usb handle
114 const char *usb_name(usb_handle* handle);
116 int known_device_locked(const char* dev_name) {
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))) {
133 int known_device(const char* dev_name) {
136 if (NULL != dev_name) {
137 sdb_mutex_lock(&usb_lock);
138 ret = known_device_locked(dev_name);
139 sdb_mutex_unlock(&usb_lock);
145 int register_new_device(usb_handle* handle) {
149 sdb_mutex_lock(&usb_lock);
151 // Check if device is already in the list
152 if (known_device_locked(handle->interface_name)) {
153 sdb_mutex_unlock(&usb_lock);
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;
163 sdb_mutex_unlock(&usb_lock);
168 void* device_poll_thread(void* unused) {
169 D("Created device thread\n");
182 if(sdb_thread_create(&tid, device_poll_thread, NULL)) {
183 fatal_errno("cannot create input thread");
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));
196 // Set linkers back to the handle
201 ret->sdb_interface = SdbCreateInterfaceByName(interface_name);
203 if (NULL == ret->sdb_interface) {
205 errno = GetLastError();
209 // Open read pipe (endpoint)
211 SdbOpenDefaultBulkReadEndpoint(ret->sdb_interface,
212 SdbOpenAccessTypeReadWrite,
213 SdbOpenSharingModeReadWrite);
214 if (NULL != ret->sdb_read_pipe) {
215 // Open write pipe (endpoint)
216 ret->sdb_write_pipe =
217 SdbOpenDefaultBulkWriteEndpoint(ret->sdb_interface,
218 SdbOpenAccessTypeReadWrite,
219 SdbOpenSharingModeReadWrite);
220 if (NULL != ret->sdb_write_pipe) {
221 // Save interface name
222 unsigned long name_len = 0;
224 // First get expected name length
225 SdbGetInterfaceName(ret->sdb_interface,
230 ret->interface_name = (char*)malloc(name_len);
232 if (NULL != ret->interface_name) {
234 if (SdbGetInterfaceName(ret->sdb_interface,
238 // We're done at this point
242 SetLastError(ERROR_OUTOFMEMORY);
248 // Something went wrong.
249 int saved_errno = GetLastError();
250 usb_cleanup_handle(ret);
252 SetLastError(saved_errno);
257 int usb_write(usb_handle* handle, const void* data, int len) {
258 unsigned long time_out = 5000;
259 unsigned long written = 0;
262 D("usb_write %d\n", len);
263 if (NULL != handle) {
265 ret = SdbWriteEndpointSync(handle->sdb_write_pipe,
270 int saved_errno = GetLastError();
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 SdbWriteEndpointSync(handle->sdb_write_pipe,
287 // assume ERROR_INVALID_HANDLE indicates we are disconnected
288 if (saved_errno == ERROR_INVALID_HANDLE)
293 D("usb_write NULL handle\n");
294 SetLastError(ERROR_INVALID_HANDLE);
297 D("usb_write failed: %d\n", errno);
302 int usb_read(usb_handle *handle, void* data, int len) {
303 unsigned long time_out = 0;
304 unsigned long read = 0;
307 D("usb_read %d\n", len);
308 if (NULL != handle) {
310 int xfer = (len > 4096) ? 4096 : len;
312 ret = SdbReadEndpointSync(handle->sdb_read_pipe,
317 int saved_errno = GetLastError();
318 D("usb_write got: %ld, expected: %d, errno: %d\n", read, xfer, saved_errno);
326 // assume ERROR_INVALID_HANDLE indicates we are disconnected
327 if (saved_errno == ERROR_INVALID_HANDLE)
334 D("usb_read NULL handle\n");
335 SetLastError(ERROR_INVALID_HANDLE);
338 D("usb_read failed: %d\n", errno);
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->sdb_write_pipe)
348 SdbCloseHandle(handle->sdb_write_pipe);
349 if (NULL != handle->sdb_read_pipe)
350 SdbCloseHandle(handle->sdb_read_pipe);
351 if (NULL != handle->sdb_interface)
352 SdbCloseHandle(handle->sdb_interface);
354 handle->interface_name = NULL;
355 handle->sdb_write_pipe = NULL;
356 handle->sdb_read_pipe = NULL;
357 handle->sdb_interface = NULL;
361 void usb_kick(usb_handle* handle) {
362 if (NULL != handle) {
363 sdb_mutex_lock(&usb_lock);
365 usb_cleanup_handle(handle);
367 sdb_mutex_unlock(&usb_lock);
369 SetLastError(ERROR_INVALID_HANDLE);
370 errno = ERROR_INVALID_HANDLE;
374 int usb_close(usb_handle* handle) {
377 if (NULL != handle) {
378 // Remove handle from the list
379 sdb_mutex_lock(&usb_lock);
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;
388 sdb_mutex_unlock(&usb_lock);
391 usb_cleanup_handle(handle);
398 const char *usb_name(usb_handle* handle) {
399 if (NULL == handle) {
400 SetLastError(ERROR_INVALID_HANDLE);
401 errno = ERROR_INVALID_HANDLE;
405 return (const char*)handle->interface_name;
408 int recognized_device(usb_handle* handle) {
412 // Check vendor and product id first
413 USB_DEVICE_DESCRIPTOR device_desc;
415 if (!SdbGetUsbDeviceDescriptor(handle->sdb_interface,
420 // Then check interface properties
421 USB_INTERFACE_DESCRIPTOR interf_desc;
423 if (!SdbGetUsbInterfaceDescriptor(handle->sdb_interface,
428 // Must have two endpoints
429 if (2 != interf_desc.bNumEndpoints) {
433 if (is_sdb_interface(device_desc.idVendor, device_desc.idProduct,
434 interf_desc.bInterfaceClass, interf_desc.bInterfaceSubClass, interf_desc.bInterfaceProtocol)) {
436 if(interf_desc.bInterfaceProtocol == 0x01) {
437 SdbEndpointInformation endpoint_info;
438 // assuming zero is a valid bulk endpoint ID
439 if (SdbGetEndpointInformation(handle->sdb_interface, 0, &endpoint_info)) {
440 handle->zero_mask = endpoint_info.max_packet_size - 1;
450 void find_devices() {
451 usb_handle* handle = NULL;
452 char entry_buffer[2048];
453 char interf_name[2048];
454 SdbInterfaceInfo* next_interface = (SdbInterfaceInfo*)(&entry_buffer[0]);
455 unsigned long entry_buffer_size = sizeof(entry_buffer);
458 // Enumerate all present and active interfaces.
459 SDBAPIHANDLE enum_handle =
460 SdbEnumInterfaces(usb_class_id, true, true, true);
462 if (NULL == enum_handle)
465 while (SdbNextInterface(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);
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 (SdbGetSerialNumber(handle->sdb_interface,
491 // Lets make sure that we don't duplicate this device
492 if (register_new_device(handle)) {
493 register_usb_transport(handle, serial_number, 1);
495 D("register_new_device failed for %s\n", interf_name);
496 usb_cleanup_handle(handle);
500 D("cannot get serial number\n");
501 usb_cleanup_handle(handle);
505 usb_cleanup_handle(handle);
511 entry_buffer_size = sizeof(entry_buffer);
514 SdbCloseHandle(enum_handle);