1/* Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 *     * Redistributions of source code must retain the above copyright
7 *       notice, this list of conditions and the following disclaimer.
8 *     * Redistributions in binary form must reproduce the above
9 *       copyright notice, this list of conditions and the following
10 *       disclaimer in the documentation and/or other materials provided
11 *       with the distribution.
12 *     * Neither the name of The Linux Foundation, nor the names of its
13 *       contributors may be used to endorse or promote products derived
14 *       from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#define LOG_NDDEBUG 0
31#define LOG_TAG "LocSvc_eng"
32
33#include <stdint.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <unistd.h>
37#include <dlfcn.h>
38#include <ctype.h>
39#include <math.h>
40#include <pthread.h>
41#include <arpa/inet.h>
42#include <netinet/in.h>         /* struct sockaddr_in */
43#include <sys/socket.h>
44#include <sys/time.h>
45#include <netdb.h>
46#include <time.h>
47
48#include <LocEngAdapter.h>
49
50#include <cutils/sched_policy.h>
51#ifndef USE_GLIB
52#include <utils/SystemClock.h>
53#include <utils/Log.h>
54#endif /* USE_GLIB */
55
56#ifdef USE_GLIB
57#include <glib.h>
58#include <sys/syscall.h>
59#endif /* USE_GLIB */
60
61#include <string.h>
62
63#include <loc_eng.h>
64#include <loc_eng_ni.h>
65#include <loc_eng_dmn_conn.h>
66#include <loc_eng_dmn_conn_handler.h>
67#include <loc_eng_msg.h>
68#include <loc_eng_nmea.h>
69#include <msg_q.h>
70#include <loc.h>
71#include "log_util.h"
72#include "platform_lib_includes.h"
73#include "loc_core_log.h"
74#include "loc_eng_log.h"
75
76#define SUCCESS TRUE
77#define FAILURE FALSE
78
79#ifndef GPS_CONF_FILE
80#define GPS_CONF_FILE            "/etc/gps.conf"   //??? platform independent
81#endif
82
83#ifndef SAP_CONF_FILE
84#define SAP_CONF_FILE            "/etc/sap.conf"
85#endif
86
87using namespace loc_core;
88
89boolean configAlreadyRead = false;
90unsigned int agpsStatus = 0;
91loc_gps_cfg_s_type gps_conf;
92loc_sap_cfg_s_type sap_conf;
93
94/* Parameter spec table */
95static loc_param_s_type loc_parameter_table[] =
96{
97  {"INTERMEDIATE_POS",               &gps_conf.INTERMEDIATE_POS,               NULL, 'n'},
98  {"ACCURACY_THRES",                 &gps_conf.ACCURACY_THRES,                 NULL, 'n'},
99  {"ENABLE_WIPER",                   &gps_conf.ENABLE_WIPER,                   NULL, 'n'},
100  {"NMEA_PROVIDER",                  &gps_conf.NMEA_PROVIDER,                  NULL, 'n'},
101  {"SUPL_VER",                       &gps_conf.SUPL_VER,                       NULL, 'n'},
102  {"CAPABILITIES",                   &gps_conf.CAPABILITIES,                   NULL, 'n'},
103  {"GYRO_BIAS_RANDOM_WALK",          &sap_conf.GYRO_BIAS_RANDOM_WALK,          &sap_conf.GYRO_BIAS_RANDOM_WALK_VALID, 'f'},
104  {"ACCEL_RANDOM_WALK_SPECTRAL_DENSITY",     &sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY,    &sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
105  {"ANGLE_RANDOM_WALK_SPECTRAL_DENSITY",     &sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY,    &sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
106  {"RATE_RANDOM_WALK_SPECTRAL_DENSITY",      &sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY,     &sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
107  {"VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY",  &sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY, &sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
108  {"SENSOR_ACCEL_BATCHES_PER_SEC",   &sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC,   NULL, 'n'},
109  {"SENSOR_ACCEL_SAMPLES_PER_BATCH", &sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH, NULL, 'n'},
110  {"SENSOR_GYRO_BATCHES_PER_SEC",    &sap_conf.SENSOR_GYRO_BATCHES_PER_SEC,    NULL, 'n'},
111  {"SENSOR_GYRO_SAMPLES_PER_BATCH",  &sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH,  NULL, 'n'},
112  {"SENSOR_ACCEL_BATCHES_PER_SEC_HIGH",   &sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH,   NULL, 'n'},
113  {"SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH", &sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH, NULL, 'n'},
114  {"SENSOR_GYRO_BATCHES_PER_SEC_HIGH",    &sap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH,    NULL, 'n'},
115  {"SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH",  &sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH,  NULL, 'n'},
116  {"SENSOR_CONTROL_MODE",            &sap_conf.SENSOR_CONTROL_MODE,            NULL, 'n'},
117  {"SENSOR_USAGE",                   &sap_conf.SENSOR_USAGE,                   NULL, 'n'},
118  {"SENSOR_ALGORITHM_CONFIG_MASK",   &sap_conf.SENSOR_ALGORITHM_CONFIG_MASK,   NULL, 'n'},
119  {"QUIPC_ENABLED",                  &gps_conf.QUIPC_ENABLED,                  NULL, 'n'},
120  {"LPP_PROFILE",                    &gps_conf.LPP_PROFILE,                    NULL, 'n'},
121  {"A_GLONASS_POS_PROTOCOL_SELECT",  &gps_conf.A_GLONASS_POS_PROTOCOL_SELECT,  NULL, 'n'},
122};
123
124static void loc_default_parameters(void)
125{
126   /* defaults */
127   gps_conf.INTERMEDIATE_POS = 0;
128   gps_conf.ACCURACY_THRES = 0;
129   gps_conf.ENABLE_WIPER = 0;
130   gps_conf.NMEA_PROVIDER = 0;
131   gps_conf.SUPL_VER = 0x10000;
132   gps_conf.CAPABILITIES = 0x7;
133
134   sap_conf.GYRO_BIAS_RANDOM_WALK = 0;
135   sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC = 2;
136   sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH = 5;
137   sap_conf.SENSOR_GYRO_BATCHES_PER_SEC = 2;
138   sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH = 5;
139   sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH = 4;
140   sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH = 25;
141   sap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH = 4;
142   sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH = 25;
143   sap_conf.SENSOR_CONTROL_MODE = 0; /* AUTO */
144   sap_conf.SENSOR_USAGE = 0; /* Enabled */
145   sap_conf.SENSOR_ALGORITHM_CONFIG_MASK = 0; /* INS Disabled = FALSE*/
146
147   /* Values MUST be set by OEMs in configuration for sensor-assisted
148      navigation to work. There are NO default values */
149   sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY = 0;
150   sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
151   sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
152   sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY = 0;
153
154   sap_conf.GYRO_BIAS_RANDOM_WALK_VALID = 0;
155   sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
156   sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
157   sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
158   sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
159
160      /* LTE Positioning Profile configuration is disable by default*/
161   gps_conf.LPP_PROFILE = 0;
162
163   /*By default no positioning protocol is selected on A-GLONASS system*/
164   gps_conf.A_GLONASS_POS_PROTOCOL_SELECT = 0;
165}
166
167// 2nd half of init(), singled out for
168// modem restart to use.
169static int loc_eng_reinit(loc_eng_data_s_type &loc_eng_data);
170static void loc_eng_agps_reinit(loc_eng_data_s_type &loc_eng_data);
171
172static int loc_eng_set_server(loc_eng_data_s_type &loc_eng_data,
173                              LocServerType type, const char *hostname, int port);
174// Internal functions
175static void loc_inform_gps_status(loc_eng_data_s_type &loc_eng_data,
176                                  GpsStatusValue status);
177static void loc_eng_report_status(loc_eng_data_s_type &loc_eng_data,
178                                  GpsStatusValue status);
179static void loc_eng_process_conn_request(loc_eng_data_s_type &loc_eng_data,
180                                         int connHandle, AGpsType agps_type);
181static void loc_eng_agps_close_status(loc_eng_data_s_type &loc_eng_data, int is_succ);
182static void loc_eng_handle_engine_down(loc_eng_data_s_type &loc_eng_data) ;
183static void loc_eng_handle_engine_up(loc_eng_data_s_type &loc_eng_data) ;
184
185static int loc_eng_start_handler(loc_eng_data_s_type &loc_eng_data);
186static int loc_eng_stop_handler(loc_eng_data_s_type &loc_eng_data);
187
188static void deleteAidingData(loc_eng_data_s_type &logEng);
189static AgpsStateMachine*
190getAgpsStateMachine(loc_eng_data_s_type& logEng, AGpsExtType agpsType);
191
192static void update_aiding_data_for_deletion(loc_eng_data_s_type& loc_eng_data) {
193    if (loc_eng_data.engine_status != GPS_STATUS_ENGINE_ON &&
194        loc_eng_data.aiding_data_for_deletion != 0)
195    {
196        loc_eng_data.adapter->deleteAidingData(loc_eng_data.aiding_data_for_deletion);
197        loc_eng_data.aiding_data_for_deletion = 0;
198    }
199}
200
201static void* noProc(void* data)
202{
203    return NULL;
204}
205
206
207/*********************************************************************
208 * definitions of the static messages used in the file
209 *********************************************************************/
210//        case LOC_ENG_MSG_REQUEST_NI:
211LocEngRequestNi::LocEngRequestNi(void* locEng,
212                                 GpsNiNotification &notif,
213                                 const void* data) :
214    LocMsg(), mLocEng(locEng), mNotify(notif), mPayload(data) {
215    locallog();
216}
217void LocEngRequestNi::proc() const {
218    loc_eng_ni_request_handler(*((loc_eng_data_s_type*)mLocEng),
219                               &mNotify, mPayload);
220}
221void LocEngRequestNi::locallog() const
222{
223    LOC_LOGV("id: %d\n  type: %s\n  flags: %d\n  time out: %d\n  "
224             "default response: %s\n  requestor id encoding: %s\n"
225             "  text encoding: %s\n  passThroughData: %p",
226             mNotify.notification_id,
227             loc_get_ni_type_name(mNotify.ni_type),
228             mNotify.notify_flags,
229             mNotify.timeout,
230             loc_get_ni_response_name(mNotify.default_response),
231             loc_get_ni_encoding_name(mNotify.requestor_id_encoding),
232             loc_get_ni_encoding_name(mNotify.text_encoding),
233             mPayload);
234}
235inline void LocEngRequestNi::log() const {
236    locallog();
237}
238
239//        case LOC_ENG_MSG_INFORM_NI_RESPONSE:
240// in loc_eng_ni.cpp
241
242//        case LOC_ENG_MSG_START_FIX:
243LocEngStartFix::LocEngStartFix(LocEngAdapter* adapter) :
244    LocMsg(), mAdapter(adapter)
245{
246    locallog();
247}
248inline void LocEngStartFix::proc() const
249{
250    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mAdapter->getOwner();
251    loc_eng_start_handler(*locEng);
252}
253inline void LocEngStartFix::locallog() const
254{
255    LOC_LOGV("LocEngStartFix");
256}
257inline void LocEngStartFix::log() const
258{
259    locallog();
260}
261void LocEngStartFix::send() const {
262    mAdapter->sendMsg(this);
263}
264
265//        case LOC_ENG_MSG_STOP_FIX:
266LocEngStopFix::LocEngStopFix(LocEngAdapter* adapter) :
267    LocMsg(), mAdapter(adapter)
268{
269    locallog();
270}
271inline void LocEngStopFix::proc() const
272{
273    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mAdapter->getOwner();
274    loc_eng_stop_handler(*locEng);
275}
276inline void LocEngStopFix::locallog() const
277{
278    LOC_LOGV("LocEngStopFix");
279}
280inline void LocEngStopFix::log() const
281{
282    locallog();
283}
284void LocEngStopFix::send() const {
285    mAdapter->sendMsg(this);
286}
287
288//        case LOC_ENG_MSG_SET_POSITION_MODE:
289LocEngPositionMode::LocEngPositionMode(LocEngAdapter* adapter,
290                                       LocPosMode &mode) :
291    LocMsg(), mAdapter(adapter), mPosMode(mode)
292{
293    mPosMode.logv();
294}
295inline void LocEngPositionMode::proc() const {
296    mAdapter->setPositionMode(&mPosMode);
297}
298inline void LocEngPositionMode::log() const {
299    mPosMode.logv();
300}
301void LocEngPositionMode::send() const {
302    mAdapter->sendMsg(this);
303}
304
305//        case LOC_ENG_MSG_SET_TIME:
306struct LocEngSetTime : public LocMsg {
307    LocEngAdapter* mAdapter;
308    const GpsUtcTime mTime;
309    const int64_t mTimeReference;
310    const int mUncertainty;
311    inline LocEngSetTime(LocEngAdapter* adapter,
312                         GpsUtcTime t, int64_t tf, int unc) :
313        LocMsg(), mAdapter(adapter),
314        mTime(t), mTimeReference(tf), mUncertainty(unc)
315    {
316        locallog();
317    }
318    inline virtual void proc() const {
319        mAdapter->setTime(mTime, mTimeReference, mUncertainty);
320    }
321    inline void locallog() const {
322        LOC_LOGV("time: %lld\n  timeReference: %lld\n  uncertainty: %d",
323                 mTime, mTimeReference, mUncertainty);
324    }
325    inline virtual void log() const {
326        locallog();
327    }
328};
329
330 //       case LOC_ENG_MSG_INJECT_LOCATION:
331struct LocEngInjectLocation : public LocMsg {
332    LocEngAdapter* mAdapter;
333    const double mLatitude;
334    const double mLongitude;
335    const float mAccuracy;
336    inline LocEngInjectLocation(LocEngAdapter* adapter,
337                                double lat, double lon, float accur) :
338        LocMsg(), mAdapter(adapter),
339        mLatitude(lat), mLongitude(lon), mAccuracy(accur)
340    {
341        locallog();
342    }
343    inline virtual void proc() const {
344        mAdapter->injectPosition(mLatitude, mLongitude, mAccuracy);
345    }
346    inline void locallog() const {
347        LOC_LOGV("latitude: %f\n  longitude: %f\n  accuracy: %f",
348                 mLatitude, mLongitude, mAccuracy);
349    }
350    inline virtual void log() const {
351        locallog();
352    }
353};
354
355//        case LOC_ENG_MSG_SET_SERVER_IPV4:
356struct LocEngSetServerIpv4 : public LocMsg {
357    LocEngAdapter* mAdapter;
358    const unsigned int mNlAddr;
359    const int mPort;
360    const LocServerType mServerType;
361    inline LocEngSetServerIpv4(LocEngAdapter* adapter,
362                               unsigned int ip,
363                               int port,
364                               LocServerType type) :
365        LocMsg(), mAdapter(adapter),
366        mNlAddr(ip), mPort(port), mServerType(type)
367    {
368        locallog();
369    }
370    inline virtual void proc() const {
371        mAdapter->setServer(mNlAddr, mPort, mServerType);
372    }
373    inline void locallog() const {
374        LOC_LOGV("LocEngSetServerIpv4 - addr: %x, port: %d, type: %s",
375                 mNlAddr, mPort, loc_get_server_type_name(mServerType));
376    }
377    inline virtual void log() const {
378        locallog();
379    }
380};
381
382//        case LOC_ENG_MSG_SET_SERVER_URL:
383struct LocEngSetServerUrl : public LocMsg {
384    LocEngAdapter* mAdapter;
385    const int mLen;
386    char* mUrl;
387    inline LocEngSetServerUrl(LocEngAdapter* adapter,
388                              char* urlString,
389                              int url_len) :
390        LocMsg(), mAdapter(adapter),
391        mLen(url_len), mUrl(new char[mLen+1])
392    {
393        memcpy((void*)mUrl, (void*)urlString, url_len);
394        mUrl[mLen] = 0;
395        locallog();
396    }
397    inline ~LocEngSetServerUrl()
398    {
399        delete[] mUrl;
400    }
401    inline virtual void proc() const {
402        mAdapter->setServer(mUrl, mLen);
403    }
404    inline void locallog() const {
405        LOC_LOGV("LocEngSetServerUrl - url: %s", mUrl);
406    }
407    inline virtual void log() const {
408        locallog();
409    }
410};
411
412//        case LOC_ENG_MSG_A_GLONASS_PROTOCOL:
413struct LocEngAGlonassProtocol : public LocMsg {
414    LocEngAdapter* mAdapter;
415    const unsigned long mAGlonassProtocl;
416    inline LocEngAGlonassProtocol(LocEngAdapter* adapter,
417                                  unsigned long protocol) :
418        LocMsg(), mAdapter(adapter), mAGlonassProtocl(protocol)
419    {
420        locallog();
421    }
422    inline virtual void proc() const {
423        mAdapter->setAGLONASSProtocol(mAGlonassProtocl);
424    }
425    inline  void locallog() const {
426        LOC_LOGV("A-GLONASS protocol: 0x%lx", mAGlonassProtocl);
427    }
428    inline virtual void log() const {
429        locallog();
430    }
431};
432
433//        case LOC_ENG_MSG_SUPL_VERSION:
434struct LocEngSuplVer : public LocMsg {
435    LocEngAdapter* mAdapter;
436    const int mSuplVer;
437    inline LocEngSuplVer(LocEngAdapter* adapter,
438                         int suplVer) :
439        LocMsg(), mAdapter(adapter), mSuplVer(suplVer)
440    {
441        locallog();
442    }
443    inline virtual void proc() const {
444        mAdapter->setSUPLVersion(mSuplVer);
445    }
446    inline  void locallog() const {
447        LOC_LOGV("SUPL Version: %d", mSuplVer);
448    }
449    inline virtual void log() const {
450        locallog();
451    }
452};
453
454//        case LOC_ENG_MSG_LPP_CONFIG:
455struct LocEngLppConfig : public LocMsg {
456    LocEngAdapter* mAdapter;
457    const int mLppConfig;
458    inline LocEngLppConfig(LocEngAdapter* adapter,
459                           int lppConfig) :
460        LocMsg(), mAdapter(adapter), mLppConfig(lppConfig)
461    {
462        locallog();
463    }
464    inline virtual void proc() const {
465        mAdapter->setLPPConfig(mLppConfig);
466    }
467    inline void locallog() const {
468        LOC_LOGV("LocEngLppConfig - profile: %d", mLppConfig);
469    }
470    inline virtual void log() const {
471        locallog();
472    }
473};
474
475//        case LOC_ENG_MSG_SET_SENSOR_CONTROL_CONFIG:
476struct LocEngSensorControlConfig : public LocMsg {
477    LocEngAdapter* mAdapter;
478    const int mSensorsDisabled;
479    inline LocEngSensorControlConfig(LocEngAdapter* adapter,
480                                     int sensorsDisabled) :
481        LocMsg(), mAdapter(adapter), mSensorsDisabled(sensorsDisabled)
482    {
483        locallog();
484    }
485    inline virtual void proc() const {
486        mAdapter->setSensorControlConfig(mSensorsDisabled);
487    }
488    inline  void locallog() const {
489        LOC_LOGV("LocEngSensorControlConfig - Sensors Disabled: %d",
490                 mSensorsDisabled);
491    }
492    inline virtual void log() const {
493        locallog();
494    }
495};
496
497//        case LOC_ENG_MSG_SET_SENSOR_PROPERTIES:
498struct LocEngSensorProperties : public LocMsg {
499    LocEngAdapter* mAdapter;
500    const bool mGyroBiasVarianceRandomWalkValid;
501    const float mGyroBiasVarianceRandomWalk;
502    const bool mAccelRandomWalkValid;
503    const float mAccelRandomWalk;
504    const bool mAngleRandomWalkValid;
505    const float mAngleRandomWalk;
506    const bool mRateRandomWalkValid;
507    const float mRateRandomWalk;
508    const bool mVelocityRandomWalkValid;
509    const float mVelocityRandomWalk;
510    inline LocEngSensorProperties(LocEngAdapter* adapter,
511                                  bool gyroBiasRandomWalk_valid,
512                                  float gyroBiasRandomWalk,
513                                  bool accelRandomWalk_valid,
514                                  float accelRandomWalk,
515                                  bool angleRandomWalk_valid,
516                                  float angleRandomWalk,
517                                  bool rateRandomWalk_valid,
518                                  float rateRandomWalk,
519                                  bool velocityRandomWalk_valid,
520                                  float velocityRandomWalk) :
521        LocMsg(), mAdapter(adapter),
522        mGyroBiasVarianceRandomWalkValid(gyroBiasRandomWalk_valid),
523        mGyroBiasVarianceRandomWalk(gyroBiasRandomWalk),
524        mAccelRandomWalkValid(accelRandomWalk_valid),
525        mAccelRandomWalk(accelRandomWalk),
526        mAngleRandomWalkValid(angleRandomWalk_valid),
527        mAngleRandomWalk(angleRandomWalk),
528        mRateRandomWalkValid(rateRandomWalk_valid),
529        mRateRandomWalk(rateRandomWalk),
530        mVelocityRandomWalkValid(velocityRandomWalk_valid),
531        mVelocityRandomWalk(velocityRandomWalk)
532    {
533        locallog();
534    }
535    inline virtual void proc() const {
536        mAdapter->setSensorProperties(mGyroBiasVarianceRandomWalkValid,
537                                      mGyroBiasVarianceRandomWalk,
538                                      mAccelRandomWalkValid,
539                                      mAccelRandomWalk,
540                                      mAngleRandomWalkValid,
541                                      mAngleRandomWalk,
542                                      mRateRandomWalkValid,
543                                      mRateRandomWalk,
544                                      mVelocityRandomWalkValid,
545                                      mVelocityRandomWalk);
546    }
547    inline  void locallog() const {
548        LOC_LOGV("Sensor properties validity, Gyro Random walk: %d "
549                 "Accel Random Walk: %d "
550                 "Angle Random Walk: %d Rate Random Walk: %d "
551                 "Velocity Random Walk: %d\n"
552                 "Sensor properties, Gyro Random walk: %f "
553                 "Accel Random Walk: %f "
554                 "Angle Random Walk: %f Rate Random Walk: %f "
555                 "Velocity Random Walk: %f",
556                 mGyroBiasVarianceRandomWalkValid,
557                 mAccelRandomWalkValid,
558                 mAngleRandomWalkValid,
559                 mRateRandomWalkValid,
560                 mVelocityRandomWalkValid,
561                 mGyroBiasVarianceRandomWalk,
562                 mAccelRandomWalk,
563                 mAngleRandomWalk,
564                 mRateRandomWalk,
565                 mVelocityRandomWalk
566            );
567    }
568    inline virtual void log() const {
569        locallog();
570    }
571};
572
573//        case LOC_ENG_MSG_SET_SENSOR_PERF_CONTROL_CONFIG:
574struct LocEngSensorPerfControlConfig : public LocMsg {
575    LocEngAdapter* mAdapter;
576    const int mControlMode;
577    const int mAccelSamplesPerBatch;
578    const int mAccelBatchesPerSec;
579    const int mGyroSamplesPerBatch;
580    const int mGyroBatchesPerSec;
581    const int mAccelSamplesPerBatchHigh;
582    const int mAccelBatchesPerSecHigh;
583    const int mGyroSamplesPerBatchHigh;
584    const int mGyroBatchesPerSecHigh;
585    const int mAlgorithmConfig;
586    inline LocEngSensorPerfControlConfig(LocEngAdapter* adapter,
587                                         int controlMode,
588                                         int accelSamplesPerBatch,
589                                         int accelBatchesPerSec,
590                                         int gyroSamplesPerBatch,
591                                         int gyroBatchesPerSec,
592                                         int accelSamplesPerBatchHigh,
593                                         int accelBatchesPerSecHigh,
594                                         int gyroSamplesPerBatchHigh,
595                                         int gyroBatchesPerSecHigh,
596                                         int algorithmConfig) :
597        LocMsg(), mAdapter(adapter),
598        mControlMode(controlMode),
599        mAccelSamplesPerBatch(accelSamplesPerBatch),
600        mAccelBatchesPerSec(accelBatchesPerSec),
601        mGyroSamplesPerBatch(gyroSamplesPerBatch),
602        mGyroBatchesPerSec(gyroBatchesPerSec),
603        mAccelSamplesPerBatchHigh(accelSamplesPerBatchHigh),
604        mAccelBatchesPerSecHigh(accelBatchesPerSecHigh),
605        mGyroSamplesPerBatchHigh(gyroSamplesPerBatchHigh),
606        mGyroBatchesPerSecHigh(gyroBatchesPerSecHigh),
607        mAlgorithmConfig(algorithmConfig)
608    {
609        locallog();
610    }
611    inline virtual void proc() const {
612        mAdapter->setSensorPerfControlConfig(mControlMode,
613                                             mAccelSamplesPerBatch,
614                                             mAccelBatchesPerSec,
615                                             mGyroSamplesPerBatch,
616                                             mGyroBatchesPerSec,
617                                             mAccelSamplesPerBatchHigh,
618                                             mAccelBatchesPerSecHigh,
619                                             mGyroSamplesPerBatchHigh,
620                                             mGyroBatchesPerSecHigh,
621                                             mAlgorithmConfig);
622    }
623    inline void locallog() const {
624        LOC_LOGV("Sensor Perf Control Config (performanceControlMode)(%u) "
625                 "accel(#smp,#batches) (%u,%u) "
626                 "gyro(#smp,#batches) (%u,%u), "
627                 "accel_high(#smp,#batches) (%u,%u) "
628                 "gyro_high(#smp,#batches) (%u,%u), "
629                 "algorithmConfig(%u)\n",
630                 mControlMode,
631                 mAccelSamplesPerBatch, mAccelBatchesPerSec,
632                 mGyroSamplesPerBatch, mGyroBatchesPerSec,
633                 mAccelSamplesPerBatchHigh, mAccelBatchesPerSecHigh,
634                 mGyroSamplesPerBatchHigh, mGyroBatchesPerSecHigh,
635                 mAlgorithmConfig);
636    }
637    inline virtual void log() const {
638        locallog();
639    }
640};
641
642//        case LOC_ENG_MSG_EXT_POWER_CONFIG:
643struct LocEngExtPowerConfig : public LocMsg {
644    LocEngAdapter* mAdapter;
645    const int mIsBatteryCharging;
646    inline LocEngExtPowerConfig(LocEngAdapter* adapter,
647                                int isBatteryCharging) :
648        LocMsg(), mAdapter(adapter),
649        mIsBatteryCharging(isBatteryCharging)
650    {
651        locallog();
652    }
653    inline virtual void proc() const {
654        mAdapter->setExtPowerConfig(mIsBatteryCharging);
655    }
656    inline void locallog() const {
657        LOC_LOGV("LocEngExtPowerConfig - isBatteryCharging: %d",
658                 mIsBatteryCharging);
659    }
660    inline virtual void log() const {
661        locallog();
662    }
663};
664
665//        case LOC_ENG_MSG_REPORT_POSITION:
666LocEngReportPosition::LocEngReportPosition(LocAdapterBase* adapter,
667                                           UlpLocation &loc,
668                                           GpsLocationExtended &locExtended,
669                                           void* locExt,
670                                           enum loc_sess_status st,
671                                           LocPosTechMask technology) :
672    LocMsg(), mAdapter(adapter), mLocation(loc),
673    mLocationExtended(locExtended),
674    mLocationExt(((loc_eng_data_s_type*)
675                  ((LocEngAdapter*)
676                   (mAdapter))->getOwner())->location_ext_parser(locExt)),
677    mStatus(st), mTechMask(technology)
678{
679    locallog();
680}
681void LocEngReportPosition::proc() const {
682    LocEngAdapter* adapter = (LocEngAdapter*)mAdapter;
683    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)adapter->getOwner();
684
685    if (locEng->mute_session_state != LOC_MUTE_SESS_IN_SESSION) {
686        bool reported = false;
687        if (locEng->location_cb != NULL) {
688            if (LOC_SESS_FAILURE == mStatus) {
689                // in case we want to handle the failure case
690                locEng->location_cb(NULL, NULL);
691                reported = true;
692            }
693            // what's in the else if is... (line by line)
694            // 1. this is a final fix; and
695            //   1.1 it is a Satellite fix; or
696            //   1.2 it is a sensor fix
697            // 2. (must be intermediate fix... implicit)
698            //   2.1 we accepte intermediate; and
699            //   2.2 it is NOT the case that
700            //   2.2.1 there is inaccuracy; and
701            //   2.2.2 we care about inaccuracy; and
702            //   2.2.3 the inaccuracy exceeds our tolerance
703            else if ((LOC_SESS_SUCCESS == mStatus &&
704                      ((LOC_POS_TECH_MASK_SATELLITE |
705                        LOC_POS_TECH_MASK_SENSORS) &
706                       mTechMask)) ||
707                     (LOC_SESS_INTERMEDIATE == locEng->intermediateFix &&
708                      !((mLocation.gpsLocation.flags &
709                         GPS_LOCATION_HAS_ACCURACY) &&
710                        (gps_conf.ACCURACY_THRES != 0) &&
711                        (mLocation.gpsLocation.accuracy >
712                         gps_conf.ACCURACY_THRES)))) {
713                locEng->location_cb((UlpLocation*)&(mLocation),
714                                    (void*)mLocationExt);
715                reported = true;
716            }
717        }
718
719        // if we have reported this fix
720        if (reported &&
721            // and if this is a singleshot
722            GPS_POSITION_RECURRENCE_SINGLE ==
723            locEng->adapter->getPositionMode().recurrence) {
724            if (LOC_SESS_INTERMEDIATE == mStatus) {
725                // modem could be still working for a final fix,
726                // although we no longer need it.  So stopFix().
727                locEng->adapter->stopFix();
728            }
729            // turn off the session flag.
730            locEng->adapter->setInSession(false);
731        }
732
733        if (locEng->generateNmea &&
734            mLocation.position_source == ULP_LOCATION_IS_FROM_GNSS)
735        {
736            unsigned char generate_nmea = reported &&
737                                          (mStatus != LOC_SESS_FAILURE);
738            loc_eng_nmea_generate_pos(locEng, mLocation, mLocationExtended,
739                                      generate_nmea);
740        }
741
742        // Free the allocated memory for rawData
743        UlpLocation* gp = (UlpLocation*)&(mLocation);
744        if (gp != NULL && gp->rawData != NULL)
745        {
746            delete (char*)gp->rawData;
747            gp->rawData = NULL;
748            gp->rawDataSize = 0;
749        }
750    }
751}
752void LocEngReportPosition::locallog() const {
753    LOC_LOGV("flags: %d\n  source: %d\n  latitude: %f\n  longitude: %f\n  "
754             "altitude: %f\n  speed: %f\n  bearing: %f\n  accuracy: %f\n  "
755             "timestamp: %lld\n  rawDataSize: %d\n  rawData: %p\n  Session"
756             " status: %d\n Technology mask: %u",
757             mLocation.gpsLocation.flags, mLocation.position_source,
758             mLocation.gpsLocation.latitude, mLocation.gpsLocation.longitude,
759             mLocation.gpsLocation.altitude, mLocation.gpsLocation.speed,
760             mLocation.gpsLocation.bearing, mLocation.gpsLocation.accuracy,
761             mLocation.gpsLocation.timestamp, mLocation.rawDataSize,
762             mLocation.rawData, mStatus, mTechMask);
763}
764void LocEngReportPosition::log() const {
765    locallog();
766}
767void LocEngReportPosition::send() const {
768    mAdapter->sendMsg(this);
769}
770
771
772//        case LOC_ENG_MSG_REPORT_SV:
773LocEngReportSv::LocEngReportSv(LocAdapterBase* adapter,
774                               GpsSvStatus &sv,
775                               GpsLocationExtended &locExtended,
776                               void* svExt) :
777    LocMsg(), mAdapter(adapter), mSvStatus(sv),
778    mLocationExtended(locExtended),
779    mSvExt(((loc_eng_data_s_type*)
780            ((LocEngAdapter*)
781             (mAdapter))->getOwner())->sv_ext_parser(svExt))
782{
783    locallog();
784}
785void LocEngReportSv::proc() const {
786    LocEngAdapter* adapter = (LocEngAdapter*)mAdapter;
787    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)adapter->getOwner();
788
789    if (locEng->mute_session_state != LOC_MUTE_SESS_IN_SESSION)
790    {
791        if (locEng->sv_status_cb != NULL) {
792            locEng->sv_status_cb((GpsSvStatus*)&(mSvStatus),
793                                 (void*)mSvExt);
794        }
795
796        if (locEng->generateNmea)
797        {
798            loc_eng_nmea_generate_sv(locEng, mSvStatus, mLocationExtended);
799        }
800    }
801}
802void LocEngReportSv::locallog() const {
803    LOC_LOGV("num sv: %d\n  ephemeris mask: %dxn  almanac mask: %x\n  "
804             "used in fix mask: %x\n      sv: prn         snr       "
805             "elevation      azimuth",
806             mSvStatus.num_svs, mSvStatus.ephemeris_mask,
807             mSvStatus.almanac_mask, mSvStatus.used_in_fix_mask);
808    for (int i = 0; i < mSvStatus.num_svs && i < GPS_MAX_SVS; i++) {
809        LOC_LOGV("   %d:   %d    %f    %f    %f\n  ",
810                 i,
811                 mSvStatus.sv_list[i].prn,
812                 mSvStatus.sv_list[i].snr,
813                 mSvStatus.sv_list[i].elevation,
814                 mSvStatus.sv_list[i].azimuth);
815    }
816}
817inline void LocEngReportSv::log() const {
818    locallog();
819}
820void LocEngReportSv::send() const {
821    mAdapter->sendMsg(this);
822}
823
824//        case LOC_ENG_MSG_REPORT_STATUS:
825LocEngReportStatus::LocEngReportStatus(void* locEng,
826                                       GpsStatusValue engineStatus) :
827    LocMsg(),  mLocEng(locEng), mStatus(engineStatus)
828{
829    locallog();
830}
831inline void LocEngReportStatus::proc() const
832{
833    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*) mLocEng;
834
835    loc_eng_report_status(*locEng, mStatus);
836    update_aiding_data_for_deletion(*locEng);
837}
838inline void LocEngReportStatus::locallog() const {
839    LOC_LOGV("LocEngReportStatus");
840}
841inline void LocEngReportStatus::log() const {
842    locallog();
843}
844
845//        case LOC_ENG_MSG_REPORT_NMEA:
846LocEngReportNmea::LocEngReportNmea(void* locEng,
847                                   const char* data, int len) :
848    LocMsg(), mLocEng(locEng), mNmea(new char[len]), mLen(len)
849{
850    memcpy((void*)mNmea, (void*)data, len);
851    locallog();
852}
853void LocEngReportNmea::proc() const {
854    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*) mLocEng;
855
856    struct timeval tv;
857    gettimeofday(&tv, (struct timezone *) NULL);
858    int64_t now = tv.tv_sec * 1000LL + tv.tv_usec / 1000;
859    locEng->nmea_cb(now, mNmea, mLen);
860}
861inline void LocEngReportNmea::locallog() const {
862    LOC_LOGV("LocEngReportNmea");
863}
864inline void LocEngReportNmea::log() const {
865    locallog();
866}
867
868//        case LOC_ENG_MSG_REPORT_XTRA_SERVER:
869LocEngReportXtraServer::LocEngReportXtraServer(void* locEng,
870                                               const char *url1,
871                                               const char *url2,
872                                               const char *url3,
873                                               const int maxlength) :
874    LocMsg(), mLocEng(locEng), mMaxLen(maxlength),
875    mServers(new char[3*(mMaxLen+1)])
876{
877    strlcpy(mServers, url1, mMaxLen);
878    strlcpy(&(mServers[mMaxLen+1]), url2, mMaxLen);
879    strlcpy(&(mServers[(mMaxLen+1)<<1]), url3, mMaxLen);
880    locallog();
881}
882void LocEngReportXtraServer::proc() const {
883    loc_eng_xtra_data_s_type* locEngXtra =
884        &(((loc_eng_data_s_type*)mLocEng)->xtra_module_data);
885
886    if (locEngXtra->report_xtra_server_cb != NULL) {
887        CALLBACK_LOG_CALLFLOW("report_xtra_server_cb", %s, mServers);
888        locEngXtra->report_xtra_server_cb(mServers,
889                                          &(mServers[mMaxLen+1]),
890                                          &(mServers[(mMaxLen+1)<<1]));
891    } else {
892        LOC_LOGE("Callback function for request xtra is NULL");
893    }
894}
895inline void LocEngReportXtraServer::locallog() const {
896    LOC_LOGV("LocEngReportXtraServers: server1: %s\n  server2: %s\n"
897             "  server3: %s\n",
898             mServers, &mServers[mMaxLen], &mServers[mMaxLen<<1]);
899}
900inline void LocEngReportXtraServer::log() const {
901    locallog();
902}
903
904//        case LOC_ENG_MSG_REQUEST_BIT:
905//        case LOC_ENG_MSG_RELEASE_BIT:
906LocEngReqRelBIT::LocEngReqRelBIT(void* locEng, AGpsExtType type,
907                                 int ipv4, char* ipv6, bool isReq) :
908    LocMsg(), mLocEng(locEng), mType(type), mIPv4Addr(ipv4),
909    mIPv6Addr(ipv6 ? new char[16] : NULL), mIsReq(isReq) {
910    if (NULL != ipv6)
911        memcpy(mIPv6Addr, ipv6, 16);
912    locallog();
913}
914inline LocEngReqRelBIT::~LocEngReqRelBIT() {
915    if (mIPv6Addr) {
916        delete[] mIPv6Addr;
917    }
918}
919void LocEngReqRelBIT::proc() const {
920    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
921    BITSubscriber s(getAgpsStateMachine(*locEng, mType),
922                    mIPv4Addr, mIPv6Addr);
923    AgpsStateMachine* sm = (AgpsStateMachine*)s.mStateMachine;
924
925    if (mIsReq) {
926        sm->subscribeRsrc((Subscriber*)&s);
927    } else {
928        sm->unsubscribeRsrc((Subscriber*)&s);
929    }
930}
931inline void LocEngReqRelBIT::locallog() const {
932    LOC_LOGV("LocEngRequestBIT - ipv4: %d.%d.%d.%d, ipv6: %s",
933             (unsigned char)(mIPv4Addr>>24),
934             (unsigned char)(mIPv4Addr>>16),
935             (unsigned char)(mIPv4Addr>>8),
936             (unsigned char)mIPv4Addr,
937             NULL != mIPv6Addr ? mIPv6Addr : "");
938}
939inline void LocEngReqRelBIT::log() const {
940    locallog();
941}
942void LocEngReqRelBIT::send() const {
943    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
944    locEng->adapter->sendMsg(this);
945}
946
947//        case LOC_ENG_MSG_RELEASE_BIT:
948struct LocEngReleaseBIT : public LocMsg {
949    const BITSubscriber mSubscriber;
950    inline LocEngReleaseBIT(const AgpsStateMachine* stateMachine,
951                            unsigned int ipv4, char* ipv6) :
952        LocMsg(),
953        mSubscriber(stateMachine, ipv4, ipv6)
954    {
955        locallog();
956    }
957    inline virtual void proc() const
958    {
959        AgpsStateMachine* sm = (AgpsStateMachine*)mSubscriber.mStateMachine;
960        sm->unsubscribeRsrc((Subscriber*)&mSubscriber);
961    }
962    inline void locallog() const {
963        LOC_LOGV("LocEngReleaseBIT - ipv4: %d.%d.%d.%d, ipv6: %s",
964                 (unsigned char)(mSubscriber.ID>>24),
965                 (unsigned char)(mSubscriber.ID>>16),
966                 (unsigned char)(mSubscriber.ID>>8),
967                 (unsigned char)mSubscriber.ID,
968                 NULL != mSubscriber.mIPv6Addr ? mSubscriber.mIPv6Addr : "");
969    }
970    virtual void log() const {
971        locallog();
972    }
973};
974
975//        LocEngSuplEsOpened
976LocEngSuplEsOpened::LocEngSuplEsOpened(void* locEng) :
977    LocMsg(), mLocEng(locEng) {
978    locallog();
979}
980void LocEngSuplEsOpened::proc() const {
981    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
982    AgpsStateMachine* sm = locEng->ds_nif;
983    sm->onRsrcEvent(RSRC_GRANTED);
984}
985void LocEngSuplEsOpened::locallog() const {
986    LOC_LOGV("LocEngSuplEsOpened");
987}
988void LocEngSuplEsOpened::log() const {
989    locallog();
990}
991
992//        LocEngSuplEsClosed
993LocEngSuplEsClosed::LocEngSuplEsClosed(void* locEng) :
994    LocMsg(), mLocEng(locEng) {
995    locallog();
996}
997void LocEngSuplEsClosed::proc() const {
998    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
999    AgpsStateMachine* sm = locEng->ds_nif;
1000    sm->onRsrcEvent(RSRC_RELEASED);
1001}
1002void LocEngSuplEsClosed::locallog() const {
1003    LOC_LOGV("LocEngSuplEsClosed");
1004}
1005void LocEngSuplEsClosed::log() const {
1006    locallog();
1007}
1008
1009
1010//        case LOC_ENG_MSG_REQUEST_SUPL_ES:
1011LocEngRequestSuplEs::LocEngRequestSuplEs(void* locEng, int id) :
1012    LocMsg(), mLocEng(locEng), mID(id) {
1013    locallog();
1014}
1015void LocEngRequestSuplEs::proc() const {
1016    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1017    AgpsStateMachine* sm = locEng->ds_nif;
1018    DSSubscriber s(sm, mID);
1019    sm->subscribeRsrc((Subscriber*)&s);
1020}
1021inline void LocEngRequestSuplEs::locallog() const {
1022    LOC_LOGV("LocEngRequestSuplEs");
1023}
1024inline void LocEngRequestSuplEs::log() const {
1025    locallog();
1026}
1027
1028//        case LOC_ENG_MSG_REQUEST_ATL:
1029LocEngRequestATL::LocEngRequestATL(void* locEng, int id,
1030                                   AGpsExtType agps_type) :
1031    LocMsg(), mLocEng(locEng), mID(id), mType(agps_type) {
1032    locallog();
1033}
1034void LocEngRequestATL::proc() const {
1035    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1036    AgpsStateMachine* sm = (AgpsStateMachine*)
1037                           getAgpsStateMachine(*locEng, mType);
1038    ATLSubscriber s(mID,
1039                    sm,
1040                    locEng->adapter,
1041                    AGPS_TYPE_INVALID == mType);
1042    sm->subscribeRsrc((Subscriber*)&s);
1043}
1044inline void LocEngRequestATL::locallog() const {
1045    LOC_LOGV("LocEngRequestATL");
1046}
1047inline void LocEngRequestATL::log() const {
1048    locallog();
1049}
1050
1051//        case LOC_ENG_MSG_RELEASE_ATL:
1052LocEngReleaseATL::LocEngReleaseATL(void* locEng, int id) :
1053    LocMsg(), mLocEng(locEng), mID(id) {
1054    locallog();
1055}
1056void LocEngReleaseATL::proc() const {
1057    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1058    ATLSubscriber s1(mID, locEng->agnss_nif, locEng->adapter, false);
1059    if (locEng->agnss_nif->unsubscribeRsrc((Subscriber*)&s1)) {
1060        LOC_LOGD("%s:%d]: Unsubscribed from agnss_nif",
1061                 __func__, __LINE__);
1062    } else {
1063        ATLSubscriber s2(mID, locEng->internet_nif, locEng->adapter, false);
1064        if (locEng->internet_nif->unsubscribeRsrc((Subscriber*)&s2)) {
1065            LOC_LOGD("%s:%d]: Unsubscribed from internet_nif",
1066                     __func__, __LINE__);
1067        } else {
1068            DSSubscriber s3(locEng->ds_nif, mID);
1069            if(locEng->ds_nif->unsubscribeRsrc((Subscriber*)&s3)) {
1070                LOC_LOGD("%s:%d]: Unsubscribed from ds_nif",
1071                         __func__, __LINE__);
1072            } else {
1073                LOC_LOGW("%s:%d]: Could not release ATL. "
1074                         "No subscribers found\n",
1075                         __func__, __LINE__);
1076                locEng->adapter->atlCloseStatus(mID, 0);
1077            }
1078        }
1079    }
1080}
1081inline void LocEngReleaseATL::locallog() const {
1082    LOC_LOGV("LocEngReleaseATL");
1083}
1084inline void LocEngReleaseATL::log() const {
1085    locallog();
1086}
1087
1088//        case LOC_ENG_MSG_REQUEST_WIFI:
1089//        case LOC_ENG_MSG_RELEASE_WIFI:
1090LocEngReqRelWifi::LocEngReqRelWifi(void* locEng, AGpsExtType type,
1091                                   loc_if_req_sender_id_e_type sender_id,
1092                                   char* s, char* p, bool isReq) :
1093    LocMsg(), mLocEng(locEng), mType(type), mSenderId(sender_id),
1094    mSSID(NULL == s ? NULL : new char[SSID_BUF_SIZE]),
1095    mPassword(NULL == p ? NULL : new char[SSID_BUF_SIZE]),
1096    mIsReq(isReq) {
1097    if (NULL != s)
1098        strlcpy(mSSID, s, SSID_BUF_SIZE);
1099    if (NULL != p)
1100        strlcpy(mPassword, p, SSID_BUF_SIZE);
1101    locallog();
1102}
1103LocEngReqRelWifi::~LocEngReqRelWifi() {
1104    if (NULL != mSSID) {
1105        delete[] mSSID;
1106    }
1107    if (NULL != mPassword) {
1108        delete[] mPassword;
1109    }
1110}
1111void LocEngReqRelWifi::proc() const {
1112    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1113    WIFISubscriber s(locEng->wifi_nif, mSSID, mPassword, mSenderId);
1114    if (mIsReq) {
1115        locEng->wifi_nif->subscribeRsrc((Subscriber*)&s);
1116    } else {
1117        locEng->wifi_nif->unsubscribeRsrc((Subscriber*)&s);
1118    }
1119}
1120inline void LocEngReqRelWifi::locallog() const {
1121    LOC_LOGV("%s - senderId: %d, ssid: %s, password: %s",
1122             mIsReq ? "LocEngRequestWifi" : "LocEngReleaseWifi",
1123             mSenderId,
1124             NULL != mSSID ? mSSID : "",
1125             NULL != mPassword ? mPassword : "");
1126}
1127inline void LocEngReqRelWifi::log() const {
1128    locallog();
1129}
1130void LocEngReqRelWifi::send() const {
1131    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1132    locEng->adapter->sendMsg(this);
1133}
1134
1135//        case LOC_ENG_MSG_REQUEST_XTRA_DATA:
1136LocEngRequestXtra::LocEngRequestXtra(void* locEng) :
1137    mLocEng(locEng) {
1138    locallog();
1139}
1140void LocEngRequestXtra::proc() const
1141{
1142    loc_eng_xtra_data_s_type* locEngXtra =
1143        &(((loc_eng_data_s_type*)mLocEng)->xtra_module_data);
1144
1145    if (locEngXtra->download_request_cb != NULL) {
1146        CALLBACK_LOG_CALLFLOW("download_request_cb", %p, mLocEng);
1147        locEngXtra->download_request_cb();
1148    } else {
1149        LOC_LOGE("Callback function for request xtra is NULL");
1150    }
1151}
1152inline void LocEngRequestXtra::locallog() const {
1153    LOC_LOGV("LocEngReqXtra");
1154}
1155inline void LocEngRequestXtra::log() const {
1156    locallog();
1157}
1158
1159//        case LOC_ENG_MSG_REQUEST_TIME:
1160LocEngRequestTime::LocEngRequestTime(void* locEng) :
1161    LocMsg(), mLocEng(locEng)
1162{
1163    locallog();
1164}
1165void LocEngRequestTime::proc() const {
1166    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1167    if (locEng->request_utc_time_cb != NULL) {
1168        locEng->request_utc_time_cb();
1169    } else {
1170        LOC_LOGE("Callback function for request time is NULL");
1171    }
1172}
1173inline void LocEngRequestTime::locallog() const {
1174    LOC_LOGV("LocEngReqTime");
1175}
1176inline void LocEngRequestTime::log() const {
1177    locallog();
1178}
1179
1180//        case LOC_ENG_MSG_DELETE_AIDING_DATA:
1181struct LocEngDelAidData : public LocMsg {
1182    loc_eng_data_s_type* mLocEng;
1183    const GpsAidingData mType;
1184    inline LocEngDelAidData(loc_eng_data_s_type* locEng,
1185                            GpsAidingData f) :
1186        LocMsg(), mLocEng(locEng), mType(f)
1187    {
1188        locallog();
1189    }
1190    inline virtual void proc() const {
1191        mLocEng->aiding_data_for_deletion = mType;
1192        update_aiding_data_for_deletion(*mLocEng);
1193    }
1194    inline void locallog() const {
1195        LOC_LOGV("aiding data msak %d", mType);
1196    }
1197    virtual void log() const {
1198        locallog();
1199    }
1200};
1201
1202//        case LOC_ENG_MSG_ENABLE_DATA:
1203struct LocEngEnableData : public LocMsg {
1204    LocEngAdapter* mAdapter;
1205    const int mEnable;
1206    char* mAPN;
1207    const int mLen;
1208    inline LocEngEnableData(LocEngAdapter* adapter,
1209                            const char* name, int len, int enable) :
1210        LocMsg(), mAdapter(adapter),
1211        mEnable(enable), mAPN(NULL), mLen(len)
1212    {
1213        if (NULL != name) {
1214            mAPN = new char[len+1];
1215            memcpy((void*)mAPN, (void*)name, len);
1216            mAPN[len] = 0;
1217        }
1218        locallog();
1219    }
1220    inline ~LocEngEnableData() {
1221        if (NULL != mAPN) {
1222            delete[] mAPN;
1223        }
1224    }
1225    inline virtual void proc() const {
1226        mAdapter->enableData(mEnable);
1227        if (NULL != mAPN) {
1228            mAdapter->setAPN(mAPN, mLen);
1229        }
1230    }
1231    inline void locallog() const {
1232        LOC_LOGV("apn: %s\n  enable: %d",
1233                 (NULL == mAPN) ? "NULL" : mAPN, mEnable);
1234    }
1235    inline virtual void log() const {
1236        locallog();
1237    }
1238};
1239
1240//        case LOC_ENG_MSG_INJECT_XTRA_DATA:
1241// loc_eng_xtra.cpp
1242
1243//        case LOC_ENG_MSG_LOC_INIT:
1244struct LocEngInit : public LocMsg {
1245    loc_eng_data_s_type* mLocEng;
1246    inline LocEngInit(loc_eng_data_s_type* locEng) :
1247        LocMsg(), mLocEng(locEng)
1248    {
1249        locallog();
1250    }
1251    inline virtual void proc() const {
1252        loc_eng_reinit(*mLocEng);
1253    }
1254    inline void locallog() const
1255    {
1256        LOC_LOGV("LocEngInit");
1257    }
1258    inline virtual void log() const
1259    {
1260        locallog();
1261    }
1262};
1263
1264//        case LOC_ENG_MSG_REQUEST_XTRA_SERVER:
1265// loc_eng_xtra.cpp
1266
1267//        case LOC_ENG_MSG_ATL_OPEN_SUCCESS:
1268struct LocEngAtlOpenSuccess : public LocMsg {
1269    AgpsStateMachine* mStateMachine;
1270    const int mLen;
1271    char* mAPN;
1272    const AGpsBearerType mBearerType;
1273    inline LocEngAtlOpenSuccess(AgpsStateMachine* statemachine,
1274                                const char* name,
1275                                int len,
1276                                AGpsBearerType btype) :
1277        LocMsg(),
1278        mStateMachine(statemachine), mLen(len),
1279        mAPN(new char[len+1]), mBearerType(btype)
1280    {
1281        memcpy((void*)mAPN, (void*)name, len);
1282        mAPN[len] = 0;
1283        locallog();
1284    }
1285    inline ~LocEngAtlOpenSuccess()
1286    {
1287        delete[] mAPN;
1288    }
1289    inline virtual void proc() const {
1290        mStateMachine->setBearer(mBearerType);
1291        mStateMachine->setAPN(mAPN, mLen);
1292        mStateMachine->onRsrcEvent(RSRC_GRANTED);
1293    }
1294    inline void locallog() const {
1295        LOC_LOGV("LocEngAtlClosed agps type: %s\n  apn: %s\n"
1296                 "  bearer type: %s",
1297                 loc_get_agps_type_name(mStateMachine->getType()),
1298                 mAPN,
1299                 loc_get_agps_bear_name(mBearerType));
1300    }
1301    inline virtual void log() const {
1302        locallog();
1303    }
1304};
1305
1306//        case LOC_ENG_MSG_ATL_CLOSED:
1307struct LocEngAtlClosed : public LocMsg {
1308    AgpsStateMachine* mStateMachine;
1309    inline LocEngAtlClosed(AgpsStateMachine* statemachine) :
1310        LocMsg(), mStateMachine(statemachine) {
1311        locallog();
1312    }
1313    inline virtual void proc() const {
1314        mStateMachine->onRsrcEvent(RSRC_RELEASED);
1315    }
1316    inline void locallog() const {
1317        LOC_LOGV("LocEngAtlClosed");
1318    }
1319    inline virtual void log() const {
1320        locallog();
1321    }
1322};
1323
1324//        case LOC_ENG_MSG_ATL_OPEN_FAILED:
1325struct LocEngAtlOpenFailed : public LocMsg {
1326    AgpsStateMachine* mStateMachine;
1327    inline LocEngAtlOpenFailed(AgpsStateMachine* statemachine) :
1328        LocMsg(), mStateMachine(statemachine) {
1329        locallog();
1330    }
1331    inline virtual void proc() const {
1332        mStateMachine->onRsrcEvent(RSRC_DENIED);
1333    }
1334    inline void locallog() const {
1335        LOC_LOGV("LocEngAtlOpenFailed");
1336    }
1337    inline virtual void log() const {
1338        locallog();
1339    }
1340};
1341
1342//        case LOC_ENG_MSG_ENGINE_DOWN:
1343LocEngDown::LocEngDown(void* locEng) :
1344    LocMsg(), mLocEng(locEng) {
1345    locallog();
1346}
1347inline void LocEngDown::proc() const {
1348    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1349    loc_eng_handle_engine_down(*locEng);
1350}
1351inline void LocEngDown::locallog() const {
1352    LOC_LOGV("LocEngDown");
1353}
1354inline void LocEngDown::log() const {
1355    locallog();
1356}
1357
1358//        case LOC_ENG_MSG_ENGINE_UP:
1359LocEngUp::LocEngUp(void* locEng) :
1360    LocMsg(), mLocEng(locEng) {
1361    locallog();
1362}
1363inline void LocEngUp::proc() const {
1364    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1365    loc_eng_handle_engine_up(*locEng);
1366}
1367inline void LocEngUp::locallog() const {
1368    LOC_LOGV("LocEngUp");
1369}
1370inline void LocEngUp::log() const {
1371    locallog();
1372}
1373
1374/*********************************************************************
1375 * Initialization checking macros
1376 *********************************************************************/
1377#define STATE_CHECK(ctx, x, ret) \
1378    if (!(ctx))                  \
1379  {                              \
1380      /* Not intialized, abort */\
1381      LOC_LOGE("%s: log_eng state error: %s", __func__, x); \
1382      EXIT_LOG(%s, x);                                            \
1383      ret;                                                        \
1384  }
1385#define INIT_CHECK(ctx, ret) STATE_CHECK(ctx, "instance not initialized", ret)
1386
1387/*===========================================================================
1388FUNCTION    loc_eng_init
1389
1390DESCRIPTION
1391   Initialize the location engine, this include setting up global datas
1392   and registers location engien with loc api service.
1393
1394DEPENDENCIES
1395   None
1396
1397RETURN VALUE
1398   0: success
1399
1400SIDE EFFECTS
1401   N/A
1402
1403===========================================================================*/
1404int loc_eng_init(loc_eng_data_s_type &loc_eng_data, LocCallbacks* callbacks,
1405                 LOC_API_ADAPTER_EVENT_MASK_T event)
1406
1407{
1408    int ret_val = 0;
1409
1410    ENTRY_LOG_CALLFLOW();
1411    if (NULL == callbacks || 0 == event) {
1412        LOC_LOGE("loc_eng_init: bad parameters cb %p eMask %d", callbacks, event);
1413        ret_val = -1;
1414        EXIT_LOG(%d, ret_val);
1415        return ret_val;
1416    }
1417
1418    STATE_CHECK((NULL == loc_eng_data.adapter),
1419                "instance already initialized", return 0);
1420
1421    memset(&loc_eng_data, 0, sizeof (loc_eng_data));
1422
1423    if (NULL != callbacks->set_capabilities_cb) {
1424        callbacks->set_capabilities_cb(gps_conf.CAPABILITIES);
1425    }
1426
1427    // Save callbacks
1428    loc_eng_data.location_cb  = callbacks->location_cb;
1429    loc_eng_data.sv_status_cb = callbacks->sv_status_cb;
1430    loc_eng_data.status_cb    = callbacks->status_cb;
1431    loc_eng_data.nmea_cb      = callbacks->nmea_cb;
1432    loc_eng_data.acquire_wakelock_cb = callbacks->acquire_wakelock_cb;
1433    loc_eng_data.release_wakelock_cb = callbacks->release_wakelock_cb;
1434    loc_eng_data.request_utc_time_cb = callbacks->request_utc_time_cb;
1435    loc_eng_data.location_ext_parser = callbacks->location_ext_parser ?
1436        callbacks->location_ext_parser : noProc;
1437    loc_eng_data.sv_ext_parser = callbacks->sv_ext_parser ?
1438        callbacks->sv_ext_parser : noProc;
1439    loc_eng_data.intermediateFix = gps_conf.INTERMEDIATE_POS;
1440
1441    // initial states taken care of by the memset above
1442    // loc_eng_data.engine_status -- GPS_STATUS_NONE;
1443    // loc_eng_data.fix_session_status -- GPS_STATUS_NONE;
1444    // loc_eng_data.mute_session_state -- LOC_MUTE_SESS_NONE;
1445
1446    if ((event & LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT) && (gps_conf.NMEA_PROVIDER == NMEA_PROVIDER_AP))
1447    {
1448        event = event ^ LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT; // unregister for modem NMEA report
1449        loc_eng_data.generateNmea = true;
1450    }
1451    else
1452    {
1453        loc_eng_data.generateNmea = false;
1454    }
1455
1456    //Disable AGPS if capabilities are not present
1457    if(!(gps_conf.CAPABILITIES & GPS_CAPABILITY_MSA) &&
1458       !(gps_conf.CAPABILITIES & GPS_CAPABILITY_MSB)) {
1459        event &= ~(LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST |
1460                   LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST);
1461    }
1462
1463    loc_eng_data.adapter =
1464        new LocEngAdapter(event, &loc_eng_data,
1465                          (MsgTask::tCreate)callbacks->create_thread_cb);
1466
1467    LOC_LOGD("loc_eng_init created client, id = %p\n",
1468             loc_eng_data.adapter);
1469
1470    loc_eng_data.adapter->sendMsg(new LocEngInit(&loc_eng_data));
1471
1472    EXIT_LOG(%d, ret_val);
1473    return ret_val;
1474}
1475
1476static int loc_eng_reinit(loc_eng_data_s_type &loc_eng_data)
1477{
1478    ENTRY_LOG();
1479    int ret_val = LOC_API_ADAPTER_ERR_SUCCESS;
1480
1481    if (LOC_API_ADAPTER_ERR_SUCCESS == ret_val) {
1482        LOC_LOGD("loc_eng_reinit reinit() successful");
1483
1484        LocEngAdapter* adapter = loc_eng_data.adapter;
1485        adapter->sendMsg(new LocEngSuplVer(adapter, gps_conf.SUPL_VER));
1486        adapter->sendMsg(new LocEngLppConfig(adapter, gps_conf.LPP_PROFILE));
1487        adapter->sendMsg(new LocEngSensorControlConfig(adapter, sap_conf.SENSOR_USAGE));
1488        adapter->sendMsg(new LocEngAGlonassProtocol(adapter, gps_conf.A_GLONASS_POS_PROTOCOL_SELECT));
1489
1490        /* Make sure at least one of the sensor property is specified by the user in the gps.conf file. */
1491        if( sap_conf.GYRO_BIAS_RANDOM_WALK_VALID ||
1492            sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
1493            sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
1494            sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
1495            sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID )
1496        {
1497            adapter->sendMsg(new LocEngSensorProperties(adapter,
1498                                                        sap_conf.GYRO_BIAS_RANDOM_WALK_VALID,
1499                                                        sap_conf.GYRO_BIAS_RANDOM_WALK,
1500                                                        sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
1501                                                        sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY,
1502                                                        sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
1503                                                        sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY,
1504                                                        sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
1505                                                        sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY,
1506                                                        sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
1507                                                        sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY));
1508        }
1509
1510        adapter->sendMsg(new LocEngSensorPerfControlConfig(adapter,
1511                                                           sap_conf.SENSOR_CONTROL_MODE,
1512                                                           sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH,
1513                                                           sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC,
1514                                                           sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH,
1515                                                           sap_conf.SENSOR_GYRO_BATCHES_PER_SEC,
1516                                                           sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH,
1517                                                           sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH,
1518                                                           sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH,
1519                                                           sap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH,
1520                                                           sap_conf.SENSOR_ALGORITHM_CONFIG_MASK));
1521
1522        adapter->sendMsg(new LocEngEnableData(adapter, NULL, 0, (agpsStatus ? 1:0)));
1523    }
1524
1525    EXIT_LOG(%d, ret_val);
1526    return ret_val;
1527}
1528
1529/*===========================================================================
1530FUNCTION    loc_eng_cleanup
1531
1532DESCRIPTION
1533   Cleans location engine. The location client handle will be released.
1534
1535DEPENDENCIES
1536   None
1537
1538RETURN VALUE
1539   None
1540
1541SIDE EFFECTS
1542   N/A
1543
1544===========================================================================*/
1545void loc_eng_cleanup(loc_eng_data_s_type &loc_eng_data)
1546{
1547    ENTRY_LOG_CALLFLOW();
1548    INIT_CHECK(loc_eng_data.adapter, return);
1549
1550    // XTRA has no state, so we are fine with it.
1551
1552    // we need to check and clear NI
1553#if 0
1554    // we need to check and clear ATL
1555    if (NULL != loc_eng_data.agnss_nif) {
1556        delete loc_eng_data.agnss_nif;
1557        loc_eng_data.agnss_nif = NULL;
1558    }
1559    if (NULL != loc_eng_data.internet_nif) {
1560        delete loc_eng_data.internet_nif;
1561        loc_eng_data.internet_nif = NULL;
1562    }
1563#endif
1564    if (loc_eng_data.adapter->isInSession())
1565    {
1566        LOC_LOGD("loc_eng_cleanup: fix not stopped. stop it now.");
1567        loc_eng_stop(loc_eng_data);
1568    }
1569
1570#if 0 // can't afford to actually clean up, for many reason.
1571
1572    LOC_LOGD("loc_eng_init: client opened. close it now.");
1573    delete loc_eng_data.adapter;
1574    loc_eng_data.adapter = NULL;
1575
1576    loc_eng_dmn_conn_loc_api_server_unblock();
1577    loc_eng_dmn_conn_loc_api_server_join();
1578
1579#endif
1580
1581    EXIT_LOG(%s, VOID_RET);
1582}
1583
1584
1585/*===========================================================================
1586FUNCTION    loc_eng_start
1587
1588DESCRIPTION
1589   Starts the tracking session
1590
1591DEPENDENCIES
1592   None
1593
1594RETURN VALUE
1595   0: success
1596
1597SIDE EFFECTS
1598   N/A
1599
1600===========================================================================*/
1601int loc_eng_start(loc_eng_data_s_type &loc_eng_data)
1602{
1603   ENTRY_LOG_CALLFLOW();
1604   INIT_CHECK(loc_eng_data.adapter, return -1);
1605
1606   if(! loc_eng_data.adapter->getUlpProxy()->sendStartFix())
1607   {
1608       loc_eng_data.adapter->sendMsg(new LocEngStartFix(loc_eng_data.adapter));
1609   }
1610
1611   EXIT_LOG(%d, 0);
1612   return 0;
1613}
1614
1615static int loc_eng_start_handler(loc_eng_data_s_type &loc_eng_data)
1616{
1617   ENTRY_LOG();
1618   int ret_val = LOC_API_ADAPTER_ERR_SUCCESS;
1619
1620   if (!loc_eng_data.adapter->isInSession()) {
1621       ret_val = loc_eng_data.adapter->startFix();
1622
1623       if (ret_val == LOC_API_ADAPTER_ERR_SUCCESS ||
1624           ret_val == LOC_API_ADAPTER_ERR_ENGINE_DOWN)
1625       {
1626           loc_eng_data.adapter->setInSession(TRUE);
1627           loc_inform_gps_status(loc_eng_data, GPS_STATUS_SESSION_BEGIN);
1628       }
1629   }
1630
1631   EXIT_LOG(%d, ret_val);
1632   return ret_val;
1633}
1634
1635/*===========================================================================
1636FUNCTION    loc_eng_stop_wrapper
1637
1638DESCRIPTION
1639   Stops the tracking session
1640
1641DEPENDENCIES
1642   None
1643
1644RETURN VALUE
1645   0: success
1646
1647SIDE EFFECTS
1648   N/A
1649
1650===========================================================================*/
1651int loc_eng_stop(loc_eng_data_s_type &loc_eng_data)
1652{
1653    ENTRY_LOG_CALLFLOW();
1654    INIT_CHECK(loc_eng_data.adapter, return -1);
1655
1656    if(! loc_eng_data.adapter->getUlpProxy()->sendStopFix())
1657    {
1658        loc_eng_data.adapter->sendMsg(new LocEngStopFix(loc_eng_data.adapter));
1659    }
1660
1661    EXIT_LOG(%d, 0);
1662    return 0;
1663}
1664
1665static int loc_eng_stop_handler(loc_eng_data_s_type &loc_eng_data)
1666{
1667   ENTRY_LOG();
1668   int ret_val = LOC_API_ADAPTER_ERR_SUCCESS;
1669
1670   if (loc_eng_data.adapter->isInSession()) {
1671
1672       ret_val = loc_eng_data.adapter->stopFix();
1673       if (ret_val == LOC_API_ADAPTER_ERR_SUCCESS)
1674       {
1675           loc_inform_gps_status(loc_eng_data, GPS_STATUS_SESSION_END);
1676       }
1677
1678       loc_eng_data.adapter->setInSession(FALSE);
1679   }
1680
1681    EXIT_LOG(%d, ret_val);
1682    return ret_val;
1683}
1684
1685/*===========================================================================
1686FUNCTION    loc_eng_mute_one_session
1687
1688DESCRIPTION
1689   Mutes one session
1690
1691DEPENDENCIES
1692   None
1693
1694RETURN VALUE
1695   0: Success
1696
1697SIDE EFFECTS
1698   N/A
1699
1700===========================================================================*/
1701void loc_eng_mute_one_session(loc_eng_data_s_type &loc_eng_data)
1702{
1703    ENTRY_LOG();
1704    loc_eng_data.mute_session_state = LOC_MUTE_SESS_WAIT;
1705    EXIT_LOG(%s, VOID_RET);
1706}
1707
1708/*===========================================================================
1709FUNCTION    loc_eng_set_position_mode
1710
1711DESCRIPTION
1712   Sets the mode and fix frequency for the tracking session.
1713
1714DEPENDENCIES
1715   None
1716
1717RETURN VALUE
1718   0: success
1719
1720SIDE EFFECTS
1721   N/A
1722
1723===========================================================================*/
1724int loc_eng_set_position_mode(loc_eng_data_s_type &loc_eng_data,
1725                              LocPosMode &params)
1726{
1727    ENTRY_LOG_CALLFLOW();
1728    INIT_CHECK(loc_eng_data.adapter, return -1);
1729
1730    if(! loc_eng_data.adapter->getUlpProxy()->sendFixMode(params))
1731    {
1732        LocEngAdapter* adapter = loc_eng_data.adapter;
1733        adapter->sendMsg(new LocEngPositionMode(adapter, params));
1734    }
1735
1736    EXIT_LOG(%d, 0);
1737    return 0;
1738}
1739
1740/*===========================================================================
1741FUNCTION    loc_eng_inject_time
1742
1743DESCRIPTION
1744   This is used by Java native function to do time injection.
1745
1746DEPENDENCIES
1747   None
1748
1749RETURN VALUE
1750   0
1751
1752SIDE EFFECTS
1753   N/A
1754
1755===========================================================================*/
1756int loc_eng_inject_time(loc_eng_data_s_type &loc_eng_data, GpsUtcTime time,
1757                        int64_t timeReference, int uncertainty)
1758{
1759    ENTRY_LOG_CALLFLOW();
1760    INIT_CHECK(loc_eng_data.adapter, return -1);
1761    LocEngAdapter* adapter = loc_eng_data.adapter;
1762    if (adapter->mAgpsEnabled) {
1763        adapter->sendMsg(new LocEngSetTime(adapter, time, timeReference,
1764                                           uncertainty));
1765    }
1766    EXIT_LOG(%d, 0);
1767    return 0;
1768}
1769
1770
1771/*===========================================================================
1772FUNCTION    loc_eng_inject_location
1773
1774DESCRIPTION
1775   This is used by Java native function to do location injection.
1776
1777DEPENDENCIES
1778   None
1779
1780RETURN VALUE
1781   0          : Successful
1782   error code : Failure
1783
1784SIDE EFFECTS
1785   N/A
1786===========================================================================*/
1787int loc_eng_inject_location(loc_eng_data_s_type &loc_eng_data, double latitude,
1788                            double longitude, float accuracy)
1789{
1790    ENTRY_LOG_CALLFLOW();
1791    INIT_CHECK(loc_eng_data.adapter, return -1);
1792    LocEngAdapter* adapter = loc_eng_data.adapter;
1793    adapter->sendMsg(new LocEngInjectLocation(adapter, latitude, longitude,
1794                                              accuracy));
1795
1796    EXIT_LOG(%d, 0);
1797    return 0;
1798}
1799
1800
1801/*===========================================================================
1802FUNCTION    loc_eng_delete_aiding_data
1803
1804DESCRIPTION
1805   This is used by Java native function to delete the aiding data. The function
1806   updates the global variable for the aiding data to be deleted. If the GPS
1807   engine is off, the aiding data will be deleted. Otherwise, the actual action
1808   will happen when gps engine is turned off.
1809
1810DEPENDENCIES
1811   Assumes the aiding data type specified in GpsAidingData matches with
1812   LOC API specification.
1813
1814RETURN VALUE
1815   None
1816
1817SIDE EFFECTS
1818   N/A
1819
1820===========================================================================*/
1821void loc_eng_delete_aiding_data(loc_eng_data_s_type &loc_eng_data, GpsAidingData f)
1822{
1823    ENTRY_LOG_CALLFLOW();
1824    INIT_CHECK(loc_eng_data.adapter, return);
1825
1826    loc_eng_data.adapter->sendMsg(new LocEngDelAidData(&loc_eng_data, f));
1827
1828    EXIT_LOG(%s, VOID_RET);
1829}
1830
1831/*===========================================================================
1832
1833FUNCTION    loc_inform_gps_state
1834
1835DESCRIPTION
1836   Informs the GPS Provider about the GPS status
1837
1838DEPENDENCIES
1839   None
1840
1841RETURN VALUE
1842   None
1843
1844SIDE EFFECTS
1845   N/A
1846
1847===========================================================================*/
1848static void loc_inform_gps_status(loc_eng_data_s_type &loc_eng_data, GpsStatusValue status)
1849{
1850    ENTRY_LOG();
1851
1852    if (loc_eng_data.status_cb)
1853    {
1854        GpsStatus gs = { sizeof(gs),status };
1855        CALLBACK_LOG_CALLFLOW("status_cb", %s,
1856                              loc_get_gps_status_name(gs.status));
1857        loc_eng_data.status_cb(&gs);
1858    }
1859
1860    EXIT_LOG(%s, VOID_RET);
1861}
1862
1863/*
1864  Callback function passed to Data Services State Machine
1865  This becomes part of the state machine's servicer and
1866  is used to send requests to the data services client
1867*/
1868static int dataCallCb(void *cb_data)
1869{
1870    LOC_LOGD("Enter dataCallCb\n");
1871    int ret=0;
1872    if(cb_data != NULL) {
1873        dsCbData *cbData = (dsCbData *)cb_data;
1874        LocEngAdapter *locAdapter = (LocEngAdapter *)cbData->mAdapter;
1875        if(cbData->action == GPS_REQUEST_AGPS_DATA_CONN) {
1876            LOC_LOGD("dataCallCb GPS_REQUEST_AGPS_DATA_CONN\n");
1877            ret =  locAdapter->openAndStartDataCall();
1878        }
1879        else if(cbData->action == GPS_RELEASE_AGPS_DATA_CONN) {
1880            LOC_LOGD("dataCallCb GPS_RELEASE_AGPS_DATA_CONN\n");
1881            locAdapter->stopDataCall();
1882        }
1883    }
1884    else {
1885        LOC_LOGE("NULL argument received. Failing.\n");
1886        ret = -1;
1887        goto err;
1888    }
1889
1890err:
1891    LOC_LOGD("Exit dataCallCb ret = %d\n", ret);
1892    return ret;
1893}
1894
1895/*===========================================================================
1896FUNCTION    loc_eng_agps_reinit
1897
1898DESCRIPTION
1899   2nd half of loc_eng_agps_init(), singled out for modem restart to use.
1900
1901DEPENDENCIES
1902   NONE
1903
1904RETURN VALUE
1905   0
1906
1907SIDE EFFECTS
1908   N/A
1909
1910===========================================================================*/
1911static void loc_eng_agps_reinit(loc_eng_data_s_type &loc_eng_data)
1912{
1913    ENTRY_LOG();
1914
1915    // Set server addresses which came before init
1916    if (loc_eng_data.supl_host_set)
1917    {
1918        loc_eng_set_server(loc_eng_data, LOC_AGPS_SUPL_SERVER,
1919                           loc_eng_data.supl_host_buf,
1920                           loc_eng_data.supl_port_buf);
1921    }
1922
1923    if (loc_eng_data.c2k_host_set)
1924    {
1925        loc_eng_set_server(loc_eng_data, LOC_AGPS_CDMA_PDE_SERVER,
1926                           loc_eng_data.c2k_host_buf,
1927                           loc_eng_data.c2k_port_buf);
1928    }
1929    EXIT_LOG(%s, VOID_RET);
1930}
1931/*===========================================================================
1932FUNCTION    loc_eng_agps_init
1933
1934DESCRIPTION
1935   Initialize the AGps interface.
1936
1937DEPENDENCIES
1938   NONE
1939
1940RETURN VALUE
1941   0
1942
1943SIDE EFFECTS
1944   N/A
1945
1946===========================================================================*/
1947void loc_eng_agps_init(loc_eng_data_s_type &loc_eng_data, AGpsExtCallbacks* callbacks)
1948{
1949    ENTRY_LOG_CALLFLOW();
1950    INIT_CHECK(loc_eng_data.adapter, return);
1951    STATE_CHECK((NULL == loc_eng_data.agps_status_cb),
1952                "agps instance already initialized",
1953                return);
1954    if(callbacks == NULL) {
1955        LOC_LOGE("loc_eng_agps_init: bad parameters cb %p", callbacks);
1956        EXIT_LOG(%s, VOID_RET);
1957        return;
1958    }
1959
1960    //Proceed to create AGPS framework only if MSA or MSB capabilities
1961    //are present. If the target is an APQ, these masks are
1962    //cleared in get_gps_interface()
1963    if(!(gps_conf.CAPABILITIES & GPS_CAPABILITY_MSA) &&
1964       !(gps_conf.CAPABILITIES & GPS_CAPABILITY_MSB) ) {
1965        LOC_LOGD("%s:%d]: No AGPS capabilities found. Returning\n",
1966                 __func__, __LINE__);
1967        return;
1968    }
1969
1970    loc_eng_data.agps_status_cb = callbacks->status_cb;
1971
1972    loc_eng_data.agnss_nif = new AgpsStateMachine(servicerTypeAgps,
1973                                                  (void *)loc_eng_data.agps_status_cb,
1974                                                  AGPS_TYPE_SUPL,
1975                                                  false);
1976    loc_eng_data.internet_nif = new AgpsStateMachine(servicerTypeAgps,
1977                                                     (void *)loc_eng_data.agps_status_cb,
1978                                                     AGPS_TYPE_WWAN_ANY,
1979                                                     false);
1980    loc_eng_data.wifi_nif = new AgpsStateMachine(servicerTypeAgps,
1981                                                 (void *)loc_eng_data.agps_status_cb,
1982                                                 AGPS_TYPE_WIFI,
1983                                                 true);
1984    if(!loc_eng_data.adapter->initDataServiceClient()) {
1985        LOC_LOGD("%s:%d]: Creating new ds state machine\n", __func__, __LINE__);
1986        loc_eng_data.ds_nif = new DSStateMachine(servicerTypeExt,
1987                                                 (void *)dataCallCb,
1988                                                 loc_eng_data.adapter);
1989        LOC_LOGD("%s:%d]: Created new ds state machine\n", __func__, __LINE__);
1990    }
1991
1992    //loc_eng_dmn_conn_loc_api_server_launch(callbacks->create_thread_cb,
1993    //                                               NULL, NULL, &loc_eng_data);
1994
1995    loc_eng_agps_reinit(loc_eng_data);
1996    EXIT_LOG(%s, VOID_RET);
1997}
1998
1999static void deleteAidingData(loc_eng_data_s_type &logEng) {
2000    if (logEng.engine_status != GPS_STATUS_ENGINE_ON &&
2001        logEng.aiding_data_for_deletion != 0) {
2002        logEng.adapter->deleteAidingData(logEng.aiding_data_for_deletion);
2003        logEng.aiding_data_for_deletion = 0;
2004    }
2005}
2006
2007static AgpsStateMachine*
2008getAgpsStateMachine(loc_eng_data_s_type &locEng, AGpsExtType agpsType) {
2009    AgpsStateMachine* stateMachine;
2010    switch (agpsType) {
2011    case AGPS_TYPE_WIFI: {
2012        stateMachine = locEng.wifi_nif;
2013        break;
2014    }
2015    case AGPS_TYPE_INVALID:
2016    case AGPS_TYPE_SUPL: {
2017        stateMachine = locEng.agnss_nif;
2018        break;
2019    }
2020    case AGPS_TYPE_SUPL_ES: {
2021        stateMachine = locEng.ds_nif;
2022        break;
2023    }
2024    default:
2025        stateMachine  = locEng.internet_nif;
2026    }
2027    return stateMachine;
2028}
2029
2030/*===========================================================================
2031FUNCTION    loc_eng_agps_open
2032
2033DESCRIPTION
2034   This function is called when on-demand data connection opening is successful.
2035It should inform engine about the data open result.
2036
2037DEPENDENCIES
2038   NONE
2039
2040RETURN VALUE
2041   0
2042
2043SIDE EFFECTS
2044   N/A
2045
2046===========================================================================*/
2047int loc_eng_agps_open(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType,
2048                     const char* apn, AGpsBearerType bearerType)
2049{
2050    ENTRY_LOG_CALLFLOW();
2051    INIT_CHECK(loc_eng_data.adapter && loc_eng_data.agps_status_cb,
2052               return -1);
2053
2054    if (apn == NULL)
2055    {
2056        LOC_LOGE("APN Name NULL\n");
2057        return 0;
2058    }
2059
2060    LOC_LOGD("loc_eng_agps_open APN name = [%s]", apn);
2061
2062    int apn_len = smaller_of(strlen (apn), MAX_APN_LEN);
2063    AgpsStateMachine* sm = getAgpsStateMachine(loc_eng_data, agpsType);
2064
2065    loc_eng_data.adapter->sendMsg(
2066        new LocEngAtlOpenSuccess(sm, apn, apn_len, bearerType));
2067
2068    EXIT_LOG(%d, 0);
2069    return 0;
2070}
2071
2072/*===========================================================================
2073FUNCTION    loc_eng_agps_closed
2074
2075DESCRIPTION
2076   This function is called when on-demand data connection closing is done.
2077It should inform engine about the data close result.
2078
2079DEPENDENCIES
2080   NONE
2081
2082RETURN VALUE
2083   0
2084
2085SIDE EFFECTS
2086   N/A
2087
2088===========================================================================*/
2089int loc_eng_agps_closed(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType)
2090{
2091    ENTRY_LOG_CALLFLOW();
2092    INIT_CHECK(loc_eng_data.adapter && loc_eng_data.agps_status_cb,
2093               return -1);
2094
2095    AgpsStateMachine* sm = getAgpsStateMachine(loc_eng_data, agpsType);
2096    loc_eng_data.adapter->sendMsg(new LocEngAtlClosed(sm));
2097
2098    EXIT_LOG(%d, 0);
2099    return 0;
2100}
2101
2102/*===========================================================================
2103FUNCTION    loc_eng_agps_open_failed
2104
2105DESCRIPTION
2106   This function is called when on-demand data connection opening has failed.
2107It should inform engine about the data open result.
2108
2109DEPENDENCIES
2110   NONE
2111
2112RETURN VALUE
2113   0
2114
2115SIDE EFFECTS
2116   N/A
2117
2118===========================================================================*/
2119int loc_eng_agps_open_failed(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType)
2120{
2121    ENTRY_LOG_CALLFLOW();
2122    INIT_CHECK(loc_eng_data.adapter && loc_eng_data.agps_status_cb,
2123               return -1);
2124
2125    AgpsStateMachine* sm = getAgpsStateMachine(loc_eng_data, agpsType);
2126    loc_eng_data.adapter->sendMsg(new LocEngAtlOpenFailed(sm));
2127
2128    EXIT_LOG(%d, 0);
2129    return 0;
2130}
2131
2132/*===========================================================================
2133
2134FUNCTION resolve_in_addr
2135
2136DESCRIPTION
2137   Translates a hostname to in_addr struct
2138
2139DEPENDENCIES
2140   n/a
2141
2142RETURN VALUE
2143   TRUE if successful
2144
2145SIDE EFFECTS
2146   n/a
2147
2148===========================================================================*/
2149static boolean resolve_in_addr(const char *host_addr, struct in_addr *in_addr_ptr)
2150{
2151    ENTRY_LOG();
2152    boolean ret_val = TRUE;
2153
2154    struct hostent             *hp;
2155    hp = gethostbyname(host_addr);
2156    if (hp != NULL) /* DNS OK */
2157    {
2158        memcpy(in_addr_ptr, hp->h_addr_list[0], hp->h_length);
2159    }
2160    else
2161    {
2162        /* Try IP representation */
2163        if (inet_aton(host_addr, in_addr_ptr) == 0)
2164        {
2165            /* IP not valid */
2166            LOC_LOGE("DNS query on '%s' failed\n", host_addr);
2167            ret_val = FALSE;
2168        }
2169    }
2170
2171    EXIT_LOG(%s, loc_logger_boolStr[ret_val!=0]);
2172    return ret_val;
2173}
2174
2175/*===========================================================================
2176FUNCTION    loc_eng_set_server
2177
2178DESCRIPTION
2179   This is used to set the default AGPS server. Server address is obtained
2180   from gps.conf.
2181
2182DEPENDENCIES
2183   NONE
2184
2185RETURN VALUE
2186   0
2187
2188SIDE EFFECTS
2189   N/A
2190
2191===========================================================================*/
2192static int loc_eng_set_server(loc_eng_data_s_type &loc_eng_data,
2193                              LocServerType type, const char* hostname, int port)
2194{
2195    ENTRY_LOG();
2196    int ret = 0;
2197    LocEngAdapter* adapter = loc_eng_data.adapter;
2198
2199    if (LOC_AGPS_SUPL_SERVER == type) {
2200        char url[MAX_URL_LEN];
2201        unsigned int len = snprintf(url, sizeof(url), "%s:%u", hostname, (unsigned) port);
2202
2203        if (sizeof(url) > len) {
2204            adapter->sendMsg(new LocEngSetServerUrl(adapter, url, len));
2205        }
2206    } else if (LOC_AGPS_CDMA_PDE_SERVER == type ||
2207               LOC_AGPS_CUSTOM_PDE_SERVER == type ||
2208               LOC_AGPS_MPC_SERVER == type) {
2209        struct in_addr addr;
2210        if (!resolve_in_addr(hostname, &addr))
2211        {
2212            LOC_LOGE("loc_eng_set_server, hostname %s cannot be resolved.\n", hostname);
2213            ret = -2;
2214        } else {
2215            unsigned int ip = htonl(addr.s_addr);
2216            adapter->sendMsg(new LocEngSetServerIpv4(adapter, ip, port, type));
2217        }
2218    } else {
2219        LOC_LOGE("loc_eng_set_server, type %d cannot be resolved.\n", type);
2220    }
2221
2222    EXIT_LOG(%d, ret);
2223    return ret;
2224}
2225
2226/*===========================================================================
2227FUNCTION    loc_eng_set_server_proxy
2228
2229DESCRIPTION
2230   If loc_eng_set_server is called before loc_eng_init, it doesn't work. This
2231   proxy buffers server settings and calls loc_eng_set_server when the client is
2232   open.
2233
2234DEPENDENCIES
2235   NONE
2236
2237RETURN VALUE
2238   0
2239
2240SIDE EFFECTS
2241   N/A
2242
2243===========================================================================*/
2244int loc_eng_set_server_proxy(loc_eng_data_s_type &loc_eng_data,
2245                             LocServerType type,
2246                             const char* hostname, int port)
2247{
2248    ENTRY_LOG_CALLFLOW();
2249    int ret_val = 0;
2250
2251    if (NULL != loc_eng_data.adapter)
2252    {
2253        ret_val = loc_eng_set_server(loc_eng_data, type, hostname, port);
2254    } else {
2255        LOC_LOGW("set_server called before init. save the address, type: %d, hostname: %s, port: %d",
2256                 (int) type, hostname, port);
2257        switch (type)
2258        {
2259        case LOC_AGPS_SUPL_SERVER:
2260            strlcpy(loc_eng_data.supl_host_buf, hostname,
2261                    sizeof(loc_eng_data.supl_host_buf));
2262            loc_eng_data.supl_port_buf = port;
2263            loc_eng_data.supl_host_set = 1;
2264            break;
2265        case LOC_AGPS_CDMA_PDE_SERVER:
2266            strlcpy(loc_eng_data.c2k_host_buf, hostname,
2267                    sizeof(loc_eng_data.c2k_host_buf));
2268            loc_eng_data.c2k_port_buf = port;
2269            loc_eng_data.c2k_host_set = 1;
2270            break;
2271        default:
2272            LOC_LOGE("loc_eng_set_server_proxy, unknown server type = %d", (int) type);
2273        }
2274    }
2275
2276    EXIT_LOG(%d, ret_val);
2277    return ret_val;
2278}
2279
2280/*===========================================================================
2281FUNCTION    loc_eng_agps_ril_update_network_availability
2282
2283DESCRIPTION
2284   Sets data call allow vs disallow flag to modem
2285   This is the only member of sLocEngAGpsRilInterface implemented.
2286
2287DEPENDENCIES
2288   None
2289
2290RETURN VALUE
2291   0: success
2292
2293SIDE EFFECTS
2294   N/A
2295
2296===========================================================================*/
2297void loc_eng_agps_ril_update_network_availability(loc_eng_data_s_type &loc_eng_data,
2298                                                  int available, const char* apn)
2299{
2300    ENTRY_LOG_CALLFLOW();
2301
2302    //This is to store the status of data availability over the network.
2303    //If GPS is not enabled, the INIT_CHECK will fail and the modem will
2304    //not be updated with the network's availability. Since the data status
2305    //can change before GPS is enabled the, storing the status will enable
2306    //us to inform the modem after GPS is enabled
2307    agpsStatus = available;
2308
2309    INIT_CHECK(loc_eng_data.adapter, return);
2310    if (apn != NULL)
2311    {
2312        LOC_LOGD("loc_eng_agps_ril_update_network_availability: APN Name = [%s]\n", apn);
2313        int apn_len = smaller_of(strlen (apn), MAX_APN_LEN);
2314        LocEngAdapter* adapter = loc_eng_data.adapter;
2315        adapter->sendMsg(new LocEngEnableData(adapter, apn,  apn_len, available));
2316    }
2317    EXIT_LOG(%s, VOID_RET);
2318}
2319
2320/*===========================================================================
2321FUNCTION    loc_eng_report_status
2322
2323DESCRIPTION
2324   Reports GPS engine state to Java layer.
2325
2326DEPENDENCIES
2327   N/A
2328
2329RETURN VALUE
2330   N/A
2331
2332SIDE EFFECTS
2333   N/A
2334
2335===========================================================================*/
2336static void loc_eng_report_status (loc_eng_data_s_type &loc_eng_data, GpsStatusValue status)
2337{
2338    ENTRY_LOG();
2339    // Switch from WAIT to MUTE, for "engine on" or "session begin" event
2340    if (status == GPS_STATUS_SESSION_BEGIN || status == GPS_STATUS_ENGINE_ON)
2341    {
2342        if (loc_eng_data.mute_session_state == LOC_MUTE_SESS_WAIT)
2343        {
2344            LOC_LOGD("loc_eng_report_status: mute_session_state changed from WAIT to IN SESSION");
2345            loc_eng_data.mute_session_state = LOC_MUTE_SESS_IN_SESSION;
2346        }
2347    }
2348
2349    // Switch off MUTE session
2350    if (loc_eng_data.mute_session_state == LOC_MUTE_SESS_IN_SESSION &&
2351        (status == GPS_STATUS_SESSION_END || status == GPS_STATUS_ENGINE_OFF))
2352    {
2353        LOC_LOGD("loc_eng_report_status: mute_session_state changed from IN SESSION to NONE");
2354        loc_eng_data.mute_session_state = LOC_MUTE_SESS_NONE;
2355    }
2356
2357    // Session End is not reported during Android navigating state
2358    boolean navigating = loc_eng_data.adapter->isInSession();
2359    if (status != GPS_STATUS_NONE &&
2360        !(status == GPS_STATUS_SESSION_END && navigating) &&
2361        !(status == GPS_STATUS_SESSION_BEGIN && !navigating))
2362    {
2363        if (loc_eng_data.mute_session_state != LOC_MUTE_SESS_IN_SESSION)
2364        {
2365            // Inform GpsLocationProvider about mNavigating status
2366            loc_inform_gps_status(loc_eng_data, status);
2367        }
2368        else {
2369            LOC_LOGD("loc_eng_report_status: muting the status report.");
2370        }
2371    }
2372
2373    // Only keeps ENGINE ON/OFF in engine_status
2374    if (status == GPS_STATUS_ENGINE_ON || status == GPS_STATUS_ENGINE_OFF)
2375    {
2376        loc_eng_data.engine_status = status;
2377    }
2378
2379    // Only keeps SESSION BEGIN/END in fix_session_status
2380    if (status == GPS_STATUS_SESSION_BEGIN || status == GPS_STATUS_SESSION_END)
2381    {
2382        loc_eng_data.fix_session_status = status;
2383    }
2384    EXIT_LOG(%s, VOID_RET);
2385}
2386
2387/*===========================================================================
2388FUNCTION loc_eng_handle_engine_down
2389         loc_eng_handle_engine_up
2390
2391DESCRIPTION
2392   Calls this function when it is detected that modem restart is happening.
2393   Either we detected the modem is down or received modem up event.
2394   This must be called from the deferred thread to avoid race condition.
2395
2396DEPENDENCIES
2397   None
2398
2399RETURN VALUE
2400   None
2401
2402SIDE EFFECTS
2403   N/A
2404
2405===========================================================================*/
2406void loc_eng_handle_engine_down(loc_eng_data_s_type &loc_eng_data)
2407{
2408    ENTRY_LOG();
2409    loc_eng_ni_reset_on_engine_restart(loc_eng_data);
2410    loc_eng_report_status(loc_eng_data, GPS_STATUS_ENGINE_OFF);
2411    EXIT_LOG(%s, VOID_RET);
2412}
2413
2414void loc_eng_handle_engine_up(loc_eng_data_s_type &loc_eng_data)
2415{
2416    ENTRY_LOG();
2417    loc_eng_reinit(loc_eng_data);
2418
2419    if (loc_eng_data.agps_status_cb != NULL) {
2420        loc_eng_data.agnss_nif->dropAllSubscribers();
2421        loc_eng_data.internet_nif->dropAllSubscribers();
2422
2423        loc_eng_agps_reinit(loc_eng_data);
2424    }
2425
2426    loc_eng_report_status(loc_eng_data, GPS_STATUS_ENGINE_ON);
2427
2428    // modem is back up.  If we crashed in the middle of navigating, we restart.
2429    if (loc_eng_data.adapter->isInSession()) {
2430        // This sets the copy in adapter to modem
2431        loc_eng_data.adapter->setPositionMode(NULL);
2432        loc_eng_data.adapter->setInSession(false);
2433        loc_eng_start_handler(loc_eng_data);
2434    }
2435    EXIT_LOG(%s, VOID_RET);
2436}
2437
2438#ifdef USE_GLIB
2439/*===========================================================================
2440FUNCTION set_sched_policy
2441
2442DESCRIPTION
2443   Local copy of this function which bypasses android set_sched_policy
2444
2445DEPENDENCIES
2446   None
2447
2448RETURN VALUE
2449   0
2450
2451SIDE EFFECTS
2452   N/A
2453
2454===========================================================================*/
2455static int set_sched_policy(int tid, SchedPolicy policy)
2456{
2457    return 0;
2458}
2459#endif /* USE_GLIB */
2460
2461/*===========================================================================
2462FUNCTION    loc_eng_read_config
2463
2464DESCRIPTION
2465   Initiates the reading of the gps config file stored in /etc dir
2466
2467DEPENDENCIES
2468   None
2469
2470RETURN VALUE
2471   0: success
2472
2473SIDE EFFECTS
2474   N/A
2475
2476===========================================================================*/
2477int loc_eng_read_config(void)
2478{
2479    ENTRY_LOG_CALLFLOW();
2480    if(configAlreadyRead == false)
2481    {
2482      // Initialize our defaults before reading of configuration file overwrites them.
2483      loc_default_parameters();
2484      // We only want to parse the conf file once. This is a good place to ensure that.
2485      // In fact one day the conf file should go into context.
2486      UTIL_READ_CONF(GPS_CONF_FILE, loc_parameter_table);
2487      UTIL_READ_CONF(SAP_CONF_FILE, loc_parameter_table);
2488      configAlreadyRead = true;
2489    } else {
2490      LOC_LOGV("GPS Config file has already been read\n");
2491    }
2492
2493    EXIT_LOG(%d, 0);
2494    return 0;
2495}
2496