~nexulockr-dev/nexulockr/android-tools

« back to all changes in this revision

Viewing changes to core/adb/usb_windows.c

  • Committer: Ian Santopietro
  • Date: 2014-05-30 17:55:06 UTC
  • Revision ID: isantop@gmail.com-20140530175506-7irb6lx626i8d2j8
Set up proper function for all nexus devices in the Udev rule.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
187
void usb_cleanup() {
 
188
}
 
189
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
}