adb_winapi_test.cpp revision 2be4a90641291ebe17d8f280ea09ac5768a209bd
1/*
2 * Copyright (C) 2009 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// This file contains implementation of a test application that tests
18// functionality of AdbWinApi interface. In this test we will use AdbWinApi
19// interface in order to enumerate USB interfaces for Android ADB class, and
20// for each interface found we will test USB I/O on that interface by sending
21// a simple "hand shake" message to the device connected via this interface.
22
23#include "stdafx.h"
24
25#ifdef _DEBUG
26#define new DEBUG_NEW
27#endif
28
29// Android ADB interface identifier
30const GUID kAdbInterfaceId = ANDROID_USB_CLASS_ID;
31
32// Number of interfaces detected in TestEnumInterfaces.
33int interface_count = 0;
34
35// Constants used to initialize a "handshake" message
36#define MAX_PAYLOAD 4096
37#define A_SYNC 0x434e5953
38#define A_CNXN 0x4e584e43
39#define A_OPEN 0x4e45504f
40#define A_OKAY 0x59414b4f
41#define A_CLSE 0x45534c43
42#define A_WRTE 0x45545257
43#define A_VERSION 0x01000000
44
45// Formats message sent to USB device
46struct message {
47    unsigned int command;       /* command identifier constant      */
48    unsigned int arg0;          /* first argument                   */
49    unsigned int arg1;          /* second argument                  */
50    unsigned int data_length;   /* length of payload (0 is allowed) */
51    unsigned int data_crc32;    /* crc32 of data payload            */
52    unsigned int magic;         /* command ^ 0xffffffff             */
53};
54
55//
56// Test routines declarations.
57//
58
59// Tests interface enumeration.
60bool TestEnumInterfaces();
61
62// Tests all interfaces detected for our device class.
63bool TestInterfaces();
64
65// Tests interface addressed by the given device name.
66bool TestInterface(const wchar_t* device_name);
67
68// Tests interface opened with ADB API.
69bool TestInterfaceHandle(ADBAPIHANDLE interface_handle);
70
71// Sends a "handshake" message to the given interface.
72bool DeviceHandShake(ADBAPIHANDLE adb_interface);
73
74int __cdecl _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) {
75  // Test enum interfaces.
76  if (!TestEnumInterfaces())
77    return -1;
78
79  if (0 == interface_count) {
80    printf("\nNo ADB interfaces found. Make sure that device is "
81           "connected to USB port and is powered on.");
82    return 1;
83  }
84
85  // Test each interface found in the system
86  if (!TestInterfaces())
87    return -2;
88
89  return 0;
90}
91
92bool TestEnumInterfaces() {
93  // Enumerate interfaces
94  ADBAPIHANDLE enum_handle =
95    AdbEnumInterfaces(kAdbInterfaceId, true, true, true);
96  if (NULL == enum_handle) {
97    printf("\nEnum interfaces failure:");
98    printf("\nUnable to enumerate ADB interfaces: %u", GetLastError());
99    return false;
100  }
101
102  // Unite interface info structure and buffer big enough to contain the
103  // largest structure.
104  union {
105    AdbInterfaceInfo interface_info;
106    char buf[4096];
107  };
108  unsigned long buf_size = sizeof(buf);
109
110  // Enumerate (and count) interfaces, printing information for each found
111  // interface.
112  interface_count = 0;
113  while (AdbNextInterface(enum_handle, &interface_info, &buf_size)) {
114    interface_count++;
115    printf("\nFound interface %ws:", interface_info.device_name);
116    if (interface_info.flags & SPINT_ACTIVE)
117      printf(" ACTIVE");
118    if (interface_info.flags & SPINT_DEFAULT)
119      printf(" DEFAULT");
120    if (interface_info.flags & SPINT_REMOVED)
121      printf(" REMOVED");
122
123    buf_size = sizeof(buf);;
124  };
125
126  AdbCloseHandle(enum_handle);
127  return true;
128}
129
130bool TestInterfaces() {
131  // Enumerate interfaces
132  ADBAPIHANDLE enum_handle =
133    AdbEnumInterfaces(kAdbInterfaceId, true, true, true);
134  if (NULL == enum_handle) {
135    printf("\nTest interfaces failure:");
136    printf("\nUnable to enumerate ADB interfaces: %u", GetLastError());
137    return false;
138  }
139
140  // Unite interface info structure and buffer big enough to contain the
141  // largest structure.
142  union {
143    AdbInterfaceInfo interface_info;
144    char buf[4096];
145  };
146  unsigned long buf_size = sizeof(buf);
147
148  // Test each found interface
149  while (AdbNextInterface(enum_handle, &interface_info, &buf_size)) {
150    TestInterface(interface_info.device_name);
151    buf_size = sizeof(buf);
152  };
153
154  AdbCloseHandle(enum_handle);
155
156  // Create interface by VID/PID/MI
157  ADBAPIHANDLE interface_handle =
158      AdbCreateInterface(kAdbInterfaceId, DEVICE_VENDOR_ID,
159                         DEVICE_COMPOSITE_PRODUCT_ID, DEVICE_INTERFACE_ID);
160  if (NULL == interface_handle) {
161    printf("\nUnable to create interface by VID/PID: %u", GetLastError());
162    return false;
163  }
164
165  // Test it
166  TestInterfaceHandle(interface_handle);
167  AdbCloseHandle(interface_handle);
168  return true;
169}
170
171bool TestInterface(const wchar_t* device_name) {
172  printf("\n*** Test interface( %ws )", device_name);
173
174  // Get ADB handle to the interface by its name
175  ADBAPIHANDLE interface_handle = AdbCreateInterfaceByName(device_name);
176  if (NULL == interface_handle) {
177    printf(" FAILED:\nUnable to create interface by name: %u", GetLastError());
178    return false;
179  }
180
181  // Test it
182  TestInterfaceHandle(interface_handle);
183  AdbCloseHandle(interface_handle);
184  return true;
185}
186
187bool TestInterfaceHandle(ADBAPIHANDLE interface_handle) {
188  // Get interface name.
189  char intr_name[4096];
190  unsigned long intr_name_size = sizeof(intr_name);
191  if (AdbGetInterfaceName(interface_handle, intr_name, &intr_name_size, true)) {
192    printf("\n+++ Interface name %s", intr_name);
193  } else {
194    printf("\n--- AdbGetInterfaceName failure %u", GetLastError());
195    return false;
196  }
197
198  // Get device descriptor for the interface
199  USB_DEVICE_DESCRIPTOR dev_desc;
200  if (AdbGetUsbDeviceDescriptor(interface_handle, &dev_desc)) {
201    printf("\n+++ Device descriptor:");
202    printf("\n        bLength            = %u", dev_desc.bLength);
203    printf("\n        bDescriptorType    = %u", dev_desc.bDescriptorType);
204    printf("\n        bcdUSB             = %u", dev_desc.bcdUSB);
205    printf("\n        bDeviceClass       = %u", dev_desc.bDeviceClass);
206    printf("\n        bDeviceSubClass    = %u", dev_desc.bDeviceSubClass);
207    printf("\n        bDeviceProtocol    = %u", dev_desc.bDeviceProtocol);
208    printf("\n        bMaxPacketSize0    = %u", dev_desc.bMaxPacketSize0);
209    printf("\n        idVendor           = %X", dev_desc.idVendor);
210    printf("\n        idProduct          = %X", dev_desc.idProduct);
211    printf("\n        bcdDevice          = %u", dev_desc.bcdDevice);
212    printf("\n        iManufacturer      = %u", dev_desc.iManufacturer);
213    printf("\n        iProduct           = %u", dev_desc.iProduct);
214    printf("\n        iSerialNumber      = %u", dev_desc.iSerialNumber);
215    printf("\n        bNumConfigurations = %u", dev_desc.bDescriptorType);
216  } else {
217    printf("\n--- AdbGetUsbDeviceDescriptor failure %u", GetLastError());
218    return false;
219  }
220
221  // Get configuration descriptor for the interface
222  USB_CONFIGURATION_DESCRIPTOR config_desc;
223  if (AdbGetUsbConfigurationDescriptor(interface_handle, &config_desc)) {
224    printf("\n+++ Configuration descriptor:");
225    printf("\n        bLength             = %u", config_desc.bLength);
226    printf("\n        bDescriptorType     = %u", config_desc.bDescriptorType);
227    printf("\n        wTotalLength        = %u", config_desc.wTotalLength);
228    printf("\n        bNumInterfaces      = %u", config_desc.bNumInterfaces);
229    printf("\n        bConfigurationValue = %u", config_desc.bConfigurationValue);
230    printf("\n        iConfiguration      = %u", config_desc.iConfiguration);
231    printf("\n        bmAttributes        = %u", config_desc.bmAttributes);
232    printf("\n        MaxPower            = %u", config_desc.MaxPower);
233  } else {
234    printf("\n--- AdbGetUsbConfigurationDescriptor failure %u", GetLastError());
235    return false;
236  }
237
238  // Get device serial number
239  char ser_num[1024];
240  unsigned long ser_num_size = sizeof(ser_num);
241  if (AdbGetSerialNumber(interface_handle, ser_num, &ser_num_size, true)) {
242    printf("\n+++ Serial number: %s", ser_num);
243  } else {
244    printf("\n--- AdbGetSerialNumber failure %u", GetLastError());
245    return false;
246  }
247
248  // Get interface descriptor
249  USB_INTERFACE_DESCRIPTOR intr_desc;
250  if (AdbGetUsbInterfaceDescriptor(interface_handle, &intr_desc)) {
251    printf("\n+++ Interface descriptor:");
252    printf("\n        bDescriptorType    = %u", intr_desc.bDescriptorType);
253    printf("\n        bInterfaceNumber   = %u", intr_desc.bInterfaceNumber);
254    printf("\n        bAlternateSetting  = %u", intr_desc.bAlternateSetting);
255    printf("\n        bNumEndpoints      = %u", intr_desc.bNumEndpoints);
256    printf("\n        bInterfaceClass    = %u", intr_desc.bInterfaceClass);
257    printf("\n        bInterfaceSubClass = %u", intr_desc.bInterfaceSubClass);
258    printf("\n        bInterfaceProtocol = %u", intr_desc.bInterfaceProtocol);
259    printf("\n        iInterface         = %u", intr_desc.iInterface);
260  } else {
261    printf("\n--- AdbGetUsbInterfaceDescriptor failure %u", GetLastError());
262    return false;
263  }
264
265  // Enumerate interface's endpoints
266  AdbEndpointInformation pipe_info;
267  for (UCHAR pipe = 0; pipe < intr_desc.bNumEndpoints; pipe++) {
268    if (AdbGetEndpointInformation(interface_handle, pipe, &pipe_info)) {
269      printf("\n      PIPE %u info:", pipe);
270      printf("\n          max_packet_size   = %u", pipe_info.max_packet_size);
271      printf("\n          max_transfer_size = %u", pipe_info.max_transfer_size);
272      printf("\n          endpoint_type     = %u", pipe_info.endpoint_type);
273      printf("\n          endpoint_address  = %02X", pipe_info.endpoint_address);
274      printf("\n          polling_interval  = %u", pipe_info.polling_interval);
275      printf("\n          setting_index     = %u", pipe_info.setting_index);
276    } else {
277      printf("\n--- AdbGetEndpointInformation(%u) failure %u", pipe, GetLastError());
278      return false;
279    }
280  }
281
282  // Get default bulk read endpoint info
283  if (AdbGetDefaultBulkReadEndpointInformation(interface_handle, &pipe_info)) {
284    printf("\n      Default Bulk Read Pipe info:");
285    printf("\n          max_packet_size   = %u", pipe_info.max_packet_size);
286    printf("\n          max_transfer_size = %u", pipe_info.max_transfer_size);
287    printf("\n          endpoint_type     = %u", pipe_info.endpoint_type);
288    printf("\n          endpoint_address  = %02X", pipe_info.endpoint_address);
289    printf("\n          polling_interval  = %u", pipe_info.polling_interval);
290    printf("\n          setting_index     = %u", pipe_info.setting_index);
291  } else {
292    printf("\n--- AdbGetDefaultBulkReadEndpointInformation failure %u", GetLastError());
293    return false;
294  }
295
296  // Get default bulk write endpoint info
297  if (AdbGetDefaultBulkWriteEndpointInformation(interface_handle, &pipe_info)) {
298    printf("\n      Default Bulk Write Pipe info:");
299    printf("\n          max_packet_size   = %u", pipe_info.max_packet_size);
300    printf("\n          max_transfer_size = %u", pipe_info.max_transfer_size);
301    printf("\n          endpoint_type     = %u", pipe_info.endpoint_type);
302    printf("\n          endpoint_address  = %02X", pipe_info.endpoint_address);
303    printf("\n          polling_interval  = %u", pipe_info.polling_interval);
304    printf("\n          setting_index     = %u", pipe_info.setting_index);
305  } else {
306    printf("\n--- AdbGetDefaultBulkWriteEndpointInformation failure %u", GetLastError());
307    return false;
308  }
309
310  // Test a handshake on that interface
311  DeviceHandShake(interface_handle);
312
313  return true;
314}
315
316bool DeviceHandShake(ADBAPIHANDLE adb_interface) {
317  // Get interface name
318  char interf_name[512];
319  unsigned long name_size = sizeof(interf_name);
320  if (!AdbGetInterfaceName(adb_interface, interf_name, &name_size, true)) {
321    printf("\nDeviceHandShake: AdbGetInterfaceName returned error %u",
322           GetLastError());
323    return false;
324  }
325
326  printf("\n\nDeviceHandShake on %s", interf_name);
327
328  char* ser_num = NULL;
329  name_size = 0;
330  if (!AdbGetSerialNumber(adb_interface, ser_num, &name_size, true)) {
331    ser_num = reinterpret_cast<char*>(malloc(name_size));
332    if (NULL != ser_num) {
333      if (!AdbGetSerialNumber(adb_interface, ser_num, &name_size, true)) {
334        printf("\n      AdbGetSerialNumber returned error %u", GetLastError());
335        AdbCloseHandle(adb_interface);
336        return false;
337      }
338      printf("\nInterface serial number is %s", ser_num);
339      free(ser_num);
340    }
341  }
342
343  // Get default read endpoint
344  ADBAPIHANDLE adb_read = AdbOpenDefaultBulkReadEndpoint(adb_interface,
345                                                         AdbOpenAccessTypeReadWrite,
346                                                         AdbOpenSharingModeReadWrite);
347  if (NULL == adb_read) {
348    printf("\n      AdbOpenDefaultBulkReadEndpoint returned error %u", GetLastError());
349    return false;
350  }
351
352  // Get default write endpoint
353  ADBAPIHANDLE adb_write = AdbOpenDefaultBulkWriteEndpoint(adb_interface,
354                                                           AdbOpenAccessTypeReadWrite,
355                                                           AdbOpenSharingModeReadWrite);
356  if (NULL == adb_write) {
357    printf("\n      AdbOpenDefaultBulkWriteEndpoint returned error %u", GetLastError());
358    AdbCloseHandle(adb_read);
359    return false;
360  }
361
362  // Send connect message
363  message msg_send;
364  msg_send.command = A_CNXN;
365  msg_send.arg0 = A_VERSION;
366  msg_send.arg1 = MAX_PAYLOAD;
367  msg_send.data_length = 0;
368  msg_send.data_crc32 = 0;
369  msg_send.magic = msg_send.command ^ 0xffffffff;
370
371  ULONG written_bytes = 0;
372  bool write_res = AdbWriteEndpointSync(adb_write, &msg_send, sizeof(msg_send), &written_bytes, 500);
373  if (!write_res) {
374    printf("\n       AdbWriteEndpointSync returned error %u", GetLastError());
375    AdbCloseHandle(adb_write);
376    AdbCloseHandle(adb_read);
377    return false;
378  }
379
380  // Receive handshake
381  message msg_rcv;
382  ULONG read_bytes = 0;
383  bool read_res = AdbReadEndpointSync(adb_read, &msg_rcv, sizeof(msg_rcv), &read_bytes, 512);
384  if (!read_res) {
385    printf("\n       AdbReadEndpointSync returned error %u", GetLastError());
386    AdbCloseHandle(adb_write);
387    AdbCloseHandle(adb_read);
388    return false;
389  }
390
391  printf("\n      Read handshake: %u bytes received", read_bytes);
392  char* cmd_ansi = reinterpret_cast<char*>(&msg_rcv.command);
393  printf("\n         command     = %08X (%c%c%c%c)", msg_rcv.command,
394         cmd_ansi[0], cmd_ansi[1], cmd_ansi[2], cmd_ansi[3]);
395  printf("\n         arg0        = %08X", msg_rcv.arg0);
396  printf("\n         arg1        = %08X", msg_rcv.arg1);
397  printf("\n         data_length = %u", msg_rcv.data_length);
398  printf("\n         data_crc32  = %08X", msg_rcv.data_crc32);
399  printf("\n         magic       = %08X", msg_rcv.magic);
400
401  if (0 != msg_rcv.data_length) {
402    char* buf = reinterpret_cast<char*>(malloc(msg_rcv.data_length));
403    read_res = AdbReadEndpointSync(adb_read, buf, msg_rcv.data_length, &read_bytes, 512);
404    if (!read_res) {
405      printf("\n       AdbReadEndpointSync (data) returned error %u", GetLastError());
406      free(buf);
407      AdbCloseHandle(adb_write);
408      AdbCloseHandle(adb_read);
409      return false;
410    }
411
412    for (ULONG n = 0; n < read_bytes; n++) {
413      if (0 == (n % 16))
414        printf("\n          ");
415      printf("%02X ", buf[n]);
416    }
417
418    printf("\n          %s", buf);
419
420    delete buf;
421  }
422
423  AdbCloseHandle(adb_write);
424  AdbCloseHandle(adb_read);
425
426  return true;
427}
428