UsbDeviceConnection.java revision b162617143519b36ac4d5baec9f650a29adec571
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
17package android.hardware.usb;
18
19import android.os.ParcelFileDescriptor;
20
21import 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 */
28public 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     *
111     * @param requestType request type for this transaction
112     * @param request request ID for this transaction
113     * @param value value field for this transaction
114     * @param index index field for this transaction
115     * @param buffer buffer for data portion of transaction,
116     * or null if no data needs to be sent or received
117     * @param length the length of the data to send or receive
118     * @param timeout in milliseconds
119     * @return length of data transferred (or zero) for success,
120     * or negative value for failure
121     *
122     * @deprecated Use {@link #controlTransfer(int, int, int, int, byte[], int, int, int)}
123     * which accepts a buffer start index.
124     */
125    @Deprecated
126    public int controlTransfer(int requestType, int request, int value,
127            int index, byte[] buffer, int length, int timeout) {
128        return controlTransfer(requestType, request, value, index, buffer, 0, length, timeout);
129    }
130
131    /**
132     * Performs a control transaction on endpoint zero for this device.
133     * The direction of the transfer is determined by the request type.
134     * If requestType & {@link UsbConstants#USB_ENDPOINT_DIR_MASK} is
135     * {@link UsbConstants#USB_DIR_OUT}, then the transfer is a write,
136     * and if it is {@link UsbConstants#USB_DIR_IN}, then the transfer
137     * is a read.
138     *
139     * @param requestType request type for this transaction
140     * @param request request ID for this transaction
141     * @param value value field for this transaction
142     * @param index index field for this transaction
143     * @param buffer buffer for data portion of transaction,
144     * or null if no data needs to be sent or received
145     * @param start the index of the first byte in the buffer to send or receive
146     * @param length the length of the data to send or receive
147     * @param timeout in milliseconds
148     * @return length of data transferred (or zero) for success,
149     * or negative value for failure
150     */
151    public int controlTransfer(int requestType, int request, int value, int index,
152            byte[] buffer, int start, int length, int timeout) {
153        checkBounds(buffer, start, length);
154        return native_control_request(requestType, request, value, index,
155                buffer, start, length, timeout);
156    }
157
158    /**
159     * Performs a bulk transaction on the given endpoint.
160     * The direction of the transfer is determined by the direction of the endpoint
161     *
162     * @param endpoint the endpoint for this transaction
163     * @param buffer buffer for data to send or receive
164     * @param length the length of the data to send or receive
165     * @param timeout in milliseconds
166     * @return length of data transferred (or zero) for success,
167     * or negative value for failure
168     *
169     * @deprecated Use {@link #bulkTransfer(UsbEndpoint, byte[], int, int, int)}
170     * which accepts a buffer start index.
171     */
172    @Deprecated
173    public int bulkTransfer(UsbEndpoint endpoint,
174            byte[] buffer, int length, int timeout) {
175        return bulkTransfer(endpoint, buffer, 0, length, timeout);
176    }
177
178    /**
179     * Performs a bulk transaction on the given endpoint.
180     * The direction of the transfer is determined by the direction of the endpoint
181     *
182     * @param endpoint the endpoint for this transaction
183     * @param buffer buffer for data to send or receive
184     * @param start the index of the first byte in the buffer to send or receive
185     * @param length the length of the data to send or receive
186     * @param timeout in milliseconds
187     * @return length of data transferred (or zero) for success,
188     * or negative value for failure
189     */
190    public int bulkTransfer(UsbEndpoint endpoint,
191            byte[] buffer, int start, int length, int timeout) {
192        checkBounds(buffer, start, length);
193        return native_bulk_request(endpoint.getAddress(), buffer, start, length, timeout);
194    }
195
196    /**
197     * Waits for the result of a {@link android.hardware.usb.UsbRequest#queue} operation
198     * Note that this may return requests queued on multiple
199     * {@link android.hardware.usb.UsbEndpoint}s.
200     * When multiple endpoints are in use, {@link android.hardware.usb.UsbRequest#getEndpoint} and
201     * {@link android.hardware.usb.UsbRequest#getClientData} can be useful in determining
202     * how to process the result of this function.
203     *
204     * @return a completed USB request, or null if an error occurred
205     */
206    public UsbRequest requestWait() {
207        UsbRequest request = native_request_wait();
208        if (request != null) {
209            request.dequeue();
210        }
211        return request;
212    }
213
214    /**
215     * Returns the serial number for the device.
216     * This will return null if the device has not been opened.
217     *
218     * @return the device serial number
219     */
220    public String getSerial() {
221        return native_get_serial();
222    }
223
224    private static void checkBounds(byte[] buffer, int start, int length) {
225        final int bufferLength = (buffer != null ? buffer.length : 0);
226        if (start < 0 || start + length > bufferLength) {
227            throw new IllegalArgumentException("Buffer start or length out of bounds.");
228        }
229    }
230
231    private native boolean native_open(String deviceName, FileDescriptor pfd);
232    private native void native_close();
233    private native int native_get_fd();
234    private native byte[] native_get_desc();
235    private native boolean native_claim_interface(int interfaceID, boolean force);
236    private native boolean native_release_interface(int interfaceID);
237    private native int native_control_request(int requestType, int request, int value,
238            int index, byte[] buffer, int start, int length, int timeout);
239    private native int native_bulk_request(int endpoint, byte[] buffer,
240            int start, int length, int timeout);
241    private native UsbRequest native_request_wait();
242    private native String native_get_serial();
243}
244