-
Notifications
You must be signed in to change notification settings - Fork 2.6k
/
MoteFinder.java
226 lines (205 loc) · 7.63 KB
/
MoteFinder.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
* -----------------------------------------------------------------
*
* Motelist
*
* Authors : Joakim Eriksson, Niclas Finne
* Created : 4 jul 2008
* Updated : $Date: 2010/11/03 14:53:05 $
* $Revision: 1.1 $
*/
package org.contikios.contiki.collect;
import java.awt.Component;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JOptionPane;
/**
*
*/
public class MoteFinder {
public static final String MOTELIST_WINDOWS = "./tools/motelist-windows.exe";
public static final String MOTELIST_LINUX = "./tools/motelist-linux";
public static final String MOTELIST_MACOS = "./tools/motelist-macos";
private final Pattern motePattern;
private final boolean isWindows;
private final boolean isMacos;
private Process moteListProcess;
// private boolean hasVerifiedProcess;
private ArrayList<String> comList = new ArrayList<String>();
private ArrayList<String> moteList = new ArrayList<String>();
public MoteFinder() {
String osName = System.getProperty("os.name", "").toLowerCase();
isWindows = osName.startsWith("win");
isMacos = osName.startsWith("mac");
motePattern = Pattern.compile("\\s(COM|/dev/[a-zA-Z]+|/dev/tty.usbserial-)(\\d+|[A-Z0-9]+)\\s");
}
public String[] getMotes() throws IOException {
searchForMotes();
return getMoteList();
}
public String[] getComPorts() throws IOException {
searchForMotes();
return getComList();
}
private void searchForMotes() throws IOException {
comList.clear();
moteList.clear();
// hasVerifiedProcess = false;
/* Connect to COM using external serialdump application */
String fullCommand;
if (isWindows) {
fullCommand = MOTELIST_WINDOWS;
} else if (isMacos) {
fullCommand = MOTELIST_MACOS;
} else {
fullCommand = MOTELIST_LINUX;
}
try {
String[] cmd = new String[] { fullCommand };
moteListProcess = Runtime.getRuntime().exec(cmd);
final BufferedReader input = new BufferedReader(new InputStreamReader(moteListProcess.getInputStream()));
final BufferedReader err = new BufferedReader(new InputStreamReader(moteListProcess.getErrorStream()));
/* Start thread listening on stdout */
Thread readInput = new Thread(new Runnable() {
public void run() {
String line;
try {
while ((line = input.readLine()) != null) {
parseIncomingLine(line);
}
input.close();
} catch (IOException e) {
System.err.println("Exception when reading from motelist");
e.printStackTrace();
}
}
}, "read motelist thread");
/* Start thread listening on stderr */
Thread readError = new Thread(new Runnable() {
public void run() {
String line;
try {
while ((line = err.readLine()) != null) {
System.err.println("Motelist error stream> " + line);
}
err.close();
} catch (IOException e) {
System.err.println("Exception when reading from motelist error stream: " + e);
}
}
}, "read motelist error stream thread");
readInput.start();
readError.start();
// Wait for the motelist program to finish executing
readInput.join();
} catch (Exception e) {
throw (IOException) new IOException("Failed to execute '" + fullCommand + "'").initCause(e);
}
}
private String[] getComList() {
return comList.toArray(new String[comList.size()]);
}
private String[] getMoteList() {
return moteList.toArray(new String[moteList.size()]);
}
public void close() {
if (moteListProcess != null) {
moteListProcess.destroy();
moteListProcess = null;
}
}
protected void parseIncomingLine(String line) {
if (line.contains("No devices found") || line.startsWith("Reference")) {
// No Sky connected or title before connected motes
// hasVerifiedProcess = true;
} else if (line.startsWith("-------")) {
// Separator
} else {
Matcher matcher = motePattern.matcher(line);
if (matcher.find()) {
String dev = matcher.group(1);
String no = matcher.group(2);
String comPort = dev + no;
String moteID = comPort;
if (isWindows) {
// Special handling of mote id under Windows
int moteNumber = Integer.parseInt(no);
moteID = Integer.toString(moteNumber - 1);
}
comList.add(comPort);
moteList.add(moteID);
} else {
System.err.println("Motelist> " + line);
}
}
}
public static String selectComPort(Component parent) {
MoteFinder finder = new MoteFinder();
try {
String[] motes = finder.getComPorts();
if (motes == null || motes.length == 0) {
JOptionPane.showMessageDialog(parent, "Could not find any connected motes.", "No mote found", JOptionPane.ERROR_MESSAGE);
return null;
} else if (motes.length == 1) {
// Only one node found
return motes[0];
} else {
// Several motes found
return (String) JOptionPane.showInputDialog(
parent, "Found multiple connected motes. Please select serial port:",
"Select serial port", JOptionPane.QUESTION_MESSAGE, null, motes, motes[0]);
}
} catch (IOException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(parent, "Failed to search for connected motes:\n" + e, "Error", JOptionPane.ERROR_MESSAGE);
return null;
} finally {
finder.close();
}
}
public static void main(String[] args) throws IOException {
MoteFinder finder = new MoteFinder();
String[] comPorts = args.length > 0 && "-v".equals(args[0]) ?
finder.getMotes() : finder.getComPorts();
finder.close();
if (comPorts == null || comPorts.length == 0) {
System.out.println("No motes connected");
} else {
for(String port: comPorts) {
System.out.println("Found Sky at " + port);
}
}
}
}