blob: 9751ebf796487b91da4fa4e1d364f0f887e1b49d [file] [log] [blame]
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001/*
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
Yabin Cui19bec5b2015-09-22 15:52:57 -070017#define TRACE_TAG USB
Dan Albertdb6fe642015-03-19 15:21:08 -070018
19#include "sysdeps.h"
20
Mark Salyzynd4bf94d2017-10-04 15:05:40 -070021// clang-format off
Dan Albertb302d122015-02-24 15:51:19 -080022#include <winsock2.h> // winsock.h *must* be included before windows.h.
Josh Gaoe7daf572016-09-21 12:37:10 -070023#include <windows.h>
Mark Salyzynd4bf94d2017-10-04 15:05:40 -070024// clang-format on
Josh Gaoe7daf572016-09-21 12:37:10 -070025#include <usb100.h>
26#include <winerror.h>
27
Dan Albertb302d122015-02-24 15:51:19 -080028#include <errno.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080029#include <stdio.h>
Christopher Ferris054d1702014-11-06 14:34:24 -080030#include <stdlib.h>
Josh Gaoe7daf572016-09-21 12:37:10 -070031
Josh Gao511ff8a2017-12-08 13:05:40 -080032#include <algorithm>
Josh Gaoe7daf572016-09-21 12:37:10 -070033#include <mutex>
Elliott Hughes73925982016-11-15 12:37:32 -080034#include <thread>
Josh Gaoe7daf572016-09-21 12:37:10 -070035
36#include <adb_api.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080037
David Pursellc573d522016-01-27 08:52:53 -080038#include <android-base/errors.h>
39
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080040#include "adb.h"
Josh Gao70267e42016-11-15 18:55:47 -080041#include "sysdeps/chrono.h"
Dan Albertb302d122015-02-24 15:51:19 -080042#include "transport.h"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080043
Josh Gao511ff8a2017-12-08 13:05:40 -080044namespace native {
45
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080046/** Structure usb_handle describes our connection to the usb device via
47 AdbWinApi.dll. This structure is returned from usb_open() routine and
48 is expected in each subsequent call that is accessing the device.
Spencer Low9f1ba562015-07-22 16:17:07 -070049
50 Most members are protected by usb_lock, except for adb_{read,write}_pipe which
51 rely on AdbWinApi.dll's handle validation and AdbCloseHandle(endpoint)'s
52 ability to break a thread out of pipe IO.
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080053*/
Josh Gao511ff8a2017-12-08 13:05:40 -080054struct usb_handle : public ::usb_handle {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -070055 /// Handle to USB interface
56 ADBAPIHANDLE adb_interface;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080057
Mark Salyzynd4bf94d2017-10-04 15:05:40 -070058 /// Handle to USB read pipe (endpoint)
59 ADBAPIHANDLE adb_read_pipe;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080060
Mark Salyzynd4bf94d2017-10-04 15:05:40 -070061 /// Handle to USB write pipe (endpoint)
62 ADBAPIHANDLE adb_write_pipe;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080063
Mark Salyzynd4bf94d2017-10-04 15:05:40 -070064 /// Interface name
65 wchar_t* interface_name;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080066
Mark Salyzynd4bf94d2017-10-04 15:05:40 -070067 /// Maximum packet size.
68 unsigned max_packet_size;
Josh Gao3734cf02017-05-02 15:01:09 -070069
Mark Salyzynd4bf94d2017-10-04 15:05:40 -070070 /// Mask for determining when to use zero length packets
71 unsigned zero_mask;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080072};
73
74/// Class ID assigned to the device by androidusb.sys
75static const GUID usb_class_id = ANDROID_USB_CLASS_ID;
76
77/// List of opened usb handles
Josh Gao511ff8a2017-12-08 13:05:40 -080078static std::vector<usb_handle*> handle_list;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080079
80/// Locker for the list of opened usb handles
Josh Gaoe7daf572016-09-21 12:37:10 -070081static std::mutex& usb_lock = *new std::mutex();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080082
83/// Checks if there is opened usb handle in handle_list for this device.
Spencer Low66763962015-11-12 20:13:21 -080084int known_device(const wchar_t* dev_name);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080085
86/// Checks if there is opened usb handle in handle_list for this device.
87/// usb_lock mutex must be held before calling this routine.
Spencer Low66763962015-11-12 20:13:21 -080088int known_device_locked(const wchar_t* dev_name);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080089
90/// Registers opened usb handle (adds it to handle_list).
91int register_new_device(usb_handle* handle);
92
93/// Checks if interface (device) matches certain criteria
94int recognized_device(usb_handle* handle);
95
96/// Enumerates present and available interfaces (devices), opens new ones and
97/// registers usb transport for them.
98void find_devices();
99
Spencer Low9f1ba562015-07-22 16:17:07 -0700100/// Kicks all USB devices
101static void kick_devices();
102
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800103/// Entry point for thread that polls (every second) for new usb interfaces.
104/// This routine calls find_devices in infinite loop.
Josh Gao0f3312a2017-04-12 17:00:49 -0700105static void device_poll_thread();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800106
107/// Initializes this module
108void usb_init();
109
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800110/// Opens usb interface (device) by interface (device) name.
111usb_handle* do_usb_open(const wchar_t* interface_name);
112
113/// Writes data to the opened usb handle
114int usb_write(usb_handle* handle, const void* data, int len);
115
116/// Reads data using the opened usb handle
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700117int usb_read(usb_handle* handle, void* data, int len);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800118
119/// Cleans up opened usb handle
120void usb_cleanup_handle(usb_handle* handle);
121
122/// Cleans up (but don't close) opened usb handle
123void usb_kick(usb_handle* handle);
124
125/// Closes opened usb handle
126int usb_close(usb_handle* handle);
127
Spencer Low66763962015-11-12 20:13:21 -0800128int known_device_locked(const wchar_t* dev_name) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700129 if (NULL != dev_name) {
130 // Iterate through the list looking for the name match.
Josh Gao511ff8a2017-12-08 13:05:40 -0800131 for (usb_handle* usb : handle_list) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700132 // In Windows names are not case sensetive!
133 if ((NULL != usb->interface_name) && (0 == wcsicmp(usb->interface_name, dev_name))) {
134 return 1;
135 }
136 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800137 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800138
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700139 return 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800140}
141
Spencer Low66763962015-11-12 20:13:21 -0800142int known_device(const wchar_t* dev_name) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700143 int ret = 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800144
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700145 if (NULL != dev_name) {
146 std::lock_guard<std::mutex> lock(usb_lock);
147 ret = known_device_locked(dev_name);
148 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800149
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700150 return ret;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800151}
152
153int register_new_device(usb_handle* handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700154 if (NULL == handle) return 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800155
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700156 std::lock_guard<std::mutex> lock(usb_lock);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800157
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700158 // Check if device is already in the list
159 if (known_device_locked(handle->interface_name)) {
160 return 0;
161 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800162
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700163 // Not in the list. Add this handle to the list.
Josh Gao511ff8a2017-12-08 13:05:40 -0800164 handle_list.push_back(handle);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800165
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700166 return 1;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800167}
168
Josh Gao0f3312a2017-04-12 17:00:49 -0700169void device_poll_thread() {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700170 adb_thread_setname("Device Poll");
171 D("Created device thread");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800172
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700173 while (true) {
174 find_devices();
175 std::this_thread::sleep_for(1s);
176 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800177}
178
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700179static LRESULT CALLBACK _power_window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
180 switch (uMsg) {
181 case WM_POWERBROADCAST:
182 switch (wParam) {
183 case PBT_APMRESUMEAUTOMATIC:
184 // Resuming from sleep or hibernation, so kick all existing USB devices
185 // and then allow the device_poll_thread to redetect USB devices from
186 // scratch. If we don't do this, existing USB devices will never respond
187 // to us because they'll be waiting for the connect/auth handshake.
188 D("Received (WM_POWERBROADCAST, PBT_APMRESUMEAUTOMATIC) notification, "
189 "so kicking all USB devices\n");
190 kick_devices();
191 return TRUE;
192 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700193 }
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700194 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
Spencer Low9f1ba562015-07-22 16:17:07 -0700195}
196
Josh Gao0f3312a2017-04-12 17:00:49 -0700197static void _power_notification_thread() {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700198 // This uses a thread with its own window message pump to get power
199 // notifications. If adb runs from a non-interactive service account, this
200 // might not work (not sure). If that happens to not work, we could use
201 // heavyweight WMI APIs to get power notifications. But for the common case
202 // of a developer's interactive session, a window message pump is more
203 // appropriate.
204 D("Created power notification thread");
205 adb_thread_setname("Power Notifier");
Spencer Low9f1ba562015-07-22 16:17:07 -0700206
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700207 // Window class names are process specific.
208 static const WCHAR kPowerNotificationWindowClassName[] = L"PowerNotificationWindow";
Spencer Low9f1ba562015-07-22 16:17:07 -0700209
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700210 // Get the HINSTANCE corresponding to the module that _power_window_proc
211 // is in (the main module).
212 const HINSTANCE instance = GetModuleHandleW(NULL);
213 if (!instance) {
214 // This is such a common API call that this should never fail.
215 fatal("GetModuleHandleW failed: %s",
216 android::base::SystemErrorCodeToString(GetLastError()).c_str());
217 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700218
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700219 WNDCLASSEXW wndclass;
220 memset(&wndclass, 0, sizeof(wndclass));
221 wndclass.cbSize = sizeof(wndclass);
222 wndclass.lpfnWndProc = _power_window_proc;
223 wndclass.hInstance = instance;
224 wndclass.lpszClassName = kPowerNotificationWindowClassName;
225 if (!RegisterClassExW(&wndclass)) {
226 fatal("RegisterClassExW failed: %s",
227 android::base::SystemErrorCodeToString(GetLastError()).c_str());
228 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700229
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700230 if (!CreateWindowExW(WS_EX_NOACTIVATE, kPowerNotificationWindowClassName,
231 L"ADB Power Notification Window", WS_POPUP, 0, 0, 0, 0, NULL, NULL,
232 instance, NULL)) {
233 fatal("CreateWindowExW failed: %s",
234 android::base::SystemErrorCodeToString(GetLastError()).c_str());
235 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700236
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700237 MSG msg;
238 while (GetMessageW(&msg, NULL, 0, 0)) {
239 TranslateMessage(&msg);
240 DispatchMessageW(&msg);
241 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700242
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700243 // GetMessageW() will return false if a quit message is posted. We don't
244 // do that, but it might be possible for that to occur when logging off or
245 // shutting down. Not a big deal since the whole process will be going away
246 // soon anyway.
247 D("Power notification thread exiting");
Spencer Low9f1ba562015-07-22 16:17:07 -0700248}
249
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800250void usb_init() {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700251 std::thread(device_poll_thread).detach();
252 std::thread(_power_notification_thread).detach();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800253}
254
Josh Gao165460f2017-05-09 13:43:35 -0700255void usb_cleanup() {}
256
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800257usb_handle* do_usb_open(const wchar_t* interface_name) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700258 unsigned long name_len = 0;
Spencer Low9f1ba562015-07-22 16:17:07 -0700259
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700260 // Allocate our handle
261 usb_handle* ret = (usb_handle*)calloc(1, sizeof(usb_handle));
262 if (NULL == ret) {
263 D("Could not allocate %u bytes for usb_handle: %s", sizeof(usb_handle), strerror(errno));
264 goto fail;
265 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800266
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700267 // Create interface.
268 ret->adb_interface = AdbCreateInterfaceByName(interface_name);
269 if (NULL == ret->adb_interface) {
270 D("AdbCreateInterfaceByName failed: %s",
271 android::base::SystemErrorCodeToString(GetLastError()).c_str());
272 goto fail;
273 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800274
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700275 // Open read pipe (endpoint)
276 ret->adb_read_pipe = AdbOpenDefaultBulkReadEndpoint(
277 ret->adb_interface, AdbOpenAccessTypeReadWrite, AdbOpenSharingModeReadWrite);
278 if (NULL == ret->adb_read_pipe) {
279 D("AdbOpenDefaultBulkReadEndpoint failed: %s",
280 android::base::SystemErrorCodeToString(GetLastError()).c_str());
281 goto fail;
282 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800283
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700284 // Open write pipe (endpoint)
285 ret->adb_write_pipe = AdbOpenDefaultBulkWriteEndpoint(
286 ret->adb_interface, AdbOpenAccessTypeReadWrite, AdbOpenSharingModeReadWrite);
287 if (NULL == ret->adb_write_pipe) {
288 D("AdbOpenDefaultBulkWriteEndpoint failed: %s",
289 android::base::SystemErrorCodeToString(GetLastError()).c_str());
290 goto fail;
291 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700292
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700293 // Save interface name
294 // First get expected name length
295 AdbGetInterfaceName(ret->adb_interface, NULL, &name_len, false);
296 if (0 == name_len) {
297 D("AdbGetInterfaceName returned name length of zero: %s",
298 android::base::SystemErrorCodeToString(GetLastError()).c_str());
299 goto fail;
300 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700301
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700302 ret->interface_name = (wchar_t*)malloc(name_len * sizeof(ret->interface_name[0]));
303 if (NULL == ret->interface_name) {
304 D("Could not allocate %lu characters for interface_name: %s", name_len, strerror(errno));
305 goto fail;
306 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700307
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700308 // Now save the name
309 if (!AdbGetInterfaceName(ret->adb_interface, ret->interface_name, &name_len, false)) {
310 D("AdbGetInterfaceName failed: %s",
311 android::base::SystemErrorCodeToString(GetLastError()).c_str());
312 goto fail;
313 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700314
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700315 // We're done at this point
316 return ret;
Spencer Low9f1ba562015-07-22 16:17:07 -0700317
318fail:
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700319 if (NULL != ret) {
320 usb_cleanup_handle(ret);
321 free(ret);
322 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800323
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700324 return NULL;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800325}
326
327int usb_write(usb_handle* handle, const void* data, int len) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700328 unsigned long time_out = 5000;
329 unsigned long written = 0;
330 int err = 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800331
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700332 D("usb_write %d", len);
333 if (NULL == handle) {
334 D("usb_write was passed NULL handle");
335 err = EINVAL;
336 goto fail;
Spencer Low9f1ba562015-07-22 16:17:07 -0700337 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700338
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700339 // Perform write
340 if (!AdbWriteEndpointSync(handle->adb_write_pipe, (void*)data, (unsigned long)len, &written,
341 time_out)) {
342 D("AdbWriteEndpointSync failed: %s",
343 android::base::SystemErrorCodeToString(GetLastError()).c_str());
344 err = EIO;
345 goto fail;
346 }
347
348 // Make sure that we've written what we were asked to write
349 D("usb_write got: %ld, expected: %d", written, len);
350 if (written != (unsigned long)len) {
351 // If this occurs, this code should be changed to repeatedly call
352 // AdbWriteEndpointSync() until all bytes are written.
353 D("AdbWriteEndpointSync was supposed to write %d, but only wrote %ld", len, written);
354 err = EIO;
355 goto fail;
356 }
357
358 if (handle->zero_mask && (len & handle->zero_mask) == 0) {
359 // Send a zero length packet
360 if (!AdbWriteEndpointSync(handle->adb_write_pipe, (void*)data, 0, &written, time_out)) {
361 D("AdbWriteEndpointSync of zero length packet failed: %s",
362 android::base::SystemErrorCodeToString(GetLastError()).c_str());
363 err = EIO;
364 goto fail;
365 }
366 }
367
368 return 0;
Spencer Low9f1ba562015-07-22 16:17:07 -0700369
370fail:
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700371 // Any failure should cause us to kick the device instead of leaving it a
372 // zombie state with potential to hang.
373 if (NULL != handle) {
374 D("Kicking device due to error in usb_write");
375 usb_kick(handle);
376 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700377
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700378 D("usb_write failed");
379 errno = err;
380 return -1;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800381}
382
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700383int usb_read(usb_handle* handle, void* data, int len) {
384 unsigned long time_out = 0;
385 unsigned long read = 0;
386 int err = 0;
387 int orig_len = len;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800388
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700389 D("usb_read %d", len);
390 if (NULL == handle) {
391 D("usb_read was passed NULL handle");
392 err = EINVAL;
393 goto fail;
Spencer Low9f1ba562015-07-22 16:17:07 -0700394 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800395
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700396 while (len == orig_len) {
397 if (!AdbReadEndpointSync(handle->adb_read_pipe, data, len, &read, time_out)) {
398 D("AdbReadEndpointSync failed: %s",
399 android::base::SystemErrorCodeToString(GetLastError()).c_str());
400 err = EIO;
401 goto fail;
402 }
403 D("usb_read got: %ld, expected: %d", read, len);
Spencer Low9f1ba562015-07-22 16:17:07 -0700404
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700405 data = (char*)data + read;
406 len -= read;
407 }
408
409 return orig_len - len;
Spencer Low9f1ba562015-07-22 16:17:07 -0700410
411fail:
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700412 // Any failure should cause us to kick the device instead of leaving it a
413 // zombie state with potential to hang.
414 if (NULL != handle) {
415 D("Kicking device due to error in usb_read");
416 usb_kick(handle);
417 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700418
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700419 D("usb_read failed");
420 errno = err;
421 return -1;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800422}
423
Spencer Low9f1ba562015-07-22 16:17:07 -0700424// Wrapper around AdbCloseHandle() that logs diagnostics.
425static void _adb_close_handle(ADBAPIHANDLE adb_handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700426 if (!AdbCloseHandle(adb_handle)) {
427 D("AdbCloseHandle(%p) failed: %s", adb_handle,
428 android::base::SystemErrorCodeToString(GetLastError()).c_str());
429 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700430}
431
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800432void usb_cleanup_handle(usb_handle* handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700433 D("usb_cleanup_handle");
434 if (NULL != handle) {
435 if (NULL != handle->interface_name) free(handle->interface_name);
436 // AdbCloseHandle(pipe) will break any threads out of pending IO calls and
437 // wait until the pipe no longer uses the interface. Then we can
438 // AdbCloseHandle() the interface.
439 if (NULL != handle->adb_write_pipe) _adb_close_handle(handle->adb_write_pipe);
440 if (NULL != handle->adb_read_pipe) _adb_close_handle(handle->adb_read_pipe);
441 if (NULL != handle->adb_interface) _adb_close_handle(handle->adb_interface);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800442
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700443 handle->interface_name = NULL;
444 handle->adb_write_pipe = NULL;
445 handle->adb_read_pipe = NULL;
446 handle->adb_interface = NULL;
447 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800448}
449
Spencer Low9f1ba562015-07-22 16:17:07 -0700450static void usb_kick_locked(usb_handle* handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700451 // The reason the lock must be acquired before calling this function is in
452 // case multiple threads are trying to kick the same device at the same time.
453 usb_cleanup_handle(handle);
Spencer Low9f1ba562015-07-22 16:17:07 -0700454}
455
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800456void usb_kick(usb_handle* handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700457 D("usb_kick");
458 if (NULL != handle) {
459 std::lock_guard<std::mutex> lock(usb_lock);
460 usb_kick_locked(handle);
461 } else {
462 errno = EINVAL;
463 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800464}
465
466int usb_close(usb_handle* handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700467 D("usb_close");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800468
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700469 if (NULL != handle) {
470 // Remove handle from the list
471 {
472 std::lock_guard<std::mutex> lock(usb_lock);
Josh Gao511ff8a2017-12-08 13:05:40 -0800473 handle_list.erase(std::remove(handle_list.begin(), handle_list.end(), handle),
474 handle_list.end());
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700475 }
476
477 // Cleanup handle
478 usb_cleanup_handle(handle);
479 free(handle);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800480 }
481
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700482 return 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800483}
484
Josh Gao3734cf02017-05-02 15:01:09 -0700485size_t usb_get_max_packet_size(usb_handle* handle) {
486 return handle->max_packet_size;
487}
488
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800489int recognized_device(usb_handle* handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700490 if (NULL == handle) return 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800491
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700492 // Check vendor and product id first
493 USB_DEVICE_DESCRIPTOR device_desc;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800494
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700495 if (!AdbGetUsbDeviceDescriptor(handle->adb_interface, &device_desc)) {
496 D("AdbGetUsbDeviceDescriptor failed: %s",
David Pursellc573d522016-01-27 08:52:53 -0800497 android::base::SystemErrorCodeToString(GetLastError()).c_str());
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700498 return 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800499 }
500
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700501 // Then check interface properties
502 USB_INTERFACE_DESCRIPTOR interf_desc;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800503
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700504 if (!AdbGetUsbInterfaceDescriptor(handle->adb_interface, &interf_desc)) {
505 D("AdbGetUsbInterfaceDescriptor failed: %s",
506 android::base::SystemErrorCodeToString(GetLastError()).c_str());
507 return 0;
508 }
509
510 // Must have two endpoints
511 if (2 != interf_desc.bNumEndpoints) {
512 return 0;
513 }
514
Mark Salyzyn21a991d2017-10-04 15:05:40 -0700515 if (!is_adb_interface(interf_desc.bInterfaceClass, interf_desc.bInterfaceSubClass,
516 interf_desc.bInterfaceProtocol)) {
517 return 0;
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700518 }
519
Mark Salyzyn21a991d2017-10-04 15:05:40 -0700520 AdbEndpointInformation endpoint_info;
521 // assuming zero is a valid bulk endpoint ID
522 if (AdbGetEndpointInformation(handle->adb_interface, 0, &endpoint_info)) {
523 handle->max_packet_size = endpoint_info.max_packet_size;
524 handle->zero_mask = endpoint_info.max_packet_size - 1;
525 D("device zero_mask: 0x%x", handle->zero_mask);
526 } else {
527 D("AdbGetEndpointInformation failed: %s",
528 android::base::SystemErrorCodeToString(GetLastError()).c_str());
529 }
530
531 return 1;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800532}
533
534void find_devices() {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700535 usb_handle* handle = NULL;
536 char entry_buffer[2048];
537 AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]);
538 unsigned long entry_buffer_size = sizeof(entry_buffer);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800539
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700540 // Enumerate all present and active interfaces.
541 ADBAPIHANDLE enum_handle = AdbEnumInterfaces(usb_class_id, true, true, true);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800542
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700543 if (NULL == enum_handle) {
544 D("AdbEnumInterfaces failed: %s",
545 android::base::SystemErrorCodeToString(GetLastError()).c_str());
546 return;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800547 }
548
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700549 while (AdbNextInterface(enum_handle, next_interface, &entry_buffer_size)) {
550 // Lets see if we already have this device in the list
551 if (!known_device(next_interface->device_name)) {
552 // This seems to be a new device. Open it!
553 handle = do_usb_open(next_interface->device_name);
554 if (NULL != handle) {
555 // Lets see if this interface (device) belongs to us
556 if (recognized_device(handle)) {
557 D("adding a new device %ls", next_interface->device_name);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800558
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700559 // We don't request a wchar_t string from AdbGetSerialNumber() because of a bug
560 // in adb_winusb_interface.cpp:CopyMemory(buffer, ser_num->bString,
561 // bytes_written) where the last parameter should be (str_len *
562 // sizeof(wchar_t)). The bug reads 2 bytes past the end of a stack buffer in the
563 // best case, and in the unlikely case of a long serial number, it will read 2
564 // bytes past the end of a heap allocation. This doesn't affect the resulting
565 // string, but we should avoid the bad reads in the first place.
566 char serial_number[512];
567 unsigned long serial_number_len = sizeof(serial_number);
568 if (AdbGetSerialNumber(handle->adb_interface, serial_number, &serial_number_len,
569 true)) {
570 // Lets make sure that we don't duplicate this device
571 if (register_new_device(handle)) {
572 register_usb_transport(handle, serial_number, NULL, 1);
573 } else {
574 D("register_new_device failed for %ls", next_interface->device_name);
575 usb_cleanup_handle(handle);
576 free(handle);
577 }
578 } else {
579 D("cannot get serial number: %s",
580 android::base::SystemErrorCodeToString(GetLastError()).c_str());
581 usb_cleanup_handle(handle);
582 free(handle);
583 }
584 } else {
585 usb_cleanup_handle(handle);
586 free(handle);
587 }
588 }
589 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700590
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700591 entry_buffer_size = sizeof(entry_buffer);
592 }
593
594 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
595 // Only ERROR_NO_MORE_ITEMS is expected at the end of enumeration.
596 D("AdbNextInterface failed: %s",
597 android::base::SystemErrorCodeToString(GetLastError()).c_str());
598 }
599
600 _adb_close_handle(enum_handle);
Spencer Low9f1ba562015-07-22 16:17:07 -0700601}
602
603static void kick_devices() {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700604 // Need to acquire lock to safely walk the list which might be modified
605 // by another thread.
606 std::lock_guard<std::mutex> lock(usb_lock);
Josh Gao511ff8a2017-12-08 13:05:40 -0800607 for (usb_handle* usb : handle_list) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700608 usb_kick_locked(usb);
609 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800610}
Josh Gao511ff8a2017-12-08 13:05:40 -0800611
612} // namespace native