| 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 | } |