2 * Copyright © 2015 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
18 package org.altusmetrum.AltosDroid;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.OutputStream;
23 import java.util.UUID;
24 import java.util.HashMap;
26 import android.content.Context;
27 import android.hardware.usb.*;
29 import android.os.Handler;
30 import android.util.Log;
32 import org.altusmetrum.altoslib_6.*;
34 public class AltosUsb extends AltosDroidLink {
37 private static final String TAG = "AltosUsb";
38 private static final boolean D = true;
40 private Thread input_thread = null;
42 private Handler handler;
44 private UsbManager manager;
45 private UsbDevice device;
46 private UsbDeviceConnection connection;
47 private UsbInterface iface;
48 private UsbEndpoint in, out;
50 private InputStream input;
51 private OutputStream output;
54 public AltosUsb(Context context, UsbDevice device, Handler handler) {
57 this.handler = handler;
63 int niface = device.getInterfaceCount();
65 for (int i = 0; i < niface; i++) {
67 iface = device.getInterface(i);
72 int nendpoints = iface.getEndpointCount();
74 for (int e = 0; e < nendpoints; e++) {
75 UsbEndpoint endpoint = iface.getEndpoint(e);
77 if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
78 switch (endpoint.getDirection()) {
79 case UsbConstants.USB_DIR_OUT:
82 case UsbConstants.USB_DIR_IN:
89 if (in != null && out != null)
93 if (in != null && out != null) {
94 Log.d(TAG, String.format("\tin %s out %s\n", in.toString(), out.toString()));
96 manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
98 if (manager == null) {
99 Log.d(TAG, "USB_SERVICE failed");
103 connection = manager.openDevice(device);
105 if (connection == null) {
106 Log.d(TAG, "openDevice failed");
110 connection.claimInterface(iface, true);
112 input_thread = new Thread(this);
113 input_thread.start();
115 // Configure the newly connected device for telemetry
121 static private boolean isAltusMetrum(UsbDevice device) {
122 if (device.getVendorId() != AltosLib.vendor_altusmetrum)
124 if (device.getProductId() < AltosLib.product_altusmetrum_min)
126 if (device.getProductId() > AltosLib.product_altusmetrum_max)
131 static boolean matchProduct(int want_product, UsbDevice device) {
133 if (!isAltusMetrum(device))
136 if (want_product == AltosLib.product_any)
139 int have_product = device.getProductId();
141 if (want_product == AltosLib.product_basestation)
142 return have_product == AltosLib.product_teledongle ||
143 have_product == AltosLib.product_teleterra ||
144 have_product == AltosLib.product_telebt ||
145 have_product == AltosLib.product_megadongle;
147 if (want_product == AltosLib.product_altimeter)
148 return have_product == AltosLib.product_telemetrum ||
149 have_product == AltosLib.product_telemega ||
150 have_product == AltosLib.product_easymega ||
151 have_product == AltosLib.product_telegps ||
152 have_product == AltosLib.product_easymini ||
153 have_product == AltosLib.product_telemini;
155 if (have_product == AltosLib.product_altusmetrum) /* old devices match any request */
158 if (want_product == have_product)
164 static public boolean request_permission(Context context, UsbDevice device, PendingIntent pi) {
165 UsbManager manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
167 // if (manager.hasPermission(device))
170 Log.d(TAG, "request permission for USB device " + device.toString());
172 manager.requestPermission(device, pi);
176 static public UsbDevice find_device(Context context, int match_product) {
177 UsbManager manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
179 HashMap<String,UsbDevice> devices = manager.getDeviceList();
181 for (UsbDevice device : devices.values()) {
182 int vendor = device.getVendorId();
183 int product = device.getProductId();
185 if (matchProduct(match_product, device)) {
186 Log.d(TAG, "found USB device " + device.toString());
194 private void disconnected() {
196 if (D) Log.d(TAG, "disconnected after closed");
200 if (D) Log.d(TAG, "Sending disconnected message");
201 handler.obtainMessage(TelemetryService.MSG_DISCONNECTED, this).sendToTarget();
204 void close_device() {
205 UsbDeviceConnection tmp_connection;
208 tmp_connection = connection;
212 if (tmp_connection != null) {
213 if (D) Log.d(TAG, "Closing USB device");
214 tmp_connection.close();
218 int read(byte[] buffer, int len) {
219 int ret = connection.bulkTransfer(in, buffer, len, -1);
220 if (D) Log.d(TAG, String.format("read(%d) = %d\n", len, ret));
224 int write(byte[] buffer, int len) {
225 int ret = connection.bulkTransfer(out, buffer, len, -1);
226 if (D) Log.d(TAG, String.format("write(%d) = %d\n", len, ret));
230 // Stubs of required methods when extending AltosLink
231 public boolean can_cancel_reply() { return false; }
232 public boolean show_reply_timeout() { return true; }
233 public void hide_reply_timeout() { }