2222import java .io .OutputStreamWriter ;
2323import java .net .Socket ;
2424import java .net .UnknownHostException ;
25+ import java .util .ArrayList ;
26+ import java .util .List ;
2527
28+ import org .json .JSONException ;
29+ import org .json .JSONObject ;
30+
31+ import de .taimos .gpsd4java .api .IObjectListener ;
32+ import de .taimos .gpsd4java .types .DeviceObject ;
33+ import de .taimos .gpsd4java .types .DevicesObject ;
2634import de .taimos .gpsd4java .types .IGPSObject ;
2735import de .taimos .gpsd4java .types .ParseException ;
36+ import de .taimos .gpsd4java .types .PollObject ;
37+ import de .taimos .gpsd4java .types .SKYObject ;
38+ import de .taimos .gpsd4java .types .TPVObject ;
39+ import de .taimos .gpsd4java .types .VersionObject ;
40+ import de .taimos .gpsd4java .types .WatchObject ;
2841
2942/**
3043 * GPSd client endpoint
@@ -40,6 +53,12 @@ public class GPSdEndpoint {
4053
4154 private Thread listenThread ;
4255
56+ private List <IObjectListener > listeners = new ArrayList <IObjectListener >();
57+
58+ private IGPSObject asnycResult = null ;
59+ private Object asyncMutex = new Object ();
60+ private Object asyncWaitMutex = new Object ();
61+
4362
4463 /**
4564 * @param server the server name or IP
@@ -63,42 +82,159 @@ public GPSdEndpoint(String server, int port) {
6382 public void start () {
6483 this .listenThread = new SocketThread (this .in , this );
6584 this .listenThread .start ();
85+
86+ try {
87+ Thread .sleep (500 );
88+ } catch (InterruptedException e ) {
89+ e .printStackTrace ();
90+ }
91+ }
92+
93+ /**
94+ * send WATCH command
95+ *
96+ * @param enable enable/disable watch mode
97+ * @param dumpData enable/disable dumping of data
98+ * @return {@link WatchObject}
99+ * @throws IOException on IO error in socket
100+ */
101+ public WatchObject watch (boolean enable , boolean dumpData ) throws IOException {
102+ return this .watch (enable , dumpData , null );
66103 }
67104
68105 /**
69106 * send WATCH command
70107 *
71108 * @param enable enable/disable watch mode
109+ * @param dumpData enable/disable dumping of data
110+ * @param device If present, enable watching only of the specified device
111+ * rather than all devices
112+ * @return {@link WatchObject}
113+ * @throws IOException on IO error in socket
72114 */
73- public void watch (boolean enable ) {
115+ public WatchObject watch (boolean enable , boolean dumpData , String device ) throws IOException {
74116 try {
75- this .out .write ("?WATCH={\" enable\" :true,\" json\" :true}" );
76- this .out .flush ();
77- } catch (IOException e ) {
117+ JSONObject watch = new JSONObject ();
118+ watch .put ("class" , "WATCH" );
119+ watch .put ("enable" , enable );
120+ watch .put ("json" , dumpData );
121+ if (device != null ) {
122+ watch .put ("device" , device );
123+ }
124+ return this .syncCommand ("?WATCH=" + watch .toString (), WatchObject .class );
125+ } catch (JSONException e ) {
78126 e .printStackTrace ();
79127 }
128+ return null ;
80129 }
81130
82131 /**
83132 * Poll GPSd for Message
84133 *
85- * @return {@link IGPSObject}
134+ * @return {@link PollObject}
135+ * @throws IOException on IO error in socket
136+ * @throws ParseException on illegal response
137+ */
138+ public PollObject poll () throws IOException , ParseException {
139+ return this .syncCommand ("?POLL;" , PollObject .class );
140+ }
141+
142+ /**
143+ * Poll GPSd version
144+ *
145+ * @return {@link VersionObject}
86146 * @throws IOException on IO error in socket
87147 * @throws ParseException on illegal response
88148 */
89- public IGPSObject poll () throws IOException , ParseException {
90- this .out .write ("?POLL;\n " );
91- this .out .flush ();
92- return ResultParser .parse (this .in .readLine ());
149+ public VersionObject version () throws IOException , ParseException {
150+ return this .syncCommand ("?VERSION;" , VersionObject .class );
93151 }
94152
95153 // TODO implement rest of commands
96154
97155 // ########################################################
98156
99- void handle (IGPSObject object ) {
100- // TODO handle response
101- System .out .println (object );
157+ /**
158+ * @param listener the listener to add
159+ */
160+ public void addListener (IObjectListener listener ) {
161+ this .listeners .add (listener );
162+ }
163+
164+ /**
165+ * @param listener the listener to remove
166+ */
167+ public void removeListener (IObjectListener listener ) {
168+ this .listeners .remove (listener );
102169 }
103170
171+ // ########################################################
172+
173+ private <T extends IGPSObject > T syncCommand (String command , Class <T > responseClass ) throws IOException {
174+ synchronized (this .asyncMutex ) {
175+ this .out .write (command + "\n " );
176+ this .out .flush ();
177+
178+ while (true ) {
179+ // wait for awaited message
180+ IGPSObject result = this .waitForResult ();
181+ if ((result == null ) || result .getClass ().equals (responseClass )) {
182+ return responseClass .cast (result );
183+ }
184+ }
185+ }
186+ }
187+
188+ // will be used later on
189+ @ SuppressWarnings ("unused" )
190+ private void voidCommand (String command ) throws IOException {
191+ synchronized (this .asyncMutex ) {
192+ this .out .write (command + "\n " );
193+ this .out .flush ();
194+ }
195+ }
196+
197+ private IGPSObject waitForResult () {
198+ synchronized (this .asyncWaitMutex ) {
199+ this .asnycResult = null ;
200+ try {
201+ this .asyncWaitMutex .wait (1000 );
202+ } catch (InterruptedException e ) {
203+ e .printStackTrace ();
204+ }
205+ if (this .asnycResult != null ) {
206+ return this .asnycResult ;
207+ }
208+ }
209+ return null ;
210+ }
211+
212+ void handle (IGPSObject object ) {
213+ if (object instanceof TPVObject ) {
214+ for (IObjectListener l : this .listeners ) {
215+ l .handleTPV ((TPVObject ) object );
216+ }
217+ } else if (object instanceof SKYObject ) {
218+ for (IObjectListener l : this .listeners ) {
219+ l .handleSKY ((SKYObject ) object );
220+ }
221+ // } else if (object instanceof ATTObject) {
222+ // for (IObjectListener l : this.listeners) {
223+ // l.handleATT((ATTObject) object);
224+ // }
225+ } else if (object instanceof DevicesObject ) {
226+ for (IObjectListener l : this .listeners ) {
227+ l .handleDevices ((DevicesObject ) object );
228+ }
229+ } else if (object instanceof DeviceObject ) {
230+ for (IObjectListener l : this .listeners ) {
231+ l .handleDevice ((DeviceObject ) object );
232+ }
233+ } else {
234+ synchronized (this .asyncWaitMutex ) {
235+ this .asnycResult = object ;
236+ this .asyncWaitMutex .notifyAll ();
237+ }
238+ }
239+ }
104240}
0 commit comments