int recognized_device(usb_handle* handle) {
    if (nullptr == handle) return 0;

    // Check vendor and product id first
    USB_DEVICE_DESCRIPTOR device_desc;

    if (!AdbGetUsbDeviceDescriptor(handle->adb_interface, &device_desc)) {
        D("AdbGetUsbDeviceDescriptor failed: %s",
          android::base::SystemErrorCodeToString(GetLastError()).c_str());
        return 0;
    }

    // Then check interface properties
    USB_INTERFACE_DESCRIPTOR interf_desc;

    if (!AdbGetUsbInterfaceDescriptor(handle->adb_interface, &interf_desc)) {
        D("AdbGetUsbInterfaceDescriptor failed: %s",
          android::base::SystemErrorCodeToString(GetLastError()).c_str());
        return 0;
    }

    // Must have two endpoints
    if (2 != interf_desc.bNumEndpoints) {
        return 0;
    }

    if (!is_adb_interface(interf_desc.bInterfaceClass, interf_desc.bInterfaceSubClass,
                          interf_desc.bInterfaceProtocol)) {
        return 0;
    }

    AdbEndpointInformation endpoint_info;
    // assuming zero is a valid bulk endpoint ID
    if (AdbGetEndpointInformation(handle->adb_interface, 0, &endpoint_info)) {
        handle->max_packet_size = endpoint_info.max_packet_size;
        handle->zero_mask = endpoint_info.max_packet_size - 1;
        D("device zero_mask: 0x%x", handle->zero_mask);
    } else {
        D("AdbGetEndpointInformation failed: %s",
          android::base::SystemErrorCodeToString(GetLastError()).c_str());
    }

    return 1;
}
bool TestInterfaceHandle(ADBAPIHANDLE interface_handle) {
  // Get interface name.
  char intr_name[4096];
  unsigned long intr_name_size = sizeof(intr_name);
  if (AdbGetInterfaceName(interface_handle, intr_name, &intr_name_size, true)) {
    printf("\n+++ Interface name %s", intr_name);
  } else {
    printf("\n--- AdbGetInterfaceName failure %u", GetLastError());
    return false;
  }

  // Get device descriptor for the interface
  USB_DEVICE_DESCRIPTOR dev_desc;
  if (AdbGetUsbDeviceDescriptor(interface_handle, &dev_desc)) {
    printf("\n+++ Device descriptor:");
    printf("\n        bLength            = %u", dev_desc.bLength);
    printf("\n        bDescriptorType    = %u", dev_desc.bDescriptorType);
    printf("\n        bcdUSB             = %u", dev_desc.bcdUSB);
    printf("\n        bDeviceClass       = %u", dev_desc.bDeviceClass);
    printf("\n        bDeviceSubClass    = %u", dev_desc.bDeviceSubClass);
    printf("\n        bDeviceProtocol    = %u", dev_desc.bDeviceProtocol);
    printf("\n        bMaxPacketSize0    = %u", dev_desc.bMaxPacketSize0);
    printf("\n        idVendor           = %X", dev_desc.idVendor);
    printf("\n        idProduct          = %X", dev_desc.idProduct);
    printf("\n        bcdDevice          = %u", dev_desc.bcdDevice);
    printf("\n        iManufacturer      = %u", dev_desc.iManufacturer);
    printf("\n        iProduct           = %u", dev_desc.iProduct);
    printf("\n        iSerialNumber      = %u", dev_desc.iSerialNumber);
    printf("\n        bNumConfigurations = %u", dev_desc.bDescriptorType);
  } else {
    printf("\n--- AdbGetUsbDeviceDescriptor failure %u", GetLastError());
    return false;
  }

  // Get configuration descriptor for the interface
  USB_CONFIGURATION_DESCRIPTOR config_desc;
  if (AdbGetUsbConfigurationDescriptor(interface_handle, &config_desc)) {
    printf("\n+++ Configuration descriptor:");
    printf("\n        bLength             = %u", config_desc.bLength);
    printf("\n        bDescriptorType     = %u", config_desc.bDescriptorType);
    printf("\n        wTotalLength        = %u", config_desc.wTotalLength);
    printf("\n        bNumInterfaces      = %u", config_desc.bNumInterfaces);
    printf("\n        bConfigurationValue = %u", config_desc.bConfigurationValue);
    printf("\n        iConfiguration      = %u", config_desc.iConfiguration);
    printf("\n        bmAttributes        = %u", config_desc.bmAttributes);
    printf("\n        MaxPower            = %u", config_desc.MaxPower);
  } else {
    printf("\n--- AdbGetUsbConfigurationDescriptor failure %u", GetLastError());
    return false;
  }

  // Get device serial number
  char ser_num[1024];
  unsigned long ser_num_size = sizeof(ser_num);
  if (AdbGetSerialNumber(interface_handle, ser_num, &ser_num_size, true)) {
    printf("\n+++ Serial number: %s", ser_num);
  } else {
    printf("\n--- AdbGetSerialNumber failure %u", GetLastError());
    return false;
  }

  // Get interface descriptor
  USB_INTERFACE_DESCRIPTOR intr_desc;
  if (AdbGetUsbInterfaceDescriptor(interface_handle, &intr_desc)) {
    printf("\n+++ Interface descriptor:");
    printf("\n        bDescriptorType    = %u", intr_desc.bDescriptorType);
    printf("\n        bInterfaceNumber   = %u", intr_desc.bInterfaceNumber);
    printf("\n        bAlternateSetting  = %u", intr_desc.bAlternateSetting);
    printf("\n        bNumEndpoints      = %u", intr_desc.bNumEndpoints);
    printf("\n        bInterfaceClass    = %u", intr_desc.bInterfaceClass);
    printf("\n        bInterfaceSubClass = %u", intr_desc.bInterfaceSubClass);
    printf("\n        bInterfaceProtocol = %u", intr_desc.bInterfaceProtocol);
    printf("\n        iInterface         = %u", intr_desc.iInterface);
  } else {
    printf("\n--- AdbGetUsbInterfaceDescriptor failure %u", GetLastError());
    return false;
  }

  // Enumerate interface's endpoints
  AdbEndpointInformation pipe_info;
  for (UCHAR pipe = 0; pipe < intr_desc.bNumEndpoints; pipe++) {
    if (AdbGetEndpointInformation(interface_handle, pipe, &pipe_info)) {
      printf("\n      PIPE %u info:", pipe);
      printf("\n          max_packet_size   = %u", pipe_info.max_packet_size);
      printf("\n          max_transfer_size = %u", pipe_info.max_transfer_size);
      printf("\n          endpoint_type     = %u", pipe_info.endpoint_type);
      printf("\n          endpoint_address  = %02X", pipe_info.endpoint_address);
      printf("\n          polling_interval  = %u", pipe_info.polling_interval);
      printf("\n          setting_index     = %u", pipe_info.setting_index);
    } else {
      printf("\n--- AdbGetEndpointInformation(%u) failure %u", pipe, GetLastError());
      return false;
    }
  }

  // Get default bulk read endpoint info
  if (AdbGetDefaultBulkReadEndpointInformation(interface_handle, &pipe_info)) {
    printf("\n      Default Bulk Read Pipe info:");
    printf("\n          max_packet_size   = %u", pipe_info.max_packet_size);
    printf("\n          max_transfer_size = %u", pipe_info.max_transfer_size);
    printf("\n          endpoint_type     = %u", pipe_info.endpoint_type);
    printf("\n          endpoint_address  = %02X", pipe_info.endpoint_address);
    printf("\n          polling_interval  = %u", pipe_info.polling_interval);
    printf("\n          setting_index     = %u", pipe_info.setting_index);
  } else {
    printf("\n--- AdbGetDefaultBulkReadEndpointInformation failure %u", GetLastError());
    return false;
  }

  // Get default bulk write endpoint info
  if (AdbGetDefaultBulkWriteEndpointInformation(interface_handle, &pipe_info)) {
    printf("\n      Default Bulk Write Pipe info:");
    printf("\n          max_packet_size   = %u", pipe_info.max_packet_size);
    printf("\n          max_transfer_size = %u", pipe_info.max_transfer_size);
    printf("\n          endpoint_type     = %u", pipe_info.endpoint_type);
    printf("\n          endpoint_address  = %02X", pipe_info.endpoint_address);
    printf("\n          polling_interval  = %u", pipe_info.polling_interval);
    printf("\n          setting_index     = %u", pipe_info.setting_index);
  } else {
    printf("\n--- AdbGetDefaultBulkWriteEndpointInformation failure %u", GetLastError());
    return false;
  }

  // Test a handshake on that interface
  DeviceHandShake(interface_handle);

  return true;
}