svn-gvsig-desktop / branches / v10 / extensions / extGPS / test / SNComHandler.java @ 44530
History | View | Annotate | Download (16.1 KB)
1 |
// Generated by P Bennett: Monday, 4 October 1999 at: 05:24:32 pm
|
---|---|
2 |
// Com Port Handler.
|
3 |
// I have released this code as a guide only.
|
4 |
// It will not run without the supporting classes.
|
5 |
// It was origanally written to communicate with a development prototype
|
6 |
// and runs under Slackware Linux Version 4 with Blackdown jdk1.1.7_v3
|
7 |
// Green Threads and rxtx version 3.4 with Java Comms API V2.0
|
8 |
// This thread is controlled by a thread that implements a queue
|
9 |
// and methods for controlling the queue and allocating the resources (modems)
|
10 |
// The modem used for development was a Siemens M20 Cellular modem.
|
11 |
// The remote equipment dumped its data upon connection and then hangs up.
|
12 |
// The protocol has changed somewhat now. (A Subset of HDLC)
|
13 |
// I have added extra comments for your benefit.
|
14 |
// It is free to use.
|
15 |
// Just a quick note. I have no formal training therefor the programming techniques
|
16 |
// may not be the best ones to use. However the technique I use has been developed
|
17 |
// through experience and it seems to work for me.
|
18 |
|
19 |
import gnu.io.CommPortIdentifier; |
20 |
import gnu.io.NoSuchPortException; |
21 |
import gnu.io.PortInUseException; |
22 |
import gnu.io.SerialPort; |
23 |
import gnu.io.SerialPortEvent; |
24 |
import gnu.io.SerialPortEventListener; |
25 |
import gnu.io.UnsupportedCommOperationException; |
26 |
|
27 |
import java.io.IOException; |
28 |
import java.io.InputStream; |
29 |
import java.io.OutputStream; |
30 |
import java.util.TooManyListenersException; |
31 |
|
32 |
/** Class To Talk To A GSM Cellular Modem, Dial an SNU and retrieve the data.
|
33 |
* Uses Java Comm API 2.0
|
34 |
* @author P Bennett
|
35 |
* @version 1.0
|
36 |
* @see SNServerIO
|
37 |
* @see SNComThread
|
38 |
*/
|
39 |
|
40 |
public class SNComHandler extends java.lang.Thread implements |
41 |
SerialPortEventListener { |
42 |
|
43 |
private static SNComThread comThread; // A reference back to the parent. |
44 |
private static SNLogger comLog; // Log handler |
45 |
private static SNConfig serverConfig; // Server Configuration object |
46 |
private String comName = "Nil"; // The com port name to use as in /dev/ttyS0 |
47 |
private boolean process = false; // Process a request |
48 |
private String requestId = "Nil"; // Request ID |
49 |
private String num = "Nil"; // The phone number to dial |
50 |
private boolean running = true; // Make it go around |
51 |
private CommPortIdentifier portId; // Port Identifier |
52 |
private SerialPort serialPort = null; // Serial Port object |
53 |
private OutputStream outputStream = null; // The streams |
54 |
private InputStream inputStream = null; |
55 |
private String errMessage = ""; // An error message |
56 |
private boolean fatalErr = false; // Big problems call the emergency team :-( |
57 |
private boolean waitForInput = true; // Wait for incoming data |
58 |
|
59 |
/** Construct a new SNComHandler Object..
|
60 |
* For initialising the array of Com Handlers.
|
61 |
* @see SNComThread
|
62 |
*/
|
63 |
public SNComHandler() {
|
64 |
} |
65 |
|
66 |
/** Construct a new SNComHandler Object.
|
67 |
* Created with the following parameters.
|
68 |
* @param cThread The parent thread.
|
69 |
* @param sLog The Logging object.
|
70 |
* @param sConfig The server config object.
|
71 |
* @param cName The Com Port name eg. /dev/ttyS0
|
72 |
* @see SNLogger
|
73 |
* @see SNConfig
|
74 |
*/
|
75 |
public SNComHandler(SNComThread cThread, SNLogger sLog, SNConfig
|
76 |
sConfig, String cName) throws NoSuchPortException { |
77 |
this.comThread = cThread; // Parent thread |
78 |
this.comLog = sLog; // Log object |
79 |
this.serverConfig = sConfig; // Config object |
80 |
this.comName = cName; // The com port name |
81 |
portId = |
82 |
(CommPortIdentifier)CommPortIdentifier.getPortIdentifier(this.comName);
|
83 |
// Set up the ID
|
84 |
this.comLog.log("Com Handler Initialised For " + comName); // Log start |
85 |
} |
86 |
|
87 |
/** Thread run method
|
88 |
* Call unit num, when requested and
|
89 |
* pass the recieved data back to
|
90 |
* the parent thread que.
|
91 |
*/
|
92 |
public void run() { |
93 |
// comLog.debugInfo("Com Handler Run Method Started For " + comName);
|
94 |
int resetCount = 0; // Reset attempts |
95 |
int resetCount2 = 0; // And again. There must be a better way |
96 |
int resetCount3 = 0; // And again. of doing this!!!! They are all the same. |
97 |
while (running) { // While we are doin it. |
98 |
if (fatalErr) { // Big problems |
99 |
comThread.queRequest(requestId, errMessage, "Error"); // Tell the parent |
100 |
comLog.log(errMessage + " " + comName + " " + num); // Tell everyone |
101 |
num = "Nil"; // Reset some variables |
102 |
resetCount = 0; // The error resets process |
103 |
resetCount2 = 0; // Round we go again. |
104 |
resetCount3 = 0;
|
105 |
fatalErr = false;
|
106 |
} |
107 |
if (!process) { // Nothing to do |
108 |
try {
|
109 |
Thread.sleep(500); // Have a sleep |
110 |
} catch (InterruptedException e) {} |
111 |
continue; // Round we go again. |
112 |
} |
113 |
comLog.debugInfo("**********We Are Processing***********");
|
114 |
if (num.equals("Nil")) { // Can't dial Nil! |
115 |
try { // Just a catch never tested |
116 |
Thread.sleep(500); // Have a sleep |
117 |
} catch (InterruptedException e) {} // Prolly does not work as intended |
118 |
continue; // Round we go again. |
119 |
} |
120 |
comLog.debugInfo("**********Trying To Open Port***********");
|
121 |
if (!openPort()) { // Try to open port |
122 |
closePort(); // Try to close it then
|
123 |
try {
|
124 |
Thread.sleep(500); // Have a sleep |
125 |
} catch (InterruptedException e) {} |
126 |
resetCount ++; // Up the counter
|
127 |
//***************** 3 goes in serverconfig ************************8
|
128 |
if (resetCount > 3) { // Check the counter |
129 |
process = false; // We got problems |
130 |
errMessage = "Error! Could Not Open Port";
|
131 |
fatalErr = true; // We got big problems |
132 |
} |
133 |
continue; // Round we go to sort it out |
134 |
} |
135 |
comLog.debugInfo("**********Trying To Reset Modem***********");
|
136 |
if (!reset()) { // We got the port now reset the modem |
137 |
try {
|
138 |
Thread.sleep(500); // Have a sleep |
139 |
} catch (InterruptedException e) {} |
140 |
resetCount2 ++; // Up the counter
|
141 |
//***************** 3 goes in serverconfig ************************8
|
142 |
if (resetCount2 > 3) { // Check the counter |
143 |
process = false; // We got problems |
144 |
errMessage = "Error! Could Not Reset Modem";
|
145 |
fatalErr = true; // We got big problems |
146 |
} |
147 |
continue; // Round we go to sort it out |
148 |
} |
149 |
comLog.debugInfo("**********Trying To Dial***********");
|
150 |
if (!dial()) { // The modem reset OK now dial |
151 |
comLog.debugInfo("**********" + errMessage + "***********"); |
152 |
try {
|
153 |
Thread.sleep(500); // Have a sleep |
154 |
} catch (InterruptedException e) {} |
155 |
resetCount3 ++; // Up the count
|
156 |
//***************** 3 goes in serverconfig ************************8
|
157 |
if (resetCount3 > 2) { // Check the count |
158 |
process = false; // We got problems |
159 |
errMessage = "Error! Could Not Dial";
|
160 |
fatalErr = true; // We got big problems |
161 |
} |
162 |
continue; // Round we go to sort it out |
163 |
} |
164 |
int numBytes = 0; // Number of bytes read from input |
165 |
byte[] readBuffer = new byte[20]; // Tmp Read buffer of 20 bytes |
166 |
String sReadBuff = ""; // Read Buffer |
167 |
boolean dLoop = true; // Loop |
168 |
while (dLoop) { // Wait for incoming data |
169 |
try {
|
170 |
while (inputStream.available() > 0) { // While there is something to read |
171 |
numBytes = inputStream.read(readBuffer); // Get the bytes
|
172 |
String tmpR = new String(readBuffer); // Set up a string |
173 |
sReadBuff += tmpR.substring(0, numBytes); // Add to read buffer |
174 |
} |
175 |
} catch (IOException e) { |
176 |
dLoop = false; // Problems |
177 |
process = false; // This has never occured |
178 |
} |
179 |
if (sReadBuff.indexOf("NO CARRIER") != -1) { // Test incoming data |
180 |
errMessage = ""; // Unit hangs up once it |
181 |
dLoop = false; // dumps its data |
182 |
} else if (sReadBuff.indexOf("ERROR") != -1) { // Check for error |
183 |
errMessage = "Error! Recieved Data Not Clean " + num + " " + comName; |
184 |
dLoop = false;
|
185 |
} else if (sReadBuff.length() > 5000) { // Check for receive runnaway |
186 |
errMessage = "";
|
187 |
dLoop = false;
|
188 |
} |
189 |
} |
190 |
if (errMessage.equals("")) { // No error occured |
191 |
comThread.queRequest(requestId, sReadBuff, "Ready"); // Tell the parent the result |
192 |
comLog.log("Data Recieved " + " " + requestId + " " + num); // Log it |
193 |
System.out.println("*********" + sReadBuff + "*********"); // Raw Debug code |
194 |
} else {
|
195 |
if (!fatalErr) { // Error |
196 |
comThread.queRequest(requestId, errMessage, "Error"); // Tell parent |
197 |
comLog.log(errMessage + " " + comName + " " + num); // Log |
198 |
System.out.println("*********" + errMessage + "*********"); // Raw debug |
199 |
} |
200 |
} |
201 |
closePort(); // Close the port
|
202 |
resetCount = 0; // Reset the variables ready for next request |
203 |
resetCount2 = 0;
|
204 |
resetCount3 = 0;
|
205 |
num = "Nil";
|
206 |
process = false;
|
207 |
} |
208 |
} |
209 |
|
210 |
/** Open Com Port
|
211 |
* @return true if succesfull
|
212 |
*/
|
213 |
private boolean openPort() { |
214 |
if (serialPort == null) { // Set up serial port object if need be |
215 |
comLog.debugInfo("**********Open Port Routine***********");
|
216 |
try {
|
217 |
serialPort = (SerialPort) portId.open("SimpleReadApp", 2000); // Open serial port |
218 |
comLog.debugInfo("**********Port Open***********");
|
219 |
} catch (PortInUseException e) {
|
220 |
return false; // Hmm its in use |
221 |
} |
222 |
if (inputStream == null) { // Set up the input stream if need be |
223 |
try {
|
224 |
inputStream = serialPort.getInputStream(); // Get the stream
|
225 |
} catch (IOException e) { |
226 |
return false; |
227 |
} |
228 |
} |
229 |
if (outputStream == null) { // Set up the output stream if need be |
230 |
try {
|
231 |
outputStream = serialPort.getOutputStream(); // Get the stream
|
232 |
} catch (IOException e) { |
233 |
return false; |
234 |
} |
235 |
} |
236 |
try {
|
237 |
serialPort.addEventListener(this); // Add the event listener |
238 |
} catch (TooManyListenersException e) { |
239 |
return false; |
240 |
} |
241 |
serialPort.notifyOnDataAvailable(true); // Set the port to notify on incoming data |
242 |
//********* Maybe this goes in serverconfig maybe on a per port basis
|
243 |
// Set the port parameters
|
244 |
try {
|
245 |
serialPort.setSerialPortParams(19200, SerialPort.DATABITS_8,
|
246 |
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); |
247 |
} catch (UnsupportedCommOperationException e) {
|
248 |
return false; |
249 |
} |
250 |
} |
251 |
return true; // Everything went ok |
252 |
} |
253 |
|
254 |
/** Close Com Port. */
|
255 |
|
256 |
private void closePort() { |
257 |
if (serialPort != null) { // Check that the serial port is not null |
258 |
serialPort.notifyOnDataAvailable(false); // Close down notification |
259 |
serialPort.removeEventListener(); // Remove the event listener
|
260 |
if (inputStream != null) { // Check for null |
261 |
try {
|
262 |
inputStream.close(); // Close it
|
263 |
inputStream = null; // Clean up |
264 |
} |
265 |
catch (IOException e) {} |
266 |
} |
267 |
if (outputStream != null) { // Check for null |
268 |
try {
|
269 |
outputStream.close(); // Close it
|
270 |
outputStream = null; // Clean up |
271 |
} |
272 |
catch (IOException e) {} |
273 |
} |
274 |
serialPort.close(); // Close the serial port
|
275 |
serialPort = null; // Clean up |
276 |
} |
277 |
} |
278 |
|
279 |
/** Reset The Modem
|
280 |
* @return true if succesfull.
|
281 |
*/
|
282 |
private boolean reset() { |
283 |
try {
|
284 |
outputStream.write(new String("atz").getBytes()); // Send the modem atz |
285 |
outputStream.write((byte)0x0D); // And the other stuff |
286 |
outputStream.write((byte)0x0A); // <CR> <LF> |
287 |
} catch (IOException e) { |
288 |
return false; |
289 |
} |
290 |
int waitingCount = 0; // Heres another counter |
291 |
waitForInput = true; // We are waiting |
292 |
while (waitForInput) { // Yes we are |
293 |
try {
|
294 |
Thread.sleep(100); // We have a little rest |
295 |
} catch (InterruptedException e) {} |
296 |
waitingCount ++; // We count
|
297 |
//***************** 20 goes in serverconfig ************************
|
298 |
if (waitingCount > 20) { // We have counted to much |
299 |
return false; // Could not reset |
300 |
} |
301 |
} |
302 |
int numBytes = 0; // Set up number of bytes read |
303 |
byte[] readBuffer = new byte[20]; // And a buffer |
304 |
String sReadBuff = ""; // And another buffer |
305 |
try {
|
306 |
while (inputStream.available() > 0) { |
307 |
numBytes = inputStream.read(readBuffer); // Read from the port
|
308 |
String tmpR = new String(readBuffer); |
309 |
sReadBuff += tmpR.substring(0, numBytes);
|
310 |
} |
311 |
} catch (IOException e) { |
312 |
return false; |
313 |
} |
314 |
//********************Maybe for serverconfig
|
315 |
if (sReadBuff.indexOf("OK") != -1) { // Test for OK response from modem |
316 |
try {
|
317 |
Thread.sleep(1000); // We have another sleep to allow things |
318 |
} catch (InterruptedException e) {} // to settle |
319 |
return true; |
320 |
} |
321 |
return false; // We did not reset OK |
322 |
} |
323 |
|
324 |
/** Dial number requested
|
325 |
* @return true if connected
|
326 |
*/
|
327 |
private boolean dial() { |
328 |
try {
|
329 |
comLog.debugInfo("**********" + num + "***********"); |
330 |
outputStream.write(new String("atd").getBytes()); // Send atd |
331 |
outputStream.write(num.getBytes()); // And the number
|
332 |
outputStream.write((byte)0x0D); // And the other stuff |
333 |
outputStream.write((byte)0x0A); |
334 |
} catch (IOException e) { |
335 |
errMessage = "Error! Could Not Write To Port ";
|
336 |
comLog.debugInfo("**********Error Writing***********");
|
337 |
return false; // Bad could not write |
338 |
} |
339 |
int waitingCount = 0; // We are counting again |
340 |
waitForInput = true; // Waiting |
341 |
while (waitForInput) {
|
342 |
try {
|
343 |
Thread.sleep(100); // Have a sleep |
344 |
} catch (InterruptedException e) {} |
345 |
waitingCount ++; // Counting
|
346 |
//**************** For serverconfig ************************
|
347 |
if (waitingCount > 200) { // Counted to much |
348 |
errMessage = "Error! Timed Out Waiting For Response";
|
349 |
return false; // Timed out |
350 |
} |
351 |
} |
352 |
int numBytes = 0; // Set up for reading |
353 |
byte[] readBuffer = new byte[20]; // Youve seen it before |
354 |
String sReadBuff = ""; // The comments are getting thinner |
355 |
boolean dLoop = true; // No need to repeat |
356 |
while (dLoop) {
|
357 |
try {
|
358 |
while (inputStream.available() > 0) { |
359 |
numBytes = inputStream.read(readBuffer); |
360 |
String tmpR = new String(readBuffer); |
361 |
sReadBuff += tmpR.substring(0, numBytes); // We read it |
362 |
} |
363 |
if (sReadBuff.indexOf("NO CARRIER") != -1) { // Out of area |
364 |
errMessage = "Error! No Carrier";
|
365 |
return false; |
366 |
} else if (sReadBuff.indexOf("BUSY") != -1) { // Busy |
367 |
errMessage = "Error! Busy"; // Who is ringing our units |
368 |
return false; // Maybe it is dialing out |
369 |
} else if (sReadBuff.indexOf("NO DIAL TONE") != -1) { // Bad no signal |
370 |
errMessage = "Error! No Dial Tone"; // Were has the ariel gone |
371 |
return false; |
372 |
} else if (sReadBuff.indexOf("OK") != -1) { // Hmm voice call no good |
373 |
errMessage = "Error! Voice Call";
|
374 |
return false; |
375 |
} else if (sReadBuff.indexOf("CONNECT") != -1) { // Ah this is what we want |
376 |
return true; // Return true |
377 |
} |
378 |
} catch (IOException e) { |
379 |
errMessage = "Error! Could Not Read From Com Port";
|
380 |
return false; // Bad but never happened yet |
381 |
} |
382 |
} |
383 |
errMessage = "Error! Invalid Data " + sReadBuff;
|
384 |
return false; // Something has gone wrong |
385 |
} |
386 |
|
387 |
/** Serial Event Routine
|
388 |
* Set waitForInput to false when data ready
|
389 |
*/
|
390 |
public void serialEvent(SerialPortEvent event) { |
391 |
switch(event.getEventType()) {
|
392 |
case SerialPortEvent.BI:
|
393 |
case SerialPortEvent.OE:
|
394 |
case SerialPortEvent.FE:
|
395 |
case SerialPortEvent.PE:
|
396 |
case SerialPortEvent.CD:
|
397 |
case SerialPortEvent.CTS:
|
398 |
case SerialPortEvent.DSR:
|
399 |
case SerialPortEvent.RI:
|
400 |
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
|
401 |
break;
|
402 |
case SerialPortEvent.DATA_AVAILABLE:
|
403 |
waitForInput = false; // We got incoming |
404 |
break; // Thats it for serial events |
405 |
} |
406 |
} |
407 |
|
408 |
/** Process Request To Call SNU.
|
409 |
* Request that a call be made and the data
|
410 |
* returned to the controlling thread.
|
411 |
* @see SNComThread
|
412 |
*/
|
413 |
public void processRequest(String req, String num) { |
414 |
requestId = req; // Set ID
|
415 |
this.num = num; // Set the phone number |
416 |
process = true; // Make it go |
417 |
} |
418 |
|
419 |
/** Is Processing Call
|
420 |
* @return true if thread is busy
|
421 |
* @see SNComThread
|
422 |
*/
|
423 |
public boolean isProcessing() { |
424 |
return process; // Are you busy |
425 |
} |
426 |
|
427 |
/** Is Processing This Q Id.
|
428 |
* @param qID The ID to test for
|
429 |
* @return true if the thread is processing qID
|
430 |
* @see SNComThread
|
431 |
*/
|
432 |
public boolean isProcessing(String qID) { |
433 |
return requestId.equals(qID); // Are you busy doing this job |
434 |
} |
435 |
} |
436 |
/* the following was added so the code will compile. Its not proper */
|
437 |
class SNLogger |
438 |
{ |
439 |
public void debugInfo(java.lang.String it) |
440 |
{ |
441 |
} |
442 |
public void log(java.lang.String it) |
443 |
{ |
444 |
} |
445 |
} |
446 |
class SNComThread |
447 |
{ |
448 |
public void queRequest(java.lang.String a, java.lang.String b, java.lang.String c) |
449 |
{ |
450 |
} |
451 |
} |
452 |
class SNConfig |
453 |
{ |
454 |
} |