Remove ant build files
[fw/altos] / altosdroid / src / org / altusmetrum / AltosDroid / AltosUsb.java
1 /*
2  * Copyright © 2015 Keith Packard <keithp@keithp.com>
3  *
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.
8  *
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.
13  *
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.
17  */
18
19 package org.altusmetrum.AltosDroid;
20
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;
26
27 import android.content.Context;
28 import android.hardware.usb.*;
29 import android.app.*;
30 import android.os.Handler;
31
32 import org.altusmetrum.altoslib_13.*;
33
34 public class AltosUsb extends AltosDroidLink {
35
36         private Thread           input_thread   = null;
37
38         private Handler          handler;
39
40         private UsbManager              manager;
41         private UsbDevice               device;
42         private UsbDeviceConnection     connection;
43         private UsbInterface            iface;
44         private UsbEndpoint             in, out;
45
46         private InputStream      input;
47         private OutputStream     output;
48
49         // Constructor
50         public AltosUsb(Context context, UsbDevice device, Handler handler) {
51                 super(handler);
52 //              set_debug(D);
53                 this.handler = handler;
54
55                 iface = null;
56                 in = null;
57                 out = null;
58
59                 int     niface = device.getInterfaceCount();
60
61                 for (int i = 0; i < niface; i++) {
62
63                         iface = device.getInterface(i);
64
65                         in = null;
66                         out = null;
67
68                         int nendpoints = iface.getEndpointCount();
69
70                         for (int e = 0; e < nendpoints; e++) {
71                                 UsbEndpoint     endpoint = iface.getEndpoint(e);
72
73                                 if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
74                                         switch (endpoint.getDirection()) {
75                                         case UsbConstants.USB_DIR_OUT:
76                                                 out = endpoint;
77                                                 break;
78                                         case UsbConstants.USB_DIR_IN:
79                                                 in = endpoint;
80                                                 break;
81                                         }
82                                 }
83                         }
84
85                         if (in != null && out != null)
86                                 break;
87                 }
88
89                 if (in != null && out != null) {
90                         AltosDebug.debug("\tin %s out %s\n", in.toString(), out.toString());
91
92                         manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
93
94                         if (manager == null) {
95                                 AltosDebug.debug("USB_SERVICE failed");
96                                 return;
97                         }
98
99                         connection = manager.openDevice(device);
100
101                         if (connection == null) {
102                                 AltosDebug.debug("openDevice failed");
103                                 return;
104                         }
105
106                         connection.claimInterface(iface, true);
107
108                         input_thread = new Thread(this);
109                         input_thread.start();
110
111                         // Configure the newly connected device for telemetry
112                         print("~\nE 0\n");
113                         set_monitor(false);
114                 }
115         }
116
117         static private boolean isAltusMetrum(UsbDevice device) {
118                 if (device.getVendorId() != AltosLib.vendor_altusmetrum)
119                         return false;
120                 if (device.getProductId() < AltosLib.product_altusmetrum_min)
121                         return false;
122                 if (device.getProductId() > AltosLib.product_altusmetrum_max)
123                         return false;
124                 return true;
125         }
126
127         static boolean matchProduct(int want_product, UsbDevice device) {
128
129                 if (!isAltusMetrum(device))
130                         return false;
131
132                 if (want_product == AltosLib.product_any)
133                         return true;
134
135                 int have_product = device.getProductId();
136
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;
142
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;
150
151                 if (have_product == AltosLib.product_altusmetrum)       /* old devices match any request */
152                         return true;
153
154                 if (want_product == have_product)
155                         return true;
156
157                 return false;
158         }
159
160         static public boolean request_permission(Context context, UsbDevice device, PendingIntent pi) {
161                 UsbManager      manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
162
163 //              if (manager.hasPermission(device))
164 //                      return true;
165
166                 AltosDebug.debug("request permission for USB device " + device.toString());
167
168                 manager.requestPermission(device, pi);
169                 return false;
170         }
171
172         static public UsbDevice find_device(Context context, int match_product) {
173                 UsbManager      manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
174
175                 HashMap<String,UsbDevice>       devices = manager.getDeviceList();
176
177                 for (UsbDevice  device : devices.values()) {
178                         int     vendor = device.getVendorId();
179                         int     product = device.getProductId();
180
181                         if (matchProduct(match_product, device)) {
182                                 AltosDebug.debug("found USB device " + device.toString());
183                                 return device;
184                         }
185                 }
186
187                 return null;
188         }
189
190         private void disconnected() {
191                 if (closed()) {
192                         AltosDebug.debug("disconnected after closed");
193                         return;
194                 }
195
196                 AltosDebug.debug("Sending disconnected message");
197                 handler.obtainMessage(TelemetryService.MSG_DISCONNECTED, this).sendToTarget();
198         }
199
200         void close_device() {
201                 UsbDeviceConnection     tmp_connection;
202
203                 synchronized(this) {
204                         tmp_connection = connection;
205                         connection = null;
206                 }
207
208                 if (tmp_connection != null) {
209                         AltosDebug.debug("Closing USB device");
210                         tmp_connection.close();
211                 }
212         }
213
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);
217                 return ret;
218         }
219
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);
223                 return ret;
224         }
225
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()    { }
230
231 }