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; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19 package org.altusmetrum.AltosDroid;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.OutputStream;
24 import java.util.UUID;
25 import java.util.HashMap;
27 import android.content.Context;
28 import android.hardware.usb.*;
30 import android.os.Handler;
32 import org.altusmetrum.altoslib_13.*;
34 public class AltosUsb extends AltosDroidLink {
36 private Thread input_thread = null;
38 private Handler handler;
40 private UsbManager manager;
41 private UsbDevice device;
42 private UsbDeviceConnection connection;
43 private UsbInterface iface;
44 private UsbEndpoint in, out;
46 private InputStream input;
47 private OutputStream output;
50 public AltosUsb(Context context, UsbDevice device, Handler handler) {
53 this.handler = handler;
59 int niface = device.getInterfaceCount();
61 for (int i = 0; i < niface; i++) {
63 iface = device.getInterface(i);
68 int nendpoints = iface.getEndpointCount();
70 for (int e = 0; e < nendpoints; e++) {
71 UsbEndpoint endpoint = iface.getEndpoint(e);
73 if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
74 switch (endpoint.getDirection()) {
75 case UsbConstants.USB_DIR_OUT:
78 case UsbConstants.USB_DIR_IN:
85 if (in != null && out != null)
89 if (in != null && out != null) {
90 AltosDebug.debug("\tin %s out %s\n", in.toString(), out.toString());
92 manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
94 if (manager == null) {
95 AltosDebug.debug("USB_SERVICE failed");
99 connection = manager.openDevice(device);
101 if (connection == null) {
102 AltosDebug.debug("openDevice failed");
106 connection.claimInterface(iface, true);
108 input_thread = new Thread(this);
109 input_thread.start();
111 // Configure the newly connected device for telemetry
117 static private boolean isAltusMetrum(UsbDevice device) {
118 if (device.getVendorId() != AltosLib.vendor_altusmetrum)
120 if (device.getProductId() < AltosLib.product_altusmetrum_min)
122 if (device.getProductId() > AltosLib.product_altusmetrum_max)
127 static boolean matchProduct(int want_product, UsbDevice device) {
129 if (!isAltusMetrum(device))
132 if (want_product == AltosLib.product_any)
135 int have_product = device.getProductId();
137 if (want_product == AltosLib.product_basestation)
138 return have_product == AltosLib.product_teledongle ||
139 have_product == AltosLib.product_teleterra ||
140 have_product == AltosLib.product_telebt ||
141 have_product == AltosLib.product_megadongle;
143 if (want_product == AltosLib.product_altimeter)
144 return have_product == AltosLib.product_telemetrum ||
145 have_product == AltosLib.product_telemega ||
146 have_product == AltosLib.product_easymega ||
147 have_product == AltosLib.product_telegps ||
148 have_product == AltosLib.product_easymini ||
149 have_product == AltosLib.product_telemini;
151 if (have_product == AltosLib.product_altusmetrum) /* old devices match any request */
154 if (want_product == have_product)
160 static public boolean request_permission(Context context, UsbDevice device, PendingIntent pi) {
161 UsbManager manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
163 // if (manager.hasPermission(device))
166 AltosDebug.debug("request permission for USB device " + device.toString());
168 manager.requestPermission(device, pi);
172 static public UsbDevice find_device(Context context, int match_product) {
173 UsbManager manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
175 HashMap<String,UsbDevice> devices = manager.getDeviceList();
177 for (UsbDevice device : devices.values()) {
178 int vendor = device.getVendorId();
179 int product = device.getProductId();
181 if (matchProduct(match_product, device)) {
182 AltosDebug.debug("found USB device " + device.toString());
190 private void disconnected() {
192 AltosDebug.debug("disconnected after closed");
196 AltosDebug.debug("Sending disconnected message");
197 handler.obtainMessage(TelemetryService.MSG_DISCONNECTED, this).sendToTarget();
200 void close_device() {
201 UsbDeviceConnection tmp_connection;
204 tmp_connection = connection;
208 if (tmp_connection != null) {
209 AltosDebug.debug("Closing USB device");
210 tmp_connection.close();
214 int read(byte[] buffer, int len) {
215 int ret = connection.bulkTransfer(in, buffer, len, -1);
216 AltosDebug.debug("read(%d) = %d\n", len, ret);
220 int write(byte[] buffer, int len) {
221 int ret = connection.bulkTransfer(out, buffer, len, -1);
222 AltosDebug.debug("write(%d) = %d\n", len, ret);
226 // Stubs of required methods when extending AltosLink
227 public boolean can_cancel_reply() { return false; }
228 public boolean show_reply_timeout() { return true; }
229 public void hide_reply_timeout() { }