Commit | Line | Data |
---|---|---|
d42e7319 JB |
1 | /* |
2 | * Copyright (C) 2012 Jolla Ltd. | |
3 | * Author: Philippe De Swert <philippe.deswert@jollamobile.com> | |
4 | * | |
5 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | * you may not use this file except in compliance with the License. | |
7 | * You may obtain a copy of the License at | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, software | |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | * See the License for the specific language governing permissions and | |
15 | * limitations under the License. | |
16 | * | |
17 | */ | |
18 | ||
19 | #include <pthread.h> | |
20 | #include <signal.h> | |
21 | #include <stdio.h> | |
22 | #include <unistd.h> | |
23 | #include <stdlib.h> | |
24 | #include <sys/time.h> | |
25 | #include <getopt.h> | |
26 | #include <string.h> | |
27 | ||
28 | #include <android/hardware/gps.h> | |
29 | ||
30 | const GpsInterface* Gps = NULL; | |
31 | const AGpsInterface* AGps = NULL; | |
32 | const AGpsRilInterface* AGpsRil = NULL; | |
33 | const GpsNiInterface *GpsNi = NULL; | |
34 | const GpsXtraInterface *GpsExtra = NULL; | |
35 | #ifdef HAVE_ULP | |
36 | const UlpNetworkInterface *UlpNetwork = NULL; | |
37 | const UlpPhoneContextInterface *UlpPhoneContext = NULL; | |
38 | #endif /* HAVE_ULP */ | |
39 | char *apn = 0; | |
40 | ||
41 | static const GpsInterface* get_gps_interface() | |
42 | { | |
43 | int error; | |
44 | hw_module_t* module; | |
45 | const GpsInterface* interface = NULL; | |
46 | struct gps_device_t *device; | |
47 | ||
48 | error = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module); | |
49 | ||
50 | if (!error) | |
51 | { | |
52 | error = module->methods->open(module, GPS_HARDWARE_MODULE_ID, (struct hw_device_t **) &device); | |
53 | fprintf(stdout, "*** device info\n id = %s\n name = %s\n author = %s\n", | |
54 | module->id, module->name, module->author); | |
55 | ||
56 | if (!error) | |
57 | { | |
58 | interface = device->get_gps_interface(device); | |
59 | } | |
60 | } | |
61 | else | |
62 | { | |
63 | fprintf(stdout, "*** GPS interface not found :\(\n Bye! \n"); | |
64 | exit(1); | |
65 | } | |
66 | ||
67 | return interface; | |
68 | } | |
69 | ||
70 | static const AGpsInterface* get_agps_interface(const GpsInterface *gps) | |
71 | { | |
72 | const AGpsInterface* interface = NULL; | |
73 | ||
74 | if (gps) | |
75 | { | |
76 | interface = (const AGpsInterface*)gps->get_extension(AGPS_INTERFACE); | |
77 | } | |
78 | return interface; | |
79 | } | |
80 | ||
81 | static const AGpsRilInterface* get_agps_ril_interface(const GpsInterface *gps) | |
82 | { | |
83 | const AGpsRilInterface* interface = NULL; | |
84 | ||
85 | if (gps) | |
86 | { | |
87 | interface = (const AGpsRilInterface*)gps->get_extension(AGPS_RIL_INTERFACE); | |
88 | } | |
89 | return interface; | |
90 | } | |
91 | ||
92 | static const GpsNiInterface* get_gps_ni_interface(const GpsInterface *gps) | |
93 | { | |
94 | const GpsNiInterface* interface = NULL; | |
95 | ||
96 | if(gps) | |
97 | { | |
98 | interface = (const GpsNiInterface*)gps->get_extension(GPS_NI_INTERFACE); | |
99 | } | |
100 | return interface; | |
101 | } | |
102 | ||
103 | static const GpsDebugInterface* get_gps_debug_interface(const GpsInterface *gps) | |
104 | { | |
105 | const GpsDebugInterface* interface = NULL; | |
106 | ||
107 | if(gps) | |
108 | { | |
109 | interface = (const GpsDebugInterface*)gps->get_extension(GPS_DEBUG_INTERFACE); | |
110 | } | |
111 | return interface; | |
112 | } | |
113 | ||
114 | static const GpsXtraInterface* get_gps_extra_interface(const GpsInterface *gps) | |
115 | { | |
116 | const GpsXtraInterface* interface = NULL; | |
117 | ||
118 | if(gps) | |
119 | { | |
120 | interface = (const GpsXtraInterface*)gps->get_extension(GPS_XTRA_INTERFACE); | |
121 | } | |
122 | return interface; | |
123 | } | |
124 | ||
125 | #ifdef HAVE_ULP | |
126 | static const UlpNetworkInterface* get_ulp_network_interface(const GpsInterface *gps) | |
127 | { | |
128 | const UlpNetworkInterface* interface = NULL; | |
129 | ||
130 | if (gps) | |
131 | { | |
132 | interface = (const UlpNetworkInterface*)gps->get_extension(ULP_NETWORK_INTERFACE); | |
133 | } | |
134 | return interface; | |
135 | } | |
136 | ||
137 | static const UlpPhoneContextInterface* get_ulp_phone_context_interface(const GpsInterface *gps) | |
138 | { | |
139 | const UlpPhoneContextInterface* interface = NULL; | |
140 | ||
141 | if (gps) | |
142 | { | |
143 | interface = (const UlpPhoneContextInterface*)gps->get_extension(ULP_PHONE_CONTEXT_INTERFACE); | |
144 | } | |
145 | return interface; | |
146 | } | |
147 | #endif /* HAVE_ULP */ | |
148 | ||
149 | static void location_callback(GpsLocation* location) | |
150 | { | |
151 | fprintf(stdout, "*** location callback\n"); | |
152 | fprintf(stdout, "flags:\t%d\n", location->flags); | |
153 | fprintf(stdout, "latitude: \t%lf\n", location->latitude); | |
154 | fprintf(stdout, "longtide: \t%lf\n", location->longitude); | |
155 | fprintf(stdout, "accuracy:\t%f\n", location->accuracy); | |
156 | fprintf(stdout, "utc: \t%ld\n", (long)location->timestamp); | |
157 | } | |
158 | ||
159 | static void status_callback(GpsStatus* status) | |
160 | { | |
161 | fprintf(stdout, "*** status callback\n"); | |
162 | ||
163 | switch (status->status) | |
164 | { | |
165 | case GPS_STATUS_NONE: | |
166 | fprintf(stdout, "*** no gps\n"); | |
167 | break; | |
168 | case GPS_STATUS_SESSION_BEGIN: | |
169 | fprintf(stdout, "*** session begin\n"); | |
170 | break; | |
171 | case GPS_STATUS_SESSION_END: | |
172 | fprintf(stdout, "*** session end\n"); | |
173 | break; | |
174 | case GPS_STATUS_ENGINE_ON: | |
175 | fprintf(stdout, "*** engine on\n"); | |
176 | break; | |
177 | case GPS_STATUS_ENGINE_OFF: | |
178 | fprintf(stdout, "*** engine off\n"); | |
179 | break; | |
180 | default: | |
181 | fprintf(stdout, "*** unknown status\n"); | |
182 | } | |
183 | } | |
184 | ||
185 | static void sv_status_callback(GpsSvStatus* sv_info) | |
186 | { | |
187 | int i = 0; | |
188 | ||
189 | fprintf(stdout, "*** sv status\n"); | |
190 | fprintf(stdout, "sv_size:\t%zu\n", sv_info->size); | |
191 | fprintf(stdout, "num_svs:\t%d\n", sv_info->num_svs); | |
192 | for(i=0; i < sv_info->num_svs; i++) | |
193 | { | |
194 | fprintf(stdout, "\t azimuth:\t%f\n", sv_info->sv_list[i].azimuth); | |
195 | fprintf(stdout, "\t elevation:\t%f\n", sv_info->sv_list[i].elevation); | |
196 | /* if prn > 65 and <= 88 this is a glonass sattelite */ | |
197 | fprintf(stdout, "\t prn:\t%d\n", sv_info->sv_list[i].prn); | |
198 | fprintf(stdout, "\t size:\t%zu\n", sv_info->sv_list[i].size); | |
199 | fprintf(stdout, "\t snr:\t%f\n", sv_info->sv_list[i].snr); | |
200 | } | |
201 | ||
202 | } | |
203 | ||
204 | static void nmea_callback(GpsUtcTime timestamp, const char* nmea, int length) | |
205 | { | |
206 | char buf[83]; | |
207 | fprintf(stdout, "*** nmea info\n"); | |
208 | fprintf(stdout, "timestamp:\t%ld\n", (long)timestamp); | |
209 | /* NMEA sentences can only be between 11 ($TTFFF*CC\r\n) and 82 characters long */ | |
210 | if (length > 10 && length < 83) { | |
211 | strncpy(buf, nmea, length); | |
212 | buf[length] = '\0'; | |
213 | fprintf(stdout, "nmea (%d): \t%s\n", length, buf); | |
214 | } else { | |
215 | fprintf(stdout, "Invalid nmea data\n"); | |
216 | } | |
217 | } | |
218 | ||
219 | static void set_capabilities_callback(uint32_t capabilities) | |
220 | { | |
221 | fprintf(stdout, "*** set capabilities\n"); | |
222 | fprintf(stdout, "capability is %.8x\n", capabilities); | |
223 | /* do nothing */ | |
224 | } | |
225 | ||
226 | static void acquire_wakelock_callback() | |
227 | { | |
228 | fprintf(stdout, "*** acquire wakelock\n"); | |
229 | /* do nothing */ | |
230 | } | |
231 | ||
232 | static void release_wakelock_callback() | |
233 | { | |
234 | fprintf(stdout, "*** release wakelock\n"); | |
235 | /* do nothing */ | |
236 | } | |
237 | ||
238 | struct ThreadWrapperContext { | |
239 | void (*func)(void *); | |
240 | void *user_data; | |
241 | }; | |
242 | ||
243 | static void *thread_wrapper_context_main_func(void *user_data) | |
244 | { | |
245 | struct ThreadWrapperContext *ctx = (struct ThreadWrapperContext *)user_data; | |
246 | ||
247 | fprintf(stderr, " **** Thread wrapper start (start=%p, arg=%p) ****\n", | |
248 | ctx->func, ctx->user_data); | |
249 | ctx->func(ctx->user_data); | |
250 | fprintf(stderr, " **** Thread wrapper end (start=%p, arg=%p) ****\n", | |
251 | ctx->func, ctx->user_data); | |
252 | ||
253 | free(ctx); | |
254 | ||
255 | return NULL; | |
256 | } | |
257 | ||
258 | static pthread_t create_thread_callback(const char* name, void (*start)(void *), void* arg) | |
259 | { | |
260 | pthread_t thread_id; | |
261 | int error = 0; | |
262 | ||
263 | /* Wrap thread function, so we can return void * to pthread and log start/end of thread */ | |
264 | struct ThreadWrapperContext *ctx = calloc(1, sizeof(struct ThreadWrapperContext)); | |
265 | ctx->func = start; | |
266 | ctx->user_data = arg; | |
267 | ||
268 | fprintf(stderr, " ** Creating thread: '%s' (start=%p, arg=%p)\n", name, start, arg); | |
269 | /* Do not use a pthread_attr_t (we'd have to take care of bionic/glibc differences) */ | |
270 | error = pthread_create(&thread_id, NULL, thread_wrapper_context_main_func, ctx); | |
271 | fprintf(stderr, " ** After thread_create: '%s', error=%d (start=%p, arg=%p)\n", name, error, start, arg); | |
272 | ||
273 | if(error != 0) | |
274 | return 0; | |
275 | ||
276 | return thread_id; | |
277 | } | |
278 | ||
279 | static void agps_handle_status_callback(AGpsStatus *status) | |
280 | { | |
281 | if(status->type) | |
282 | { | |
283 | fprintf(stdout, "*** gps type %d\n", status->type); | |
284 | } | |
285 | switch (status->status) | |
286 | { | |
287 | case GPS_REQUEST_AGPS_DATA_CONN: | |
288 | fprintf(stdout, "*** data_conn_open\n"); | |
289 | #ifndef HAS_ANDROID_4_2_0 | |
290 | AGps->data_conn_open(AGPS_TYPE_SUPL, apn, AGPS_APN_BEARER_IPV4); | |
291 | #else | |
292 | AGps->data_conn_open(apn); | |
293 | #endif | |
294 | break; | |
295 | case GPS_RELEASE_AGPS_DATA_CONN: | |
296 | fprintf(stdout, "*** data_conn_closed\n"); | |
297 | #ifndef HAS_ANDROID_4_2_0 | |
298 | AGps->data_conn_closed(AGPS_TYPE_SUPL); | |
299 | #else | |
300 | AGps->data_conn_closed(); | |
301 | #endif | |
302 | break; | |
303 | case GPS_AGPS_DATA_CONNECTED: | |
304 | fprintf(stdout, "*** data_conn_established\n"); | |
305 | break; | |
306 | case GPS_AGPS_DATA_CONN_DONE: | |
307 | fprintf(stdout, "*** data_conn_done\n"); | |
308 | break; | |
309 | case GPS_AGPS_DATA_CONN_FAILED: | |
310 | fprintf(stdout, "*** data_conn_FAILED\n"); | |
311 | break; | |
312 | } | |
313 | } | |
314 | ||
315 | static void agps_ril_set_id_callback(uint32_t flags) | |
316 | { | |
317 | fprintf(stdout, "*** set_id_cb\n"); | |
318 | AGpsRil->set_set_id(AGPS_SETID_TYPE_IMSI, "000000000000000"); | |
319 | } | |
320 | ||
321 | static void agps_ril_refloc_callback(uint32_t flags) | |
322 | { | |
323 | fprintf(stdout, "*** refloc_cb\n"); | |
324 | /* TODO : find out how to fill in location | |
325 | AGpsRefLocation location; | |
326 | AGpsRil->set_ref_location(&location, sizeof(location)); | |
327 | */ | |
328 | } | |
329 | ||
330 | static void ni_notify_callback (GpsNiNotification *notification) | |
331 | { | |
332 | fprintf(stdout, "*** ni notification callback\n"); | |
333 | } | |
334 | ||
335 | static void download_xtra_request_callback (void) | |
336 | { | |
337 | fprintf(stdout, "*** xtra download request to client\n"); | |
338 | } | |
339 | ||
340 | #ifdef HAVE_ULP | |
341 | static void ulp_network_location_request_callback(UlpNetworkRequestPos *req) | |
342 | { | |
343 | fprintf(stdout, "*** ulp network location request (request_type=%#x, interval_ms=%d, desired_position_source=%#x)\n", | |
344 | req->request_type, req->interval_ms, req->desired_position_source); | |
345 | } | |
346 | ||
347 | static void ulp_request_phone_context_callback(UlpPhoneContextRequest *req) | |
348 | { | |
349 | fprintf(stdout, "*** ulp phone context request (context_type=%#x, request_type=%#x, interval_ms=%d)\n", | |
350 | req->context_type, req->request_type, req->interval_ms); | |
351 | ||
352 | if (UlpPhoneContext) { | |
353 | fprintf(stdout, "*** sending ulp phone context reply\n"); | |
354 | UlpPhoneContextSettings settings; | |
355 | settings.context_type = req->context_type; | |
356 | settings.is_gps_enabled = 1; | |
357 | settings.is_agps_enabled = 1; | |
358 | settings.is_network_position_available = 1; | |
359 | settings.is_wifi_setting_enabled = 1; | |
360 | settings.is_battery_charging = 0; | |
361 | settings.is_enh_location_services_enabled = 1; | |
362 | UlpPhoneContext->ulp_phone_context_settings_update(&settings); | |
363 | } | |
364 | } | |
365 | #endif /* HAVE_ULP */ | |
366 | ||
367 | GpsCallbacks callbacks = { | |
368 | sizeof(GpsCallbacks), | |
369 | location_callback, | |
370 | status_callback, | |
371 | sv_status_callback, | |
372 | nmea_callback, | |
373 | set_capabilities_callback, | |
374 | acquire_wakelock_callback, | |
375 | release_wakelock_callback, | |
376 | create_thread_callback, | |
377 | }; | |
378 | ||
379 | AGpsCallbacks callbacks2 = { | |
380 | agps_handle_status_callback, | |
381 | create_thread_callback, | |
382 | }; | |
383 | ||
384 | AGpsRilCallbacks callbacks3 = { | |
385 | agps_ril_set_id_callback, | |
386 | agps_ril_refloc_callback, | |
387 | create_thread_callback, | |
388 | }; | |
389 | ||
390 | GpsNiCallbacks callbacks4 = { | |
391 | ni_notify_callback, | |
392 | create_thread_callback, | |
393 | }; | |
394 | ||
395 | GpsXtraCallbacks callbacks5 = { | |
396 | download_xtra_request_callback, | |
397 | create_thread_callback, | |
398 | }; | |
399 | ||
400 | #ifdef HAVE_ULP | |
401 | UlpNetworkLocationCallbacks callbacks6 = { | |
402 | ulp_network_location_request_callback, | |
403 | }; | |
404 | ||
405 | UlpPhoneContextCallbacks callbacks7 = { | |
406 | ulp_request_phone_context_callback, | |
407 | }; | |
408 | #endif /* HAVE_ULP */ | |
409 | ||
410 | void sigint_handler(int signum) | |
411 | { | |
412 | fprintf(stdout, "*** cleanup\n"); | |
413 | if(AGps) | |
414 | { | |
415 | #ifndef HAS_ANDROID_4_2_0 | |
416 | AGps->data_conn_closed(AGPS_TYPE_SUPL); | |
417 | #else | |
418 | AGps->data_conn_closed(); | |
419 | #endif | |
420 | } | |
421 | if (Gps) | |
422 | { | |
423 | Gps->stop(); | |
424 | Gps->cleanup(); | |
425 | } | |
426 | exit (0); | |
427 | } | |
428 | ||
429 | int main(int argc, char *argv[]) | |
430 | { | |
431 | int sleeptime = 6000, opt, initok = 0; | |
432 | int coldstart = 0, extra = 0, ulp = 0; | |
433 | struct timeval tv; | |
434 | int agps = 0, agpsril = 0, injecttime = 0, injectlocation = 0; | |
435 | char *location = 0, *longitude, *latitude; | |
436 | float accuracy = 100; /* Use 100m as location accuracy by default */ | |
437 | ||
438 | while ((opt = getopt(argc, argv, "acl:p:rtux")) != -1) | |
439 | { | |
440 | switch (opt) { | |
441 | case 'a': | |
442 | agps = 1; | |
443 | fprintf(stdout, "*** Using agps\n"); | |
444 | break; | |
445 | case 'c': | |
446 | coldstart = 1; | |
447 | fprintf(stdout, "*** Using cold start\n"); | |
448 | break; | |
449 | case 'l': | |
450 | injectlocation = 1; | |
451 | location = optarg; | |
452 | fprintf(stdout, "*** Location info %s will be injected\n", location); | |
453 | break; | |
454 | case 'r': | |
455 | agpsril = 1; | |
456 | fprintf(stdout, "*** Using agpsril\n"); | |
457 | break; | |
458 | case 't': | |
459 | injecttime = 1; | |
460 | fprintf(stdout, "*** Timing info will be injected\n"); | |
461 | break; | |
462 | case 'p': | |
463 | apn = optarg; | |
464 | break; | |
465 | case 'u': | |
466 | ulp = 1; | |
467 | break; | |
468 | case 'x': | |
469 | extra = 1; | |
470 | fprintf(stdout, "*** Allowing for Xtra downloads\n"); | |
471 | break; | |
472 | default: | |
473 | fprintf(stderr, "\n Usage: %s \n \ | |
474 | \t-a for agps,\n \ | |
475 | \t-c for coldstarting the gps,\n \ | |
476 | \t-p <apn name> to specify an apn name,\n \ | |
477 | \t-r for agpsril,\n \ | |
478 | \t-t to inject time,\n \ | |
479 | \t-u to use ULP (if available,\n \ | |
480 | \t-x deal with Xtra gps data.\n \ | |
481 | \tnone for standalone gps\n", | |
482 | argv[0]); | |
483 | exit(1); | |
484 | } | |
485 | } | |
486 | ||
487 | if(!apn) | |
488 | { | |
489 | apn = strdup("Internet"); | |
490 | } | |
491 | ||
492 | fprintf(stdout, "*** setup signal handler\n"); | |
493 | signal(SIGINT, sigint_handler); | |
494 | ||
495 | fprintf(stdout, "*** get gps interface\n"); | |
496 | Gps = get_gps_interface(); | |
497 | ||
498 | fprintf(stdout, "*** init gps interface\n"); | |
499 | initok = Gps->init(&callbacks); | |
500 | fprintf(stdout, "*** setting positioning mode\n"); | |
501 | /* need to be done before starting gps or no info will come out */ | |
502 | if((agps||agpsril) && !initok) | |
503 | Gps->set_position_mode(GPS_POSITION_MODE_MS_BASED, GPS_POSITION_RECURRENCE_PERIODIC, 1000, 0, 0); | |
504 | else | |
505 | Gps->set_position_mode(GPS_POSITION_MODE_STANDALONE, GPS_POSITION_RECURRENCE_PERIODIC, 1000, 0, 0); | |
506 | ||
507 | if (Gps && !initok && (agps||agpsril)) | |
508 | { | |
509 | fprintf(stdout, "*** get agps interface\n"); | |
510 | AGps = get_agps_interface(Gps); | |
511 | if (AGps) | |
512 | { | |
513 | fprintf(stdout, "*** set up agps interface\n"); | |
514 | AGps->init(&callbacks2); | |
515 | fprintf(stdout, "*** set up agps server\n"); | |
516 | AGps->set_server(AGPS_TYPE_SUPL, "supl.google.com", 7276); | |
517 | } | |
518 | ||
519 | if(agpsril) | |
520 | { | |
521 | fprintf(stdout, "*** get agps ril interface\n"); | |
522 | ||
523 | AGpsRil = get_agps_ril_interface(Gps); | |
524 | if (AGpsRil) | |
525 | { | |
526 | AGpsRil->init(&callbacks3); | |
527 | } | |
528 | } | |
529 | /* if coldstart is requested, delete all location info */ | |
530 | if(coldstart) | |
531 | { | |
532 | fprintf(stdout, "*** delete aiding data\n"); | |
533 | Gps->delete_aiding_data(GPS_DELETE_ALL); | |
534 | } | |
535 | ||
536 | if(extra) | |
537 | { | |
538 | fprintf(stdout, "*** xtra aiding data init\n"); | |
539 | GpsExtra = get_gps_extra_interface(Gps); | |
540 | if(GpsExtra) | |
541 | GpsExtra->init(&callbacks5); | |
542 | } | |
543 | ||
544 | fprintf(stdout, "*** setting up network notification handling\n"); | |
545 | GpsNi = get_gps_ni_interface(Gps); | |
546 | if(GpsNi) | |
547 | { | |
548 | GpsNi->init(&callbacks4); | |
549 | } | |
550 | ||
551 | #ifdef HAVE_ULP | |
552 | if(ulp) | |
553 | { | |
554 | UlpNetwork = get_ulp_network_interface(Gps); | |
555 | if (UlpNetwork) { | |
556 | fprintf(stdout, "*** got ulp network interface\n"); | |
557 | if (UlpNetwork->init(&callbacks6) != 0) { | |
558 | fprintf(stdout, "*** FAILED to init ulp network interface\n"); | |
559 | UlpNetwork = NULL; | |
560 | } | |
561 | } | |
562 | else | |
563 | fprintf(stdout, "*** ULP failed!\n"); | |
564 | ||
565 | UlpPhoneContext = get_ulp_phone_context_interface(Gps); | |
566 | if (UlpPhoneContext) { | |
567 | fprintf(stdout, "*** got ulp phone context interface\n"); | |
568 | UlpPhoneContext->init(&callbacks7); | |
569 | } | |
570 | } | |
571 | #endif /* HAVE_ULP */ | |
572 | } | |
573 | if(injecttime) | |
574 | { | |
575 | fprintf(stdout, "*** aiding gps by injecting time information\n"); | |
576 | gettimeofday(&tv, NULL); | |
577 | Gps->inject_time(tv.tv_sec, tv.tv_sec, 0); | |
578 | } | |
579 | ||
580 | if(injectlocation) | |
581 | { | |
582 | fprintf(stdout, "*** aiding gps by injecting location information\n"); | |
583 | //Gps->inject_location(double latitude, double longitude, float accuracy); | |
584 | latitude = strtok(location, ","); | |
585 | longitude = strtok(NULL, ","); | |
586 | Gps->inject_location(strtod(latitude, NULL), strtod(longitude, NULL), accuracy); | |
587 | } | |
588 | ||
589 | fprintf(stdout, "*** start gps track\n"); | |
590 | Gps->start(); | |
591 | ||
592 | fprintf(stdout, "*** gps tracking started\n"); | |
593 | ||
594 | while(sleeptime > 0) | |
595 | { | |
596 | fprintf(stdout, "*** tracking.... \n"); | |
597 | sleep(100); | |
598 | sleeptime = sleeptime - 100; | |
599 | } | |
600 | ||
601 | if (AGps) | |
602 | AGps->data_conn_closed(AGPS_TYPE_SUPL); | |
603 | fprintf(stdout, "*** stop tracking\n"); | |
604 | Gps->stop(); | |
605 | fprintf(stdout, "*** cleaning up\n"); | |
606 | Gps->cleanup(); | |
607 | ||
608 | return 0; | |
609 | } |