View Javadoc

1   /*
2    * Trip Tracker, a real-time position tracking system for the Internet.
3    * Copyright (C) 2006  Team Trip Tracker
4    *
5    * This program is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License as published by the
7    * Free Software Foundation; either version 2 of the License, or (at your
8    * option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful, but
11   * WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13   * General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License along
16   * with this program; if not, write to the Free Software Foundation, Inc.,
17   * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18   */
19  
20  package triptracker.client.gps.core;
21  
22  import static triptracker.core.Protocol.*;
23  
24  import java.io.BufferedReader;
25  import java.io.File;
26  import java.io.FileNotFoundException;
27  import java.io.FileOutputStream;
28  import java.io.FileReader;
29  import java.io.FileWriter;
30  import java.io.IOException;
31  import java.io.OutputStreamWriter;
32  import java.io.PrintWriter;
33  import java.util.List;
34  import java.util.TooManyListenersException;
35  
36  import gnu.io.PortInUseException;
37  import gnu.io.UnsupportedCommOperationException;
38  
39  import triptracker.client.net.GPSSocket;
40  import triptracker.client.net.GPSSocketListener;
41  import triptracker.core.Coordinate;
42  import triptracker.core.Route;
43  
44  /***
45   * GPS Client sends coordinates to a server. This is the model for the GPS
46   * client in the MVC separation.
47   */
48  public class GPSClientModel {
49  	private final String TMP_FILE = "tmpBuffer.tmp";
50  	private File outputFile = new File(TMP_FILE);
51  	private OutputStreamWriter outW = null;
52  	private final GPSConnection gps = new GPSConnection();
53  	private final GPSSocket socket = new GPSSocket();
54  
55  	private Coordinate gpsCoord;
56  	private Coordinate oldCoord;
57  
58  	private static String comPort;
59  
60  	private int interval = 2;
61  
62  	private boolean transferToServer = false;
63  	private boolean recieveFromGPS = false;
64  	private boolean autoTransfer = false;
65  	private boolean enableCompression = false;
66  	private Route activeRoute = new Route(-1, -1, null);
67  
68  	/***
69  	 * Stores temporary coordinates while without internet connection.
70  	 */
71  	public void storeTmpCoords(Coordinate coord) throws IOException {
72  		String message = makeMsg(coord.getY(), coord.getX(), coord
73  				.getDateString());
74  
75  		// Creates the buffer file if it doesent exist
76  		if (!outputFile.exists())
77  			outputFile.createNewFile();
78  
79  		// Stores the message to bufferfile
80  		PrintWriter tmpOut = new PrintWriter(new FileWriter(outputFile, true));
81  		tmpOut.print(message);
82  		tmpOut.flush();
83  	}
84  
85  	/***
86  	 * Transfers coordinates stored in a temporary file while network was
87  	 * unreachable.
88  	 */
89  	public boolean transferTmpCoords() throws FileNotFoundException,
90  			IllegalStateException, IOException {
91  		FileReader inputFile;
92  		StringBuilder coordBuffer = new StringBuilder();
93  
94  		inputFile = new FileReader(outputFile);
95  		BufferedReader inFile = new BufferedReader(inputFile);
96  
97  		// Reads from file to StringBuilder
98  		String x;
99  		while ((x = inFile.readLine()) != null) {
100 			System.out.println("Read: " + x);
101 			coordBuffer.append(x + DELIMITER);
102 		}
103 
104 		// Closes the file
105 		inFile.close();
106 
107 		// Sends the buffer to server
108 		if (socket.sendTmpCoords(coordBuffer)) {
109 			inFile.close();
110 			if (outputFile.delete())
111 				System.out.println("Deleted " + outputFile.toString()
112 						+ " file ..");
113 			else {
114 				System.out.println("Could not delete " + outputFile.toString());
115 				throw new IllegalStateException();
116 			}
117 			return true;
118 		} else
119 			return false;
120 	}
121 
122 	/***
123 	 * Opens the given file
124 	 * 
125 	 * @param file the given file
126 	 * @throws FileNotFoundException 
127 	 */
128 	public void openFile(String file) throws FileNotFoundException {
129 		outW = new OutputStreamWriter(new FileOutputStream("nmeaout.txt"));
130 	}
131 
132 	/***
133 	 * Write data from GPS-reciever to a file.
134 	 * 
135 	 * @param data GPS data to write to file
136 	 * @throws IOException if write fails
137 	 */
138 	public void writeGPSData(String data) throws IOException {
139 		// Write ALL data from device to file
140 		outW.write(data + "\n");
141 	}
142 
143 	/***
144 	 * Logs on to the server.
145 	 * 
146 	 * @param user username
147 	 * @param pass password
148 	 */
149 	public void logon(String user, String pass) throws IOException {
150 		socket.logon(user, pass);
151 	}
152 
153 	/***
154 	 * Connects to the GPS on the set serial port.
155 	 */
156 	public void openGPSPort() throws PortInUseException,
157 			TooManyListenersException, UnsupportedCommOperationException,
158 			IOException {
159 		gps.open(getPort());
160 		System.out.println("opening port");
161 	}
162 
163 	/***
164 	 * Register a listener for GPS device events.
165 	 * 
166 	 * @param listener event receiver to register
167 	 */
168 	public void addGPSListener(GPSListener listener) {
169 		gps.addListener(listener);
170 	}
171 
172 	/***
173 	 * Remove listener from listener queue.
174 	 * 
175 	 * @param listener event receiver to remove
176 	 */
177 	public void removeGPSListener(GPSListener listener) {
178 		gps.removeListener(listener);
179 	}
180 
181 	/***
182 	 * Register a listener for server events.
183 	 * 
184 	 * @param listener event receiver to register
185 	 */
186 	public void addSocketListener(GPSSocketListener listener) {
187 		socket.addListener(listener);
188 	}
189 
190 	/***
191 	 * Remove listener from listener queue.
192 	 * @param listener event receiver to remove
193 	 */
194 	public void removeSocketListener(GPSSocketListener listener) {
195 		socket.removeListener(listener);
196 	}
197 
198 	/***
199 	 * Disconnects from socket.
200 	 * @throws IOException 
201 	 */
202 	public void disconnectFromSocket() throws IOException {
203 		socket.disconnect();
204 	}
205 
206 	/***
207 	 * Gets a list of the available COM ports.
208 	 * 
209 	 * @return a list of COM ports
210 	 */
211 	public List<String> getComPorts() {
212 		return gps.getPorts();
213 	}
214 
215 	/***
216 	 * Get the COM-port
217 	 * @return active COM-port
218 	 */
219 	public String getPort() {
220 		return comPort;
221 	}
222 
223 	/***
224 	 * Sets a port to the active COM-port
225 	 * @param port the port you want to set as active
226 	 */
227 	public void setPort(String port) {
228 		System.out.println("port: " + port);
229 		comPort = port;
230 	}
231 
232 	/***
233 	 * Set if you want compression or not.
234 	 * 
235 	 * @param compression true for compression, otherwise false
236 	 */
237 	public void setCompression(boolean compression) {
238 		enableCompression = compression;
239 	}
240 
241 	/***
242 	 * Checks if the client should use compression to send the
243 	 * buffered coordinates to the server
244 	 * 
245 	 * @return true if compression
246 	 */
247 	public boolean getCompression() {
248 		return enableCompression;
249 	}
250 
251 	/***
252 	 * Set interval for recieving coordinates from the GPS-unit
253 	 * @param inte the interval in s.
254 	 */
255 	public void setInterval(int inte) {
256 		interval = inte;
257 	}
258 
259 	/***
260 	 * Gets the interval for recieving coordinates from the GPS-unit
261 	 * @return the interval in s.
262 	 */
263 	public int getInterval() {
264 		return interval;
265 	}
266 
267 	/***
268 	 * Checks if connected to socket.
269 	 * 
270 	 * @return true if connected
271 	 */
272 	public boolean isConnected() {
273 		return socket.isConnected();
274 	}
275 
276 	/***
277 	 * Checks if logged in to server
278 	 * @return true if logged in
279 	 */
280 	public boolean isLoggedIn() {
281 		return socket.isLoggedIn();
282 	}
283 
284 	/***
285 	 * Gets the date/time the coordinate was recieved.
286 	 * 
287 	 * @return date and time of current coordinate
288 	 */
289 	public String getCoordDate() {
290 		if (gpsCoord == null)
291 			syncCoords();
292 		return gpsCoord.getDateString();
293 	}
294 
295 	public String getStringLat() {
296 		return gpsCoord.getStringLat();
297 	}
298 
299 	public String getStringLon() {
300 		return gpsCoord.getStringLon();
301 	}
302 
303 	/***
304 	 * Gets the current coordinate from the GPS.
305 	 *
306 	 */
307 	public void syncCoords() {
308 		oldCoord = gpsCoord;
309 		gpsCoord = gps.getCurrentCoordinate();
310 	}
311 
312 	/***
313 	 * Gets the current coordinate
314 	 * 
315 	 * @return the current coordinate
316 	 */
317 	public Coordinate getCurrentCoord() {
318 		if (oldCoord != null)
319 			return gpsCoord;
320 		else
321 			return null;
322 	}
323 
324 	/***
325 	 * Gets the old coordinate
326 	 * 
327 	 * @return the old coordinate
328 	 */
329 	public Coordinate getOldCoord() {
330 		if (oldCoord != null)
331 			return oldCoord;
332 		else
333 			return null;
334 	}
335 
336 	/***
337 	 * Saves the coordinates, based on connected to server or not.
338 	 * @throws IOException 
339 	 */
340 	public void saveCoord() throws IOException {
341 		if (oldCoord != null && gpsCoord.getDate().equals(oldCoord.getDate())) {
342 			System.out.println("Dropping duplicate coord: " + gpsCoord);
343 			return;
344 		} else {
345 			//oldCoord = gpsCoord;
346 		}
347 
348 		if (socket.isLoggedIn() && transferToServer
349 				&& activeRoute.getRouteId() != -1) {
350 			// Send to server
351 			socket.sendCoord(gpsCoord);
352 			System.out.println("@@ Transferring");
353 		} else {
354 			// Buffer to file
355 			storeTmpCoords(gpsCoord);
356 			System.out.println("** Buffering ..");
357 		}
358 	}
359 
360 	/***
361 	 * Changes the state of transferToServer, 
362 	 * this decides if the coordinates should 
363 	 * be buffered locally, og sent to server
364 	 */
365 	public void changeTransferState() {
366 		transferToServer = !transferToServer;
367 		System.out.println("Transfer To Server is set to " + transferToServer);
368 	}
369 
370 	/***
371 	 * Gets the state of transferToServer
372 	 * 
373 	 * @return true if transfer to server, else false
374 	 */
375 	public boolean getTransferState() {
376 		return transferToServer;
377 	}
378 
379 	/***
380 	 * Creates a new route on server with the 
381 	 * given description.
382 	 * 
383 	 * @param routeDesc the description of the route
384 	 */
385 	public void createRoute(String routeDesc) {
386 		socket.makeRoute(routeDesc);
387 	}
388 
389 	/***
390 	 * Gets the routes for a given user
391 	 * 
392 	 * @param user get this users routes
393 	 */
394 	public void getRoutes(String user) {
395 		socket.getRoutes(user);
396 	}
397 
398 	/***
399 	 * Gets the current username
400 	 * 
401 	 * @return current username
402 	 */
403 	public String getUsername() {
404 		return socket.getUsername();
405 	}
406 
407 	/***
408 	 * Sets the given route as the active route on server
409 	 * 
410 	 * @param route the active route
411 	 */
412 	public void setRouteOnServer(Route route) {
413 		socket.setRoute(route);
414 	}
415 
416 	/***
417 	 * Returns a route's id
418 	 * 
419 	 * @param route the route to get id from
420 	 * @return the route's id
421 	 */
422 	public int getRouteId(Route route) {
423 		return route.getRouteId();
424 	}
425 
426 	/***
427 	 * Returns a route's desciption
428 	 * 
429 	 * @param route the route to get description from
430 	 * @return the route's description
431 	 */
432 	public String getRouteDesc(Route route) {
433 		Route r = route;
434 		return r.getDescription();
435 	}
436 
437 	/***
438 	 * Sets current route as active route locally.
439 	 * Note that active route has to be set on the 
440 	 * server too, except if a new route is created.
441 	 * 
442 	 * @param route route to set active
443 	 */
444 	public void setActiveRoute(Route route) {
445 		System.out.println(route);
446 		activeRoute = route;
447 		System.out.println("Active route is now: "
448 				+ activeRoute.getDescription());
449 	}
450 
451 	/***
452 	 * Returns the active route
453 	 * 
454 	 * @return the active route
455 	 */
456 	public Route getActiveRoute() {
457 		return activeRoute;
458 	}
459 
460 	/***
461 	 * Checks if the GPS-unit has a fixed position from 
462 	 * the satellites.
463 	 * 
464 	 * @return true if fixed position
465 	 */
466 	public boolean hasSignal() {
467 		return gps.hasSignal();
468 	}
469 
470 	/***
471 	 * Checks wheter the buffer file exists or not. 
472 	 * 
473 	 * @return true if the file exists.
474 	 */
475 	public boolean bufferFileExists() {
476 		return outputFile.exists();
477 	}
478 
479 	/***
480 	 * Changes the state of recieving from GPS-unit.
481 	 * State is set to opposit of the current.
482 	 * (i.e true if it was false)
483 	 */
484 	public void changeGPSState() {
485 		recieveFromGPS = !recieveFromGPS;
486 		System.out.println("Transfer To Server is set to " + transferToServer);
487 	}
488 
489 	/***
490 	 * Gets the state of recieving from GPS-unit
491 	 * 
492 	 * @return true if recieve
493 	 */
494 	public boolean getGPSState() {
495 		return recieveFromGPS;
496 	}
497 
498 	/***
499 	 * Closes the GPS port
500 	 */
501 	public void closeGPSPort() {
502 		gps.closePort();
503 	}
504 
505 	/***
506 	 * Gets the current coordinates
507 	 * 
508 	 * @return current coordinates recieved from GPS
509 	 */
510 	public boolean currCoordSet() {
511 		return gps.currCoordSet();
512 	}
513 
514 	/***
515 	 * Starts recieving from the GPS-unit
516 	 */
517 	public void startRecieveFromGPS() {
518 		gps.startRecieve();
519 		System.out.println("* Starting recieve from GPS");
520 	}
521 
522 	/***
523 	 * Stops recieving from the GPS-unit
524 	 * @throws IOException 
525 	 * @throws UnsupportedCommOperationException 
526 	 * @throws TooManyListenersException 
527 	 * @throws PortInUseException 
528 	 * @throws IllegalArgumentException 
529 	 */
530 	public void stopRecieveFromGPS() throws IllegalArgumentException, PortInUseException, TooManyListenersException, UnsupportedCommOperationException, IOException {
531 		// XXX tried to add close/open port here
532 		// to fix problem with disconnecting the port if 
533 		// the plug is pulled out while the app runs 
534 		// (Would not normally occour if you have an "normal"
535 		// serial port (not an usb-> serial adapter as we use 
536 		// for testing).
537 		gps.closePort();
538 		gps.open(getPort());
539 		gps.stopRecieve();
540 	}
541 
542 	/***
543 	 * Checks if connected to the GPS-unit
544 	 * 
545 	 * @return true if connected
546 	 */
547 	public boolean isConnectedToGPS() {
548 		return gps.isConnected();
549 	}
550 
551 	/***
552 	 * Checks if autotransfer is set
553 	 * 
554 	 * @return true if autotransfer
555 	 */
556 	public boolean getAutoTransferState() {
557 		return autoTransfer;
558 	}
559 
560 	/***
561 	 * Sets the autotransfer variable
562 	 * 
563 	 * @param enable true if autotransfer, else false
564 	 */
565 	public void autoTransfer(boolean enable) {
566 		autoTransfer = enable;
567 	}
568 
569 	/***
570 	 * Checks if active route is set locally.
571 	 * 
572 	 * @return true if active route exist
573 	 */
574 	public boolean hasActiveRoute() {
575 		return (activeRoute.getRouteId() != -1);
576 	}
577 
578 	public void setHost(String host) {
579 		socket.setHost(host);
580 	}
581 
582 	public void setPort(int port) {
583 		socket.setPort(port);
584 	}
585 }