Merge remote branch 'origin/master' into altosui
[fw/altos] / ao-tools / altosui / AltosDeviceLinux.java
1 /*
2  * Copyright © 2010 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; version 2 of the License.
7  *
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.
12  *
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.
16  */
17
18 package altosui;
19 import java.lang.*;
20 import java.io.*;
21 import java.util.*;
22 import altosui.AltosDevice;
23
24 public class AltosDeviceLinux extends AltosDevice {
25
26         String load_string(File file) {
27                 try {
28                         FileInputStream in = new FileInputStream(file);
29                         String result = "";
30                         int c;
31                         try {
32                                 while ((c = in.read()) != -1) {
33                                         if (c == '\n')
34                                                 break;
35                                         result = result + (char) c;
36                                 }
37                                 return result;
38                         } catch (IOException ee) {
39                                 return "";
40                         }
41                 } catch (FileNotFoundException ee) {
42                         return "";
43                 }
44         }
45         String load_string(File dir, String name) {
46                 return load_string(new File(dir, name));
47         }
48
49         int load_hex(File file) {
50                 try {
51                         return Integer.parseInt(load_string(file).trim(), 16);
52                 } catch (NumberFormatException ee) {
53                         return -1;
54                 }
55         }
56
57         int load_hex(File dir, String name) {
58                 return load_hex(new File(dir, name));
59         }
60
61         int load_dec(File file) {
62                 try {
63                         return Integer.parseInt(load_string(file).trim());
64                 } catch (NumberFormatException ee) {
65                         return -1;
66                 }
67         }
68
69         int load_dec(File dir, String name) {
70                 return load_dec(new File(dir, name));
71         }
72
73         String usb_tty(File sys_dir) {
74                 String base = sys_dir.getName();
75                 int num_configs = load_hex(sys_dir, "bNumConfigurations");
76                 int num_inters = load_hex(sys_dir, "bNumInterfaces");
77                 for (int config = 1; config <= num_configs; config++) {
78                         for (int inter = 0; inter < num_inters; inter++) {
79                                 String endpoint_base = String.format("%s:%d.%d",
80                                                                      base, config, inter);
81                                 File endpoint_full = new File(sys_dir, endpoint_base);
82
83                                 File[] namelist;
84
85                                 /* Check for tty:ttyACMx style names */
86                                 class tty_colon_filter implements FilenameFilter {
87                                         public boolean accept(File dir, String name) {
88                                                 return name.startsWith("tty:");
89                                         }
90                                 }
91                                 namelist = endpoint_full.listFiles(new tty_colon_filter());
92                                 if (namelist != null && namelist.length > 0)
93                                         return new File ("/dev", namelist[0].getName().substring(4)).getPath();
94
95                                 /* Check for tty/ttyACMx style names */
96                                 class tty_filter implements FilenameFilter {
97                                         public boolean accept(File dir, String name) {
98                                                 return name.startsWith("tty");
99                                         }
100                                 }
101                                 File tty_dir = new File(endpoint_full, "tty");
102                                 namelist = tty_dir.listFiles(new tty_filter());
103                                 if (namelist != null && namelist.length > 0)
104                                         return new File ("/dev", namelist[0].getName()).getPath();
105                         }
106                 }
107                 return null;
108         }
109
110         public AltosDeviceLinux (File sys) {
111                 sys = sys;
112                 manufacturer = load_string(sys, "manufacturer");
113                 product = load_string(sys, "product");
114                 serial = load_dec(sys, "serial");
115                 idProduct = load_hex(sys, "idProduct");
116                 idVendor = load_hex(sys, "idVendor");
117                 tty = usb_tty(sys);
118         }
119
120         public String toString() {
121                 return String.format("%-20s %6d %-15s", product, serial, tty == null ? "" : tty);
122         }
123         static public AltosDeviceLinux[] list() {
124                 LinkedList<AltosDeviceLinux> devices = new LinkedList<AltosDeviceLinux>();
125
126                 class dev_filter implements FilenameFilter{
127                         public boolean accept(File dir, String name) {
128                                 for (int i = 0; i < name.length(); i++) {
129                                         char c = name.charAt(i);
130                                         if (Character.isDigit(c))
131                                                 continue;
132                                         if (c == '-')
133                                                 continue;
134                                         if (c == '.' && i != 1)
135                                                 continue;
136                                         return false;
137                                 }
138                                 return true;
139                         }
140                 }
141
142                 File usb_devices = new File("/sys/bus/usb/devices");
143                 File[] devs = usb_devices.listFiles(new dev_filter());
144                 if (devs != null) {
145                         for (int e = 0; e < devs.length; e++) {
146                                 AltosDeviceLinux        dev = new AltosDeviceLinux(devs[e]);
147                                 if (dev.idVendor == 0xfffe && dev.tty != null) {
148                                         devices.add(dev);
149                                 }
150                         }
151                 }
152                 AltosDeviceLinux[] foo = new AltosDeviceLinux[devices.size()];
153                 for (int e = 0; e < devices.size(); e++)
154                         foo[e] = devices.get(e);
155                 return foo;
156         }
157
158         static public AltosDeviceLinux[] list(String model) {
159                 AltosDeviceLinux[] devices = list();
160                 if (model != null) {
161                         LinkedList<AltosDeviceLinux> subset = new LinkedList<AltosDeviceLinux>();
162                         for (int i = 0; i < devices.length; i++) {
163                                 if (devices[i].product.startsWith(model))
164                                         subset.add(devices[i]);
165                         }
166                         devices = new AltosDeviceLinux[subset.size()];
167                         for (int e = 0; e < subset.size(); e++)
168                                 devices[e] = subset.get(e);
169                 }
170                 return devices;
171         }
172 }