1 /* 2 * Copyright (C) 2011 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 package android.hardware.usb; 18 19 import android.os.ParcelFileDescriptor; 20 21 import java.io.FileDescriptor; 22 23 24 /** 25 * This class is used for sending and receiving data and control messages to a USB device. 26 * Instances of this class are created by {@link UsbManager#openDevice}. 27 */ 28 public class UsbDeviceConnection { 29 30 private static final String TAG = "UsbDeviceConnection"; 31 32 private final UsbDevice mDevice; 33 34 // used by the JNI code 35 private int mNativeContext; 36 37 /** 38 * UsbDevice should only be instantiated by UsbService implementation 39 * @hide 40 */ 41 public UsbDeviceConnection(UsbDevice device) { 42 mDevice = device; 43 } 44 45 /* package */ boolean open(String name, ParcelFileDescriptor pfd) { 46 return native_open(name, pfd.getFileDescriptor()); 47 } 48 49 /** 50 * Releases all system resources related to the device. 51 * Once the object is closed it cannot be used again. 52 * The client must call {@link UsbManager#openDevice} again 53 * to retrieve a new instance to reestablish communication with the device. 54 */ 55 public void close() { 56 native_close(); 57 } 58 59 /** 60 * Returns the native file descriptor for the device, or 61 * -1 if the device is not opened. 62 * This is intended for passing to native code to access the device. 63 * 64 * @return the native file descriptor 65 */ 66 public int getFileDescriptor() { 67 return native_get_fd(); 68 } 69 70 /** 71 * Returns the raw USB descriptors for the device. 72 * This can be used to access descriptors not supported directly 73 * via the higher level APIs. 74 * 75 * @return raw USB descriptors 76 */ 77 public byte[] getRawDescriptors() { 78 return native_get_desc(); 79 } 80 81 /** 82 * Claims exclusive access to a {@link android.hardware.usb.UsbInterface}. 83 * This must be done before sending or receiving data on any 84 * {@link android.hardware.usb.UsbEndpoint}s belonging to the interface. 85 * 86 * @param intf the interface to claim 87 * @param force true to disconnect kernel driver if necessary 88 * @return true if the interface was successfully claimed 89 */ 90 public boolean claimInterface(UsbInterface intf, boolean force) { 91 return native_claim_interface(intf.getId(), force); 92 } 93 94 /** 95 * Releases exclusive access to a {@link android.hardware.usb.UsbInterface}. 96 * 97 * @return true if the interface was successfully released 98 */ 99 public boolean releaseInterface(UsbInterface intf) { 100 return native_release_interface(intf.getId()); 101 } 102 103 /** 104 * Performs a control transaction on endpoint zero for this device. 105 * The direction of the transfer is determined by the request type. 106 * If requestType & {@link UsbConstants#USB_ENDPOINT_DIR_MASK} is 107 * {@link UsbConstants#USB_DIR_OUT}, then the transfer is a write, 108 * and if it is {@link UsbConstants#USB_DIR_IN}, then the transfer 109 * is a read. 110 * <p> 111 * This method transfers data starting from index 0 in the buffer. 112 * To specify a different offset, use 113 * {@link #controlTransfer(int, int, int, int, byte[], int, int, int)}. 114 * </p> 115 * 116 * @param requestType request type for this transaction 117 * @param request request ID for this transaction 118 * @param value value field for this transaction 119 * @param index index field for this transaction 120 * @param buffer buffer for data portion of transaction, 121 * or null if no data needs to be sent or received 122 * @param length the length of the data to send or receive 123 * @param timeout in milliseconds 124 * @return length of data transferred (or zero) for success, 125 * or negative value for failure 126 */ 127 public int controlTransfer(int requestType, int request, int value, 128 int index, byte[] buffer, int length, int timeout) { 129 return controlTransfer(requestType, request, value, index, buffer, 0, length, timeout); 130 } 131 132 /** 133 * Performs a control transaction on endpoint zero for this device. 134 * The direction of the transfer is determined by the request type. 135 * If requestType & {@link UsbConstants#USB_ENDPOINT_DIR_MASK} is 136 * {@link UsbConstants#USB_DIR_OUT}, then the transfer is a write, 137 * and if it is {@link UsbConstants#USB_DIR_IN}, then the transfer 138 * is a read. 139 * 140 * @param requestType request type for this transaction 141 * @param request request ID for this transaction 142 * @param value value field for this transaction 143 * @param index index field for this transaction 144 * @param buffer buffer for data portion of transaction, 145 * or null if no data needs to be sent or received 146 * @param offset the index of the first byte in the buffer to send or receive 147 * @param length the length of the data to send or receive 148 * @param timeout in milliseconds 149 * @return length of data transferred (or zero) for success, 150 * or negative value for failure 151 */ 152 public int controlTransfer(int requestType, int request, int value, int index, 153 byte[] buffer, int offset, int length, int timeout) { 154 checkBounds(buffer, offset, length); 155 return native_control_request(requestType, request, value, index, 156 buffer, offset, length, timeout); 157 } 158 159 /** 160 * Performs a bulk transaction on the given endpoint. 161 * The direction of the transfer is determined by the direction of the endpoint. 162 * <p> 163 * This method transfers data starting from index 0 in the buffer. 164 * To specify a different offset, use 165 * {@link #bulkTransfer(UsbEndpoint, byte[], int, int, int)}. 166 * </p> 167 * 168 * @param endpoint the endpoint for this transaction 169 * @param buffer buffer for data to send or receive 170 * @param length the length of the data to send or receive 171 * @param timeout in milliseconds 172 * @return length of data transferred (or zero) for success, 173 * or negative value for failure 174 */ 175 public int bulkTransfer(UsbEndpoint endpoint, 176 byte[] buffer, int length, int timeout) { 177 return bulkTransfer(endpoint, buffer, 0, length, timeout); 178 } 179 180 /** 181 * Performs a bulk transaction on the given endpoint. 182 * The direction of the transfer is determined by the direction of the endpoint. 183 * 184 * @param endpoint the endpoint for this transaction 185 * @param buffer buffer for data to send or receive 186 * @param offset the index of the first byte in the buffer to send or receive 187 * @param length the length of the data to send or receive 188 * @param timeout in milliseconds 189 * @return length of data transferred (or zero) for success, 190 * or negative value for failure 191 */ 192 public int bulkTransfer(UsbEndpoint endpoint, 193 byte[] buffer, int offset, int length, int timeout) { 194 checkBounds(buffer, offset, length); 195 return native_bulk_request(endpoint.getAddress(), buffer, offset, length, timeout); 196 } 197 198 /** 199 * Waits for the result of a {@link android.hardware.usb.UsbRequest#queue} operation 200 * Note that this may return requests queued on multiple 201 * {@link android.hardware.usb.UsbEndpoint}s. 202 * When multiple endpoints are in use, {@link android.hardware.usb.UsbRequest#getEndpoint} and 203 * {@link android.hardware.usb.UsbRequest#getClientData} can be useful in determining 204 * how to process the result of this function. 205 * 206 * @return a completed USB request, or null if an error occurred 207 */ 208 public UsbRequest requestWait() { 209 UsbRequest request = native_request_wait(); 210 if (request != null) { 211 request.dequeue(); 212 } 213 return request; 214 } 215 216 /** 217 * Returns the serial number for the device. 218 * This will return null if the device has not been opened. 219 * 220 * @return the device serial number 221 */ 222 public String getSerial() { 223 return native_get_serial(); 224 } 225 226 private static void checkBounds(byte[] buffer, int start, int length) { 227 final int bufferLength = (buffer != null ? buffer.length : 0); 228 if (start < 0 || start + length > bufferLength) { 229 throw new IllegalArgumentException("Buffer start or length out of bounds."); 230 } 231 } 232 233 private native boolean native_open(String deviceName, FileDescriptor pfd); 234 private native void native_close(); 235 private native int native_get_fd(); 236 private native byte[] native_get_desc(); 237 private native boolean native_claim_interface(int interfaceID, boolean force); 238 private native boolean native_release_interface(int interfaceID); 239 private native int native_control_request(int requestType, int request, int value, 240 int index, byte[] buffer, int offset, int length, int timeout); 241 private native int native_bulk_request(int endpoint, byte[] buffer, 242 int offset, int length, int timeout); 243 private native UsbRequest native_request_wait(); 244 private native String native_get_serial(); 245 } 246