sl@0
|
1 |
/*
|
sl@0
|
2 |
* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
3 |
* All rights reserved.
|
sl@0
|
4 |
* This component and the accompanying materials are made available
|
sl@0
|
5 |
* under the terms of "Eclipse Public License v1.0"
|
sl@0
|
6 |
* which accompanies this distribution, and is available
|
sl@0
|
7 |
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
8 |
*
|
sl@0
|
9 |
* Initial Contributors:
|
sl@0
|
10 |
* Nokia Corporation - initial contribution.
|
sl@0
|
11 |
*
|
sl@0
|
12 |
* Contributors:
|
sl@0
|
13 |
*
|
sl@0
|
14 |
* Description:
|
sl@0
|
15 |
*
|
sl@0
|
16 |
*/
|
sl@0
|
17 |
|
sl@0
|
18 |
|
sl@0
|
19 |
import gnu.io.CommPort;
|
sl@0
|
20 |
import gnu.io.CommPortIdentifier;
|
sl@0
|
21 |
import gnu.io.SerialPort;
|
sl@0
|
22 |
import gnu.io.SerialPortEvent;
|
sl@0
|
23 |
import gnu.io.SerialPortEventListener;
|
sl@0
|
24 |
|
sl@0
|
25 |
import java.util.logging.Logger;
|
sl@0
|
26 |
|
sl@0
|
27 |
import org.apache.commons.cli.Options;
|
sl@0
|
28 |
import org.apache.commons.cli.Option;
|
sl@0
|
29 |
import org.apache.commons.cli.OptionBuilder;
|
sl@0
|
30 |
import org.apache.commons.cli.CommandLineParser;
|
sl@0
|
31 |
import org.apache.commons.cli.PosixParser;
|
sl@0
|
32 |
import org.apache.commons.cli.CommandLine;
|
sl@0
|
33 |
import org.apache.commons.cli.HelpFormatter;
|
sl@0
|
34 |
|
sl@0
|
35 |
public class UartEchoServer implements SerialPortEventListener
|
sl@0
|
36 |
{
|
sl@0
|
37 |
// Command line options
|
sl@0
|
38 |
private static final String OPTION_HELP ="help";
|
sl@0
|
39 |
private static final String OPTION_PORT ="port";
|
sl@0
|
40 |
private static final String OPTION_BAUD ="baud_rate";
|
sl@0
|
41 |
private static final String OPTION_DATA ="data_bits";
|
sl@0
|
42 |
private static final String OPTION_STOP ="stop_bits";
|
sl@0
|
43 |
private static final String OPTION_PARITY ="parity";
|
sl@0
|
44 |
private static final String OPTION_FLOW ="flow_control";
|
sl@0
|
45 |
|
sl@0
|
46 |
// Default settings for serial port
|
sl@0
|
47 |
private static final String DEFAULT_PORT_NAME = "COM1";
|
sl@0
|
48 |
private static final int DEFAULT_BAUD_RATE = 9600;
|
sl@0
|
49 |
private static final int DEFAULT_DATA_BITS = SerialPort.DATABITS_8;
|
sl@0
|
50 |
private static final int DEFAULT_STOP_BITS = SerialPort.STOPBITS_1;
|
sl@0
|
51 |
private static final int DEFAULT_PARITY = SerialPort.PARITY_NONE;
|
sl@0
|
52 |
private static final int DEFAULT_FLOW_CONTROL= SerialPort.FLOWCONTROL_NONE;
|
sl@0
|
53 |
|
sl@0
|
54 |
// Command format limiters
|
sl@0
|
55 |
private static final byte BYTE_IGNORE = '\0'; // Null
|
sl@0
|
56 |
private static final byte BYTE_CLEARBI = '\1'; // Ctrl A
|
sl@0
|
57 |
private static final byte BYTE_QUERYBI = '\2'; // Ctrl B
|
sl@0
|
58 |
private static final byte BYTE_RESET = '\3'; // Ctrl C
|
sl@0
|
59 |
private static final byte BYTE_BLOCK_START = '[';
|
sl@0
|
60 |
private static final byte BYTE_BLOCK_END = ']';
|
sl@0
|
61 |
private static final String BLOCK_ASSIGN = "=";
|
sl@0
|
62 |
private static final String BLOCK_SEPERATOR = ",";
|
sl@0
|
63 |
|
sl@0
|
64 |
// Supported commands
|
sl@0
|
65 |
private static final String CMD_BAUD_RATE = "baud_rate";
|
sl@0
|
66 |
private static final String CMD_DATA_BITS = "data_bits";
|
sl@0
|
67 |
private static final String CMD_DELAY = "delay";
|
sl@0
|
68 |
private static final String CMD_DISCONNECT = "disconnect";
|
sl@0
|
69 |
private static final String CMD_ECHO = "echo";
|
sl@0
|
70 |
private static final String CMD_FLOW_CONTROL = "flow_control";
|
sl@0
|
71 |
private static final String CMD_LOG = "log";
|
sl@0
|
72 |
private static final String CMD_PARITY = "parity";
|
sl@0
|
73 |
private static final String CMD_STOP_BITS = "stop_bits";
|
sl@0
|
74 |
|
sl@0
|
75 |
// Supported data bits
|
sl@0
|
76 |
private static final String DATA_BITS_5 = "5";
|
sl@0
|
77 |
private static final String DATA_BITS_6 = "6";
|
sl@0
|
78 |
private static final String DATA_BITS_7 = "7";
|
sl@0
|
79 |
private static final String DATA_BITS_8 = "8";
|
sl@0
|
80 |
|
sl@0
|
81 |
// Supported flow control
|
sl@0
|
82 |
private static final String FLOWCONTROL_NONE = "none";
|
sl@0
|
83 |
private static final String FLOWCONTROL_RTSCTS = "rtscts";
|
sl@0
|
84 |
private static final String FLOWCONTROL_XONXOFF = "xonxoff";
|
sl@0
|
85 |
|
sl@0
|
86 |
// Supported parity
|
sl@0
|
87 |
private static final String PARITY_NONE = "none";
|
sl@0
|
88 |
private static final String PARITY_EVEN = "even";
|
sl@0
|
89 |
private static final String PARITY_ODD = "odd";
|
sl@0
|
90 |
private static final String PARITY_MARK = "mark";
|
sl@0
|
91 |
private static final String PARITY_SPACE = "space";
|
sl@0
|
92 |
|
sl@0
|
93 |
// Supported stop bits
|
sl@0
|
94 |
private static final String STOP_BITS_1 = "1";
|
sl@0
|
95 |
private static final String STOP_BITS_1_5 = "1.5";
|
sl@0
|
96 |
private static final String STOP_BITS_2 = "2";
|
sl@0
|
97 |
|
sl@0
|
98 |
// Constants
|
sl@0
|
99 |
private static final int BUFFER_SIZE = 1024;
|
sl@0
|
100 |
private static final int SLEEP_PERIOD = 200000;
|
sl@0
|
101 |
|
sl@0
|
102 |
private enum EStatus
|
sl@0
|
103 |
{
|
sl@0
|
104 |
EStatusEcho,
|
sl@0
|
105 |
EStatusCommandStart,
|
sl@0
|
106 |
};
|
sl@0
|
107 |
|
sl@0
|
108 |
private Thread iMainThread;
|
sl@0
|
109 |
private int iRestartingDelay;
|
sl@0
|
110 |
private boolean iRestarting;
|
sl@0
|
111 |
private boolean iRunning;
|
sl@0
|
112 |
private Logger iLogger;
|
sl@0
|
113 |
private byte[] iBuffer;
|
sl@0
|
114 |
private EStatus iStatus;
|
sl@0
|
115 |
private String iCommand;
|
sl@0
|
116 |
private String iPortName;
|
sl@0
|
117 |
private byte iBI;
|
sl@0
|
118 |
|
sl@0
|
119 |
private int iBaudRate;
|
sl@0
|
120 |
private int iDataBits;
|
sl@0
|
121 |
private int iStopBits;
|
sl@0
|
122 |
private int iParity;
|
sl@0
|
123 |
private int iFlowControl;
|
sl@0
|
124 |
|
sl@0
|
125 |
private int iStartupBaudRate;
|
sl@0
|
126 |
private int iStartupDataBits;
|
sl@0
|
127 |
private int iStartupStopBits;
|
sl@0
|
128 |
private int iStartupParity;
|
sl@0
|
129 |
private int iStartupFlowControl;
|
sl@0
|
130 |
|
sl@0
|
131 |
private CommPortIdentifier iPortIdentifier;
|
sl@0
|
132 |
private SerialPort iSerialPort;
|
sl@0
|
133 |
|
sl@0
|
134 |
/*
|
sl@0
|
135 |
* Constructor
|
sl@0
|
136 |
*/
|
sl@0
|
137 |
protected UartEchoServer() throws Exception
|
sl@0
|
138 |
{
|
sl@0
|
139 |
iRestartingDelay=0;
|
sl@0
|
140 |
iRestarting=true;
|
sl@0
|
141 |
iRunning=true;
|
sl@0
|
142 |
iLogger=Logger.getLogger("UartEchoServer");
|
sl@0
|
143 |
iBuffer=new byte[BUFFER_SIZE];
|
sl@0
|
144 |
iStatus = EStatus.EStatusEcho;
|
sl@0
|
145 |
iCommand = "";
|
sl@0
|
146 |
iBI=0;
|
sl@0
|
147 |
iPortName=DEFAULT_PORT_NAME;
|
sl@0
|
148 |
iBaudRate=DEFAULT_BAUD_RATE;
|
sl@0
|
149 |
iDataBits=DEFAULT_DATA_BITS;
|
sl@0
|
150 |
iStopBits=DEFAULT_STOP_BITS;
|
sl@0
|
151 |
iParity=DEFAULT_PARITY;
|
sl@0
|
152 |
iFlowControl=DEFAULT_FLOW_CONTROL;
|
sl@0
|
153 |
}
|
sl@0
|
154 |
|
sl@0
|
155 |
/*
|
sl@0
|
156 |
* Second pahse constructor
|
sl@0
|
157 |
*
|
sl@0
|
158 |
* @param aCommandLine Command line parameters
|
sl@0
|
159 |
*/
|
sl@0
|
160 |
protected void Construct(final CommandLine aCommandLine) throws Exception
|
sl@0
|
161 |
{
|
sl@0
|
162 |
/*
|
sl@0
|
163 |
* Set port name if passed in command line
|
sl@0
|
164 |
*/
|
sl@0
|
165 |
if ( aCommandLine.hasOption(OPTION_PORT) )
|
sl@0
|
166 |
{
|
sl@0
|
167 |
iPortName=aCommandLine.getOptionValue(OPTION_PORT);
|
sl@0
|
168 |
iLogger.info("PortName:" + iPortName);
|
sl@0
|
169 |
}
|
sl@0
|
170 |
|
sl@0
|
171 |
/*
|
sl@0
|
172 |
* Set baud rate if passed in command line
|
sl@0
|
173 |
*/
|
sl@0
|
174 |
if ( aCommandLine.hasOption(OPTION_BAUD) )
|
sl@0
|
175 |
{
|
sl@0
|
176 |
setBaudRate(aCommandLine.getOptionValue(OPTION_BAUD));
|
sl@0
|
177 |
iLogger.info("Baud Rate:" + iBaudRate);
|
sl@0
|
178 |
}
|
sl@0
|
179 |
|
sl@0
|
180 |
/*
|
sl@0
|
181 |
* Set data bits if passed in command line
|
sl@0
|
182 |
*/
|
sl@0
|
183 |
if ( aCommandLine.hasOption(OPTION_DATA) )
|
sl@0
|
184 |
{
|
sl@0
|
185 |
setDataBits(aCommandLine.getOptionValue(OPTION_DATA));
|
sl@0
|
186 |
iLogger.info("Data Bits:" + iDataBits);
|
sl@0
|
187 |
}
|
sl@0
|
188 |
|
sl@0
|
189 |
/*
|
sl@0
|
190 |
* Set stop bits if passed in command line
|
sl@0
|
191 |
*/
|
sl@0
|
192 |
if ( aCommandLine.hasOption(OPTION_STOP) )
|
sl@0
|
193 |
{
|
sl@0
|
194 |
setStopBits(aCommandLine.getOptionValue(OPTION_STOP));
|
sl@0
|
195 |
iLogger.info("Stop Bits:" + iStopBits);
|
sl@0
|
196 |
}
|
sl@0
|
197 |
|
sl@0
|
198 |
/*
|
sl@0
|
199 |
* Set parity if passed in command line
|
sl@0
|
200 |
*/
|
sl@0
|
201 |
if ( aCommandLine.hasOption(OPTION_PARITY) )
|
sl@0
|
202 |
{
|
sl@0
|
203 |
setParity(aCommandLine.getOptionValue(OPTION_PARITY));
|
sl@0
|
204 |
iLogger.info("Parity:" + iParity);
|
sl@0
|
205 |
}
|
sl@0
|
206 |
|
sl@0
|
207 |
/*
|
sl@0
|
208 |
* Set flow control if passed in command line
|
sl@0
|
209 |
*/
|
sl@0
|
210 |
if ( aCommandLine.hasOption(OPTION_FLOW) )
|
sl@0
|
211 |
{
|
sl@0
|
212 |
setFlowControl(aCommandLine.getOptionValue(OPTION_FLOW));
|
sl@0
|
213 |
iLogger.info("Flow Control:" + iFlowControl);
|
sl@0
|
214 |
}
|
sl@0
|
215 |
|
sl@0
|
216 |
/*
|
sl@0
|
217 |
* Save startup values. Used by reset command
|
sl@0
|
218 |
*/
|
sl@0
|
219 |
iStartupBaudRate=iBaudRate;
|
sl@0
|
220 |
iStartupDataBits=iDataBits;
|
sl@0
|
221 |
iStartupStopBits=iStopBits;
|
sl@0
|
222 |
iStartupParity=iParity;
|
sl@0
|
223 |
iStartupFlowControl=iFlowControl;
|
sl@0
|
224 |
|
sl@0
|
225 |
/*
|
sl@0
|
226 |
* Make sure port is not in use
|
sl@0
|
227 |
*/
|
sl@0
|
228 |
iPortIdentifier=CommPortIdentifier.getPortIdentifier(iPortName);
|
sl@0
|
229 |
if ( iPortIdentifier.isCurrentlyOwned() )
|
sl@0
|
230 |
{
|
sl@0
|
231 |
throw new Exception("Error: Port is currently in use");
|
sl@0
|
232 |
}
|
sl@0
|
233 |
|
sl@0
|
234 |
/*
|
sl@0
|
235 |
* Port not in use so open it
|
sl@0
|
236 |
*/
|
sl@0
|
237 |
CommPort commPort=iPortIdentifier.open(this.getClass().getName(), 2000);
|
sl@0
|
238 |
|
sl@0
|
239 |
/*
|
sl@0
|
240 |
* Save thread
|
sl@0
|
241 |
*/
|
sl@0
|
242 |
iMainThread=Thread.currentThread();
|
sl@0
|
243 |
|
sl@0
|
244 |
/*
|
sl@0
|
245 |
* Make sure the port is of type serial
|
sl@0
|
246 |
*/
|
sl@0
|
247 |
if ( commPort instanceof SerialPort )
|
sl@0
|
248 |
{
|
sl@0
|
249 |
iSerialPort = (SerialPort) commPort;
|
sl@0
|
250 |
iFlowControl=iSerialPort.getFlowControlMode();
|
sl@0
|
251 |
while ( iRunning )
|
sl@0
|
252 |
{
|
sl@0
|
253 |
initPort();
|
sl@0
|
254 |
|
sl@0
|
255 |
iRestarting=false;
|
sl@0
|
256 |
while ( iRunning && !iRestarting )
|
sl@0
|
257 |
{
|
sl@0
|
258 |
try
|
sl@0
|
259 |
{
|
sl@0
|
260 |
iMainThread.sleep(SLEEP_PERIOD);
|
sl@0
|
261 |
}
|
sl@0
|
262 |
catch ( InterruptedException e )
|
sl@0
|
263 |
{
|
sl@0
|
264 |
}
|
sl@0
|
265 |
}
|
sl@0
|
266 |
iSerialPort.close();
|
sl@0
|
267 |
if ( iRestarting )
|
sl@0
|
268 |
{
|
sl@0
|
269 |
iLogger.finest("Restarting");
|
sl@0
|
270 |
iMainThread.sleep(iRestartingDelay);
|
sl@0
|
271 |
commPort=iPortIdentifier.open(this.getClass().getName(), 2000);
|
sl@0
|
272 |
iSerialPort = (SerialPort) commPort;
|
sl@0
|
273 |
}
|
sl@0
|
274 |
}
|
sl@0
|
275 |
}
|
sl@0
|
276 |
else
|
sl@0
|
277 |
{
|
sl@0
|
278 |
throw new Exception("Error: Only serial ports are handled by this example.");
|
sl@0
|
279 |
}
|
sl@0
|
280 |
}
|
sl@0
|
281 |
|
sl@0
|
282 |
/*
|
sl@0
|
283 |
* Initialise the port
|
sl@0
|
284 |
*/
|
sl@0
|
285 |
private void initPort() throws Exception
|
sl@0
|
286 |
{
|
sl@0
|
287 |
iSerialPort.setSerialPortParams(iBaudRate, iDataBits, iStopBits, iParity);
|
sl@0
|
288 |
iSerialPort.setFlowControlMode(iFlowControl);
|
sl@0
|
289 |
iSerialPort.addEventListener(this);
|
sl@0
|
290 |
iSerialPort.notifyOnBreakInterrupt(true);
|
sl@0
|
291 |
iSerialPort.notifyOnCarrierDetect(true);
|
sl@0
|
292 |
iSerialPort.notifyOnCTS(true);
|
sl@0
|
293 |
iSerialPort.notifyOnDataAvailable(true);
|
sl@0
|
294 |
iSerialPort.notifyOnDSR(true);
|
sl@0
|
295 |
iSerialPort.notifyOnFramingError(true);
|
sl@0
|
296 |
iSerialPort.notifyOnOutputEmpty(true);
|
sl@0
|
297 |
iSerialPort.notifyOnOverrunError(true);
|
sl@0
|
298 |
iSerialPort.notifyOnParityError(true);
|
sl@0
|
299 |
iSerialPort.notifyOnRingIndicator(true);
|
sl@0
|
300 |
iSerialPort.setInputBufferSize(BUFFER_SIZE);
|
sl@0
|
301 |
}
|
sl@0
|
302 |
|
sl@0
|
303 |
/*
|
sl@0
|
304 |
* Set the baud rate
|
sl@0
|
305 |
*
|
sl@0
|
306 |
* @param aValue String representation of the baud rate
|
sl@0
|
307 |
*/
|
sl@0
|
308 |
private void setBaudRate(final String aValue)
|
sl@0
|
309 |
{
|
sl@0
|
310 |
try
|
sl@0
|
311 |
{
|
sl@0
|
312 |
iBaudRate=Integer.parseInt(aValue);
|
sl@0
|
313 |
}
|
sl@0
|
314 |
catch (Exception e)
|
sl@0
|
315 |
{
|
sl@0
|
316 |
iLogger.severe("convertToBaudRate(" + aValue + "):exception" + e);
|
sl@0
|
317 |
}
|
sl@0
|
318 |
}
|
sl@0
|
319 |
|
sl@0
|
320 |
/*
|
sl@0
|
321 |
* Set the data bits
|
sl@0
|
322 |
*
|
sl@0
|
323 |
* @param aValue String representation of the data bits
|
sl@0
|
324 |
*/
|
sl@0
|
325 |
private void setDataBits(final String aValue)
|
sl@0
|
326 |
{
|
sl@0
|
327 |
try
|
sl@0
|
328 |
{
|
sl@0
|
329 |
if ( aValue.compareTo(DATA_BITS_5)==0 )
|
sl@0
|
330 |
{
|
sl@0
|
331 |
iDataBits=SerialPort.DATABITS_5;
|
sl@0
|
332 |
}
|
sl@0
|
333 |
else if ( aValue.compareTo(DATA_BITS_6)==0 )
|
sl@0
|
334 |
{
|
sl@0
|
335 |
iDataBits=SerialPort.DATABITS_6;
|
sl@0
|
336 |
}
|
sl@0
|
337 |
else if ( aValue.compareTo(DATA_BITS_7)==0 )
|
sl@0
|
338 |
{
|
sl@0
|
339 |
iDataBits=SerialPort.DATABITS_7;
|
sl@0
|
340 |
}
|
sl@0
|
341 |
else if ( aValue.compareTo(DATA_BITS_8)==0 )
|
sl@0
|
342 |
{
|
sl@0
|
343 |
iDataBits=SerialPort.DATABITS_8;
|
sl@0
|
344 |
}
|
sl@0
|
345 |
else
|
sl@0
|
346 |
{
|
sl@0
|
347 |
iLogger.severe("setDataBits(" + aValue + ")");
|
sl@0
|
348 |
}
|
sl@0
|
349 |
}
|
sl@0
|
350 |
catch (Exception e)
|
sl@0
|
351 |
{
|
sl@0
|
352 |
iLogger.severe("setDataBits(" + aValue + "):excpetion" + e);
|
sl@0
|
353 |
}
|
sl@0
|
354 |
}
|
sl@0
|
355 |
|
sl@0
|
356 |
/*
|
sl@0
|
357 |
* Set the flow control
|
sl@0
|
358 |
*
|
sl@0
|
359 |
* @param aValue String representation of the flow control
|
sl@0
|
360 |
*/
|
sl@0
|
361 |
private void setFlowControl(final String aValue)
|
sl@0
|
362 |
{
|
sl@0
|
363 |
try
|
sl@0
|
364 |
{
|
sl@0
|
365 |
if ( aValue.compareTo(FLOWCONTROL_NONE)==0 )
|
sl@0
|
366 |
{
|
sl@0
|
367 |
iFlowControl=SerialPort.FLOWCONTROL_NONE;
|
sl@0
|
368 |
}
|
sl@0
|
369 |
else if ( aValue.compareTo(FLOWCONTROL_RTSCTS)==0 )
|
sl@0
|
370 |
{
|
sl@0
|
371 |
iFlowControl=SerialPort.FLOWCONTROL_RTSCTS_IN | SerialPort.FLOWCONTROL_RTSCTS_OUT;
|
sl@0
|
372 |
}
|
sl@0
|
373 |
else if ( aValue.compareTo(FLOWCONTROL_XONXOFF)==0 )
|
sl@0
|
374 |
{
|
sl@0
|
375 |
iFlowControl=SerialPort.FLOWCONTROL_XONXOFF_IN | SerialPort.FLOWCONTROL_XONXOFF_OUT;
|
sl@0
|
376 |
}
|
sl@0
|
377 |
else
|
sl@0
|
378 |
{
|
sl@0
|
379 |
iLogger.severe("setFlowControl(" + aValue + ")");
|
sl@0
|
380 |
}
|
sl@0
|
381 |
}
|
sl@0
|
382 |
catch (Exception e)
|
sl@0
|
383 |
{
|
sl@0
|
384 |
iLogger.severe("setFlowControl(" + aValue + "):exception" + e);
|
sl@0
|
385 |
}
|
sl@0
|
386 |
}
|
sl@0
|
387 |
|
sl@0
|
388 |
/*
|
sl@0
|
389 |
* Set the parity
|
sl@0
|
390 |
*
|
sl@0
|
391 |
* @param aValue String representation of the parity
|
sl@0
|
392 |
*/
|
sl@0
|
393 |
private void setParity(final String aValue)
|
sl@0
|
394 |
{
|
sl@0
|
395 |
try
|
sl@0
|
396 |
{
|
sl@0
|
397 |
if ( aValue.compareTo(PARITY_NONE)==0 )
|
sl@0
|
398 |
{
|
sl@0
|
399 |
iParity=SerialPort.PARITY_NONE;
|
sl@0
|
400 |
}
|
sl@0
|
401 |
else if ( aValue.compareTo(PARITY_EVEN)==0 )
|
sl@0
|
402 |
{
|
sl@0
|
403 |
iParity=SerialPort.PARITY_EVEN;
|
sl@0
|
404 |
}
|
sl@0
|
405 |
else if ( aValue.compareTo(PARITY_ODD)==0 )
|
sl@0
|
406 |
{
|
sl@0
|
407 |
iParity=SerialPort.PARITY_ODD;
|
sl@0
|
408 |
}
|
sl@0
|
409 |
else if ( aValue.compareTo(PARITY_MARK)==0 )
|
sl@0
|
410 |
{
|
sl@0
|
411 |
iParity=SerialPort.PARITY_MARK;
|
sl@0
|
412 |
}
|
sl@0
|
413 |
else if ( aValue.compareTo(PARITY_SPACE)==0 )
|
sl@0
|
414 |
{
|
sl@0
|
415 |
iParity=SerialPort.PARITY_SPACE;
|
sl@0
|
416 |
}
|
sl@0
|
417 |
else
|
sl@0
|
418 |
{
|
sl@0
|
419 |
iLogger.severe("setParity(" + aValue + ")");
|
sl@0
|
420 |
}
|
sl@0
|
421 |
}
|
sl@0
|
422 |
catch (Exception e)
|
sl@0
|
423 |
{
|
sl@0
|
424 |
iLogger.severe("setParity(" + aValue + "):exception" + e);
|
sl@0
|
425 |
}
|
sl@0
|
426 |
}
|
sl@0
|
427 |
|
sl@0
|
428 |
/*
|
sl@0
|
429 |
* Set the stop bits
|
sl@0
|
430 |
*
|
sl@0
|
431 |
* @param aValue String representation of the stop bits
|
sl@0
|
432 |
*/
|
sl@0
|
433 |
private void setStopBits(final String aValue)
|
sl@0
|
434 |
{
|
sl@0
|
435 |
try
|
sl@0
|
436 |
{
|
sl@0
|
437 |
if ( aValue.compareTo(STOP_BITS_1)==0 )
|
sl@0
|
438 |
{
|
sl@0
|
439 |
iStopBits=SerialPort.STOPBITS_1;
|
sl@0
|
440 |
}
|
sl@0
|
441 |
else if ( aValue.compareTo(STOP_BITS_1_5)==0 )
|
sl@0
|
442 |
{
|
sl@0
|
443 |
iStopBits=SerialPort.STOPBITS_1_5;
|
sl@0
|
444 |
}
|
sl@0
|
445 |
else if ( aValue.compareTo(STOP_BITS_2)==0 )
|
sl@0
|
446 |
{
|
sl@0
|
447 |
iStopBits=SerialPort.STOPBITS_2;
|
sl@0
|
448 |
}
|
sl@0
|
449 |
else
|
sl@0
|
450 |
{
|
sl@0
|
451 |
iLogger.severe("setStopBits(" + aValue + ")");
|
sl@0
|
452 |
}
|
sl@0
|
453 |
}
|
sl@0
|
454 |
catch (Exception e)
|
sl@0
|
455 |
{
|
sl@0
|
456 |
iLogger.severe("setStopBits(" + aValue + "):exception" + e);
|
sl@0
|
457 |
}
|
sl@0
|
458 |
}
|
sl@0
|
459 |
|
sl@0
|
460 |
/*
|
sl@0
|
461 |
* Process a command from the input
|
sl@0
|
462 |
*/
|
sl@0
|
463 |
private void processCommand() throws Exception
|
sl@0
|
464 |
{
|
sl@0
|
465 |
final String values[] = iCommand.split(BLOCK_SEPERATOR);
|
sl@0
|
466 |
|
sl@0
|
467 |
iSerialPort.getOutputStream().flush();
|
sl@0
|
468 |
for ( int i=0; i<values.length; i++ )
|
sl@0
|
469 |
{
|
sl@0
|
470 |
/*
|
sl@0
|
471 |
* Commands should be of the type variable=value
|
sl@0
|
472 |
*/
|
sl@0
|
473 |
final String parts[]=values[i].split(BLOCK_ASSIGN);
|
sl@0
|
474 |
|
sl@0
|
475 |
if ( parts.length==2 )
|
sl@0
|
476 |
{
|
sl@0
|
477 |
/*
|
sl@0
|
478 |
* Set baud rate command
|
sl@0
|
479 |
*/
|
sl@0
|
480 |
if ( parts[0].compareTo(CMD_BAUD_RATE)==0 )
|
sl@0
|
481 |
{
|
sl@0
|
482 |
setBaudRate(parts[1]);
|
sl@0
|
483 |
iSerialPort.setSerialPortParams(iBaudRate, iDataBits, iStopBits, iParity);
|
sl@0
|
484 |
}
|
sl@0
|
485 |
/*
|
sl@0
|
486 |
* Set data bits command
|
sl@0
|
487 |
*/
|
sl@0
|
488 |
else if ( parts[0].compareTo(CMD_DATA_BITS)==0 )
|
sl@0
|
489 |
{
|
sl@0
|
490 |
setDataBits(parts[1]);
|
sl@0
|
491 |
iSerialPort.setSerialPortParams(iBaudRate, iDataBits, iStopBits, iParity);
|
sl@0
|
492 |
}
|
sl@0
|
493 |
/*
|
sl@0
|
494 |
* Delay command
|
sl@0
|
495 |
*/
|
sl@0
|
496 |
else if ( parts[0].compareTo(CMD_DELAY)==0 )
|
sl@0
|
497 |
{
|
sl@0
|
498 |
final int delay=Integer.parseInt(parts[1]);
|
sl@0
|
499 |
Thread.sleep(delay);
|
sl@0
|
500 |
}
|
sl@0
|
501 |
/*
|
sl@0
|
502 |
* Disconnect command
|
sl@0
|
503 |
*/
|
sl@0
|
504 |
else if ( parts[0].compareTo(CMD_DISCONNECT)==0 )
|
sl@0
|
505 |
{
|
sl@0
|
506 |
iRestartingDelay=Integer.parseInt(parts[1]);
|
sl@0
|
507 |
iRestarting=true;
|
sl@0
|
508 |
}
|
sl@0
|
509 |
/*
|
sl@0
|
510 |
* Echo command
|
sl@0
|
511 |
*/
|
sl@0
|
512 |
else if ( parts[0].compareTo(CMD_ECHO)==0 )
|
sl@0
|
513 |
{
|
sl@0
|
514 |
final int length=parts[1].length();
|
sl@0
|
515 |
for ( int index=0; index<length; ++index )
|
sl@0
|
516 |
{
|
sl@0
|
517 |
final byte out=(byte)(parts[1].charAt(index));
|
sl@0
|
518 |
iLogger.finest("<< " + out);
|
sl@0
|
519 |
iSerialPort.getOutputStream().write(out);
|
sl@0
|
520 |
}
|
sl@0
|
521 |
}
|
sl@0
|
522 |
/*
|
sl@0
|
523 |
* Set flow control command
|
sl@0
|
524 |
*/
|
sl@0
|
525 |
else if ( parts[0].compareTo(CMD_FLOW_CONTROL)==0 )
|
sl@0
|
526 |
{
|
sl@0
|
527 |
setFlowControl(parts[1]);
|
sl@0
|
528 |
iSerialPort.setFlowControlMode(iFlowControl);
|
sl@0
|
529 |
}
|
sl@0
|
530 |
/*
|
sl@0
|
531 |
* Log command
|
sl@0
|
532 |
*/
|
sl@0
|
533 |
else if ( parts[0].compareTo(CMD_LOG)==0 )
|
sl@0
|
534 |
{
|
sl@0
|
535 |
iLogger.info(parts[1]);
|
sl@0
|
536 |
}
|
sl@0
|
537 |
/*
|
sl@0
|
538 |
* Set parity command
|
sl@0
|
539 |
*/
|
sl@0
|
540 |
else if ( parts[0].compareTo(CMD_PARITY)==0 )
|
sl@0
|
541 |
{
|
sl@0
|
542 |
setParity(parts[1]);
|
sl@0
|
543 |
iSerialPort.setSerialPortParams(iBaudRate, iDataBits, iStopBits, iParity);
|
sl@0
|
544 |
}
|
sl@0
|
545 |
/*
|
sl@0
|
546 |
* Set stop bits command
|
sl@0
|
547 |
*/
|
sl@0
|
548 |
else if ( parts[0].compareTo(CMD_STOP_BITS)==0 )
|
sl@0
|
549 |
{
|
sl@0
|
550 |
setStopBits(parts[1]);
|
sl@0
|
551 |
iSerialPort.setSerialPortParams(iBaudRate, iDataBits, iStopBits, iParity);
|
sl@0
|
552 |
}
|
sl@0
|
553 |
/*
|
sl@0
|
554 |
* Error command
|
sl@0
|
555 |
*/
|
sl@0
|
556 |
else
|
sl@0
|
557 |
{
|
sl@0
|
558 |
iLogger.severe("Bad command(" + parts[0] + ")");
|
sl@0
|
559 |
}
|
sl@0
|
560 |
}
|
sl@0
|
561 |
else
|
sl@0
|
562 |
{
|
sl@0
|
563 |
iLogger.severe("Bad data");
|
sl@0
|
564 |
}
|
sl@0
|
565 |
}
|
sl@0
|
566 |
}
|
sl@0
|
567 |
|
sl@0
|
568 |
/*
|
sl@0
|
569 |
* Process data read from input stream
|
sl@0
|
570 |
*
|
sl@0
|
571 |
* @param aLength Length of the data in the buffer
|
sl@0
|
572 |
*/
|
sl@0
|
573 |
private void processInput(final int aLength) throws Exception
|
sl@0
|
574 |
{
|
sl@0
|
575 |
final String buffer=new String(iBuffer, 0, aLength);
|
sl@0
|
576 |
iLogger.finest(">> " + buffer);
|
sl@0
|
577 |
for ( int index=0; index<aLength; ++index )
|
sl@0
|
578 |
{
|
sl@0
|
579 |
switch ( iBuffer[index] )
|
sl@0
|
580 |
{
|
sl@0
|
581 |
/*
|
sl@0
|
582 |
* Ignored data
|
sl@0
|
583 |
*/
|
sl@0
|
584 |
case BYTE_IGNORE:
|
sl@0
|
585 |
break;
|
sl@0
|
586 |
/*
|
sl@0
|
587 |
* Clear the break interrupt count
|
sl@0
|
588 |
*/
|
sl@0
|
589 |
case BYTE_CLEARBI:
|
sl@0
|
590 |
iBI=0;
|
sl@0
|
591 |
break;
|
sl@0
|
592 |
/*
|
sl@0
|
593 |
* Query the break interrupt count
|
sl@0
|
594 |
*/
|
sl@0
|
595 |
case BYTE_QUERYBI:
|
sl@0
|
596 |
iLogger.finest("BI Count=" + iBI);
|
sl@0
|
597 |
iLogger.finest("<< " + iBI);
|
sl@0
|
598 |
iSerialPort.getOutputStream().write(iBI);
|
sl@0
|
599 |
break;
|
sl@0
|
600 |
/*
|
sl@0
|
601 |
* Reset port setting to startup values
|
sl@0
|
602 |
*/
|
sl@0
|
603 |
case BYTE_RESET:
|
sl@0
|
604 |
iBaudRate=iStartupBaudRate;
|
sl@0
|
605 |
iDataBits=iStartupDataBits;
|
sl@0
|
606 |
iStopBits=iStartupStopBits;
|
sl@0
|
607 |
iParity=iStartupParity;
|
sl@0
|
608 |
iFlowControl=iStartupFlowControl;
|
sl@0
|
609 |
iSerialPort.setFlowControlMode(iFlowControl);
|
sl@0
|
610 |
iSerialPort.setSerialPortParams(iBaudRate, iDataBits, iStopBits, iParity);
|
sl@0
|
611 |
iStatus=EStatus.EStatusEcho;
|
sl@0
|
612 |
break;
|
sl@0
|
613 |
default:
|
sl@0
|
614 |
/*
|
sl@0
|
615 |
* If in command mode add the byte to the command buffer
|
sl@0
|
616 |
* unless we read the end of command block character
|
sl@0
|
617 |
*/
|
sl@0
|
618 |
if ( iStatus==EStatus.EStatusCommandStart )
|
sl@0
|
619 |
{
|
sl@0
|
620 |
if ( iBuffer[index]==BYTE_BLOCK_END )
|
sl@0
|
621 |
{
|
sl@0
|
622 |
processCommand();
|
sl@0
|
623 |
iStatus=EStatus.EStatusEcho;
|
sl@0
|
624 |
}
|
sl@0
|
625 |
else
|
sl@0
|
626 |
{
|
sl@0
|
627 |
iCommand += buffer.charAt(index);
|
sl@0
|
628 |
}
|
sl@0
|
629 |
}
|
sl@0
|
630 |
/*
|
sl@0
|
631 |
* If in echo mode, echo the character unless we read the
|
sl@0
|
632 |
* start of command block character
|
sl@0
|
633 |
*/
|
sl@0
|
634 |
else if ( iStatus==EStatus.EStatusEcho )
|
sl@0
|
635 |
{
|
sl@0
|
636 |
if ( iBuffer[index]==BYTE_BLOCK_START )
|
sl@0
|
637 |
{
|
sl@0
|
638 |
iCommand="";
|
sl@0
|
639 |
iStatus=EStatus.EStatusCommandStart;
|
sl@0
|
640 |
}
|
sl@0
|
641 |
else
|
sl@0
|
642 |
{
|
sl@0
|
643 |
iLogger.finest("<< " + iBuffer[index]);
|
sl@0
|
644 |
iSerialPort.getOutputStream().write(iBuffer[index]);
|
sl@0
|
645 |
}
|
sl@0
|
646 |
}
|
sl@0
|
647 |
break;
|
sl@0
|
648 |
}
|
sl@0
|
649 |
}
|
sl@0
|
650 |
}
|
sl@0
|
651 |
|
sl@0
|
652 |
/*
|
sl@0
|
653 |
* Serial port event received
|
sl@0
|
654 |
*
|
sl@0
|
655 |
* @param aEvent Event received
|
sl@0
|
656 |
*/
|
sl@0
|
657 |
public void serialEvent(SerialPortEvent aEvent)
|
sl@0
|
658 |
{
|
sl@0
|
659 |
switch ( aEvent.getEventType() )
|
sl@0
|
660 |
{
|
sl@0
|
661 |
case SerialPortEvent.DATA_AVAILABLE:
|
sl@0
|
662 |
/*
|
sl@0
|
663 |
* Process data in input buffer
|
sl@0
|
664 |
*/
|
sl@0
|
665 |
try
|
sl@0
|
666 |
{
|
sl@0
|
667 |
final int length = iSerialPort.getInputStream().read(iBuffer);
|
sl@0
|
668 |
|
sl@0
|
669 |
if ( length>0 )
|
sl@0
|
670 |
{
|
sl@0
|
671 |
processInput(length);
|
sl@0
|
672 |
}
|
sl@0
|
673 |
}
|
sl@0
|
674 |
catch (Exception e)
|
sl@0
|
675 |
{
|
sl@0
|
676 |
e.printStackTrace();
|
sl@0
|
677 |
}
|
sl@0
|
678 |
if ( iRestarting )
|
sl@0
|
679 |
{
|
sl@0
|
680 |
iMainThread.interrupt();
|
sl@0
|
681 |
}
|
sl@0
|
682 |
break;
|
sl@0
|
683 |
case SerialPortEvent.BI:
|
sl@0
|
684 |
/*
|
sl@0
|
685 |
* Increment break interrupt count
|
sl@0
|
686 |
*/
|
sl@0
|
687 |
++iBI;
|
sl@0
|
688 |
iLogger.finest("Break Interrupt");
|
sl@0
|
689 |
break;
|
sl@0
|
690 |
case SerialPortEvent.CD:
|
sl@0
|
691 |
/*
|
sl@0
|
692 |
* Ignore
|
sl@0
|
693 |
*/
|
sl@0
|
694 |
iLogger.finest("Carrier Detect");
|
sl@0
|
695 |
break;
|
sl@0
|
696 |
case SerialPortEvent.CTS:
|
sl@0
|
697 |
/*
|
sl@0
|
698 |
* Ignore
|
sl@0
|
699 |
*/
|
sl@0
|
700 |
iLogger.finest("Clear To Send");
|
sl@0
|
701 |
break;
|
sl@0
|
702 |
case SerialPortEvent.DSR:
|
sl@0
|
703 |
/*
|
sl@0
|
704 |
* Ignore
|
sl@0
|
705 |
*/
|
sl@0
|
706 |
iLogger.finest("Data Set Ready");
|
sl@0
|
707 |
break;
|
sl@0
|
708 |
case SerialPortEvent.FE:
|
sl@0
|
709 |
/*
|
sl@0
|
710 |
* Ignore
|
sl@0
|
711 |
*/
|
sl@0
|
712 |
iLogger.finest("Framing Error");
|
sl@0
|
713 |
break;
|
sl@0
|
714 |
case SerialPortEvent.OE:
|
sl@0
|
715 |
/*
|
sl@0
|
716 |
* Ignore
|
sl@0
|
717 |
*/
|
sl@0
|
718 |
iLogger.finest("Overflow Error");
|
sl@0
|
719 |
break;
|
sl@0
|
720 |
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
|
sl@0
|
721 |
/*
|
sl@0
|
722 |
* Ignore
|
sl@0
|
723 |
*/
|
sl@0
|
724 |
iLogger.finest("Output Buffer Empty");
|
sl@0
|
725 |
break;
|
sl@0
|
726 |
case SerialPortEvent.PE:
|
sl@0
|
727 |
/*
|
sl@0
|
728 |
* Ignore
|
sl@0
|
729 |
*/
|
sl@0
|
730 |
iLogger.finest("Parity Error");
|
sl@0
|
731 |
break;
|
sl@0
|
732 |
case SerialPortEvent.RI:
|
sl@0
|
733 |
/*
|
sl@0
|
734 |
* Ignore
|
sl@0
|
735 |
*/
|
sl@0
|
736 |
iLogger.finest("Ring Interrupt");
|
sl@0
|
737 |
break;
|
sl@0
|
738 |
default:
|
sl@0
|
739 |
iLogger.finest("Unknown event");
|
sl@0
|
740 |
break;
|
sl@0
|
741 |
}
|
sl@0
|
742 |
}
|
sl@0
|
743 |
|
sl@0
|
744 |
/*
|
sl@0
|
745 |
* Application entry point
|
sl@0
|
746 |
*
|
sl@0
|
747 |
* @param aArgs COmmand line arguments
|
sl@0
|
748 |
*/
|
sl@0
|
749 |
public static void main(String[] aArgs)
|
sl@0
|
750 |
{
|
sl@0
|
751 |
final Options options = new Options();
|
sl@0
|
752 |
|
sl@0
|
753 |
options.addOption(new Option(OPTION_HELP, "print this message"));
|
sl@0
|
754 |
|
sl@0
|
755 |
OptionBuilder.withLongOpt(OPTION_PORT);
|
sl@0
|
756 |
OptionBuilder.withDescription("set port COMx");
|
sl@0
|
757 |
OptionBuilder.withValueSeparator( '=' );
|
sl@0
|
758 |
OptionBuilder.hasArg();
|
sl@0
|
759 |
options.addOption(OptionBuilder.create());
|
sl@0
|
760 |
|
sl@0
|
761 |
OptionBuilder.withLongOpt(OPTION_BAUD);
|
sl@0
|
762 |
OptionBuilder.withDescription("set the baud rate");
|
sl@0
|
763 |
OptionBuilder.withValueSeparator( '=' );
|
sl@0
|
764 |
OptionBuilder.hasArg();
|
sl@0
|
765 |
options.addOption(OptionBuilder.create());
|
sl@0
|
766 |
|
sl@0
|
767 |
OptionBuilder.withLongOpt(OPTION_DATA);
|
sl@0
|
768 |
OptionBuilder.withDescription("set the data bits [" + DATA_BITS_5 +"|" + DATA_BITS_6 + "|" + DATA_BITS_7 + "|" + DATA_BITS_8 + "]");
|
sl@0
|
769 |
OptionBuilder.withValueSeparator( '=' );
|
sl@0
|
770 |
OptionBuilder.hasArg();
|
sl@0
|
771 |
options.addOption(OptionBuilder.create());
|
sl@0
|
772 |
|
sl@0
|
773 |
OptionBuilder.withLongOpt(OPTION_STOP);
|
sl@0
|
774 |
OptionBuilder.withDescription("set the stop bits [" + STOP_BITS_1 + "|" + STOP_BITS_1_5 + "|" + STOP_BITS_2 + "]");
|
sl@0
|
775 |
OptionBuilder.withValueSeparator( '=' );
|
sl@0
|
776 |
OptionBuilder.hasArg();
|
sl@0
|
777 |
options.addOption(OptionBuilder.create());
|
sl@0
|
778 |
|
sl@0
|
779 |
OptionBuilder.withLongOpt(OPTION_PARITY);
|
sl@0
|
780 |
OptionBuilder.withDescription("set the parity [" + PARITY_NONE + "|" + PARITY_EVEN + "|" + PARITY_ODD + "|" + PARITY_MARK + "|" + PARITY_SPACE + "]");
|
sl@0
|
781 |
OptionBuilder.withValueSeparator( '=' );
|
sl@0
|
782 |
OptionBuilder.hasArg();
|
sl@0
|
783 |
options.addOption(OptionBuilder.create());
|
sl@0
|
784 |
|
sl@0
|
785 |
OptionBuilder.withLongOpt(OPTION_FLOW);
|
sl@0
|
786 |
OptionBuilder.withDescription("set the flow control [" + FLOWCONTROL_NONE + "|" + FLOWCONTROL_RTSCTS + "|" + FLOWCONTROL_XONXOFF + "]");
|
sl@0
|
787 |
OptionBuilder.withValueSeparator( '=' );
|
sl@0
|
788 |
OptionBuilder.hasArg();
|
sl@0
|
789 |
options.addOption(OptionBuilder.create());
|
sl@0
|
790 |
|
sl@0
|
791 |
final CommandLineParser parser = new PosixParser();
|
sl@0
|
792 |
|
sl@0
|
793 |
try
|
sl@0
|
794 |
{
|
sl@0
|
795 |
// parse the command line arguments
|
sl@0
|
796 |
final CommandLine commandLine = parser.parse(options, aArgs);
|
sl@0
|
797 |
|
sl@0
|
798 |
if ( commandLine.hasOption(OPTION_HELP) )
|
sl@0
|
799 |
{
|
sl@0
|
800 |
final HelpFormatter formatter = new HelpFormatter();
|
sl@0
|
801 |
formatter.printHelp("UartEchoServer", options);
|
sl@0
|
802 |
}
|
sl@0
|
803 |
else
|
sl@0
|
804 |
{
|
sl@0
|
805 |
final UartEchoServer echoServer=new UartEchoServer();
|
sl@0
|
806 |
echoServer.Construct(commandLine);
|
sl@0
|
807 |
}
|
sl@0
|
808 |
}
|
sl@0
|
809 |
catch ( Exception e )
|
sl@0
|
810 |
{
|
sl@0
|
811 |
e.printStackTrace();
|
sl@0
|
812 |
}
|
sl@0
|
813 |
}
|
sl@0
|
814 |
}
|