svn-gvsig-desktop / tags / v1_9_Build_1248 / extensions / extGPS / test / SNComHandler.java @ 43233
History | View | Annotate | Download (16.1 KB)
1 | 4720 | jaume | // 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 | 4747 | jaume | 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 | 4720 | jaume | |
27 | 4747 | jaume | import java.io.IOException; |
28 | import java.io.InputStream; |
||
29 | import java.io.OutputStream; |
||
30 | import java.util.TooManyListenersException; |
||
31 | |||
32 | 4720 | jaume | /** 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 | } |