Home | History | Annotate | Download | only in externalmanagementtest
      1 /**
      2  * Copyright (C) 2016 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 package com.android.hardware.usb.externalmanagementtest;
     17 
     18 import android.hardware.usb.UsbConstants;
     19 import android.hardware.usb.UsbDevice;
     20 import android.hardware.usb.UsbDeviceConnection;
     21 import android.util.Log;
     22 
     23 public class AoapInterface {
     24     /**
     25      * Use Google Vendor ID when in accessory mode
     26      */
     27     public static final int USB_ACCESSORY_VENDOR_ID = 0x18D1;
     28 
     29     /**
     30      * Product ID to use when in accessory mode
     31      */
     32     public static final int USB_ACCESSORY_PRODUCT_ID = 0x2D00;
     33 
     34     /**
     35      * Product ID to use when in accessory mode and adb is enabled
     36      */
     37     public static final int USB_ACCESSORY_ADB_PRODUCT_ID = 0x2D01;
     38 
     39     /**
     40      * Indexes for strings sent by the host via ACCESSORY_SEND_STRING
     41      */
     42     public static final int ACCESSORY_STRING_MANUFACTURER = 0;
     43     public static final int ACCESSORY_STRING_MODEL = 1;
     44     public static final int ACCESSORY_STRING_DESCRIPTION = 2;
     45     public static final int ACCESSORY_STRING_VERSION = 3;
     46     public static final int ACCESSORY_STRING_URI = 4;
     47     public static final int ACCESSORY_STRING_SERIAL = 5;
     48 
     49     /**
     50      * Control request for retrieving device's protocol version
     51      *
     52      *  requestType:    USB_DIR_IN | USB_TYPE_VENDOR
     53      *  request:        ACCESSORY_GET_PROTOCOL
     54      *  value:          0
     55      *  index:          0
     56      *  data            version number (16 bits little endian)
     57      *                     1 for original accessory support
     58      *                     2 adds HID and device to host audio support
     59      */
     60     public static final int ACCESSORY_GET_PROTOCOL = 51;
     61 
     62     /**
     63      * Control request for host to send a string to the device
     64      *
     65      *  requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
     66      *  request:        ACCESSORY_SEND_STRING
     67      *  value:          0
     68      *  index:          string ID
     69      *  data            zero terminated UTF8 string
     70      *
     71      *  The device can later retrieve these strings via the
     72      *  ACCESSORY_GET_STRING_* ioctls
     73      */
     74     public static final int ACCESSORY_SEND_STRING = 52;
     75 
     76     /**
     77      * Control request for starting device in accessory mode.
     78      * The host sends this after setting all its strings to the device.
     79      *
     80      *  requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
     81      *  request:        ACCESSORY_START
     82      *  value:          0
     83      *  index:          0
     84      *  data            none
     85      */
     86     public static final int ACCESSORY_START = 53;
     87 
     88     /**
     89      * Max payload size for AOAP. Limited by driver.
     90      */
     91     public static final int MAX_PAYLOAD_SIZE = 16384;
     92 
     93     private static final String TAG = AoapInterface.class.getSimpleName();
     94 
     95     public static int getProtocol(UsbDeviceConnection conn) {
     96         byte buffer[] = new byte[2];
     97         int len = conn.controlTransfer(
     98                 UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_VENDOR,
     99                 AoapInterface.ACCESSORY_GET_PROTOCOL, 0, 0, buffer, 2, 10000);
    100         if (len != 2) {
    101             return -1;
    102         }
    103         return (buffer[1] << 8) | buffer[0];
    104     }
    105 
    106     public static void sendString(UsbDeviceConnection conn, int index, String string) {
    107         byte[] buffer = (string + "\0").getBytes();
    108         int len = conn.controlTransfer(
    109                 UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_VENDOR,
    110                 AoapInterface.ACCESSORY_SEND_STRING, 0, index,
    111                 buffer, buffer.length, 10000);
    112         if (len != buffer.length) {
    113             throw new RuntimeException("Failed to send string " + index + ": \"" + string + "\"");
    114         } else {
    115             Log.i(TAG, "Sent string " + index + ": \"" + string + "\"");
    116         }
    117     }
    118 
    119     public static void sendAoapStart(UsbDeviceConnection conn) {
    120         int len = conn.controlTransfer(
    121                 UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_VENDOR,
    122                 AoapInterface.ACCESSORY_START, 0, 0, null, 0, 10000);
    123         if (len < 0) {
    124             throw new RuntimeException("control transfer for accessory start failed:" + len);
    125         }
    126     }
    127 
    128     public static boolean isDeviceInAoapMode(UsbDevice device) {
    129         final int vid = device.getVendorId();
    130         final int pid = device.getProductId();
    131         return vid == USB_ACCESSORY_VENDOR_ID
    132                 && (pid == USB_ACCESSORY_PRODUCT_ID
    133                         || pid == USB_ACCESSORY_ADB_PRODUCT_ID);
    134     }
    135 }
    136