1/* Copyright (c) 2009-2014, 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#include <new>
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
87#define XTRA1_GPSONEXTRA         "xtra1.gpsonextra.net"
88
89using namespace loc_core;
90
91boolean configAlreadyRead = false;
92unsigned int agpsStatus = 0;
93loc_gps_cfg_s_type gps_conf;
94loc_sap_cfg_s_type sap_conf;
95
96/* Parameter spec table */
97static loc_param_s_type gps_conf_table[] =
98{
99  {"GPS_LOCK",                       &gps_conf.GPS_LOCK,                       NULL, 'n'},
100  {"SUPL_VER",                       &gps_conf.SUPL_VER,                       NULL, 'n'},
101  {"LPP_PROFILE",                    &gps_conf.LPP_PROFILE,                    NULL, 'n'},
102  {"A_GLONASS_POS_PROTOCOL_SELECT",  &gps_conf.A_GLONASS_POS_PROTOCOL_SELECT,  NULL, 'n'},
103  {"AGPS_CERT_WRITABLE_MASK",        &gps_conf.AGPS_CERT_WRITABLE_MASK,        NULL, 'n'},
104  {"SUPL_MODE",                      &gps_conf.SUPL_MODE,                      NULL, 'n'},
105  {"INTERMEDIATE_POS",               &gps_conf.INTERMEDIATE_POS,               NULL, 'n'},
106  {"ACCURACY_THRES",                 &gps_conf.ACCURACY_THRES,                 NULL, 'n'},
107  {"NMEA_PROVIDER",                  &gps_conf.NMEA_PROVIDER,                  NULL, 'n'},
108  {"CAPABILITIES",                   &gps_conf.CAPABILITIES,                   NULL, 'n'},
109  {"XTRA_VERSION_CHECK",             &gps_conf.XTRA_VERSION_CHECK,             NULL, 'n'},
110  {"XTRA_SERVER_1",                  &gps_conf.XTRA_SERVER_1,                  NULL, 's'},
111  {"XTRA_SERVER_2",                  &gps_conf.XTRA_SERVER_2,                  NULL, 's'},
112  {"XTRA_SERVER_3",                  &gps_conf.XTRA_SERVER_3,                  NULL, 's'},
113  {"USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL",  &gps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL,          NULL, 'n'},
114};
115
116static loc_param_s_type sap_conf_table[] =
117{
118  {"GYRO_BIAS_RANDOM_WALK",          &sap_conf.GYRO_BIAS_RANDOM_WALK,          &sap_conf.GYRO_BIAS_RANDOM_WALK_VALID, 'f'},
119  {"ACCEL_RANDOM_WALK_SPECTRAL_DENSITY",     &sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY,    &sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
120  {"ANGLE_RANDOM_WALK_SPECTRAL_DENSITY",     &sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY,    &sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
121  {"RATE_RANDOM_WALK_SPECTRAL_DENSITY",      &sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY,     &sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
122  {"VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY",  &sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY, &sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
123  {"SENSOR_ACCEL_BATCHES_PER_SEC",   &sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC,   NULL, 'n'},
124  {"SENSOR_ACCEL_SAMPLES_PER_BATCH", &sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH, NULL, 'n'},
125  {"SENSOR_GYRO_BATCHES_PER_SEC",    &sap_conf.SENSOR_GYRO_BATCHES_PER_SEC,    NULL, 'n'},
126  {"SENSOR_GYRO_SAMPLES_PER_BATCH",  &sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH,  NULL, 'n'},
127  {"SENSOR_ACCEL_BATCHES_PER_SEC_HIGH",   &sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH,   NULL, 'n'},
128  {"SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH", &sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH, NULL, 'n'},
129  {"SENSOR_GYRO_BATCHES_PER_SEC_HIGH",    &sap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH,    NULL, 'n'},
130  {"SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH",  &sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH,  NULL, 'n'},
131  {"SENSOR_CONTROL_MODE",            &sap_conf.SENSOR_CONTROL_MODE,            NULL, 'n'},
132  {"SENSOR_USAGE",                   &sap_conf.SENSOR_USAGE,                   NULL, 'n'},
133  {"SENSOR_ALGORITHM_CONFIG_MASK",   &sap_conf.SENSOR_ALGORITHM_CONFIG_MASK,   NULL, 'n'},
134  {"SENSOR_PROVIDER",                &sap_conf.SENSOR_PROVIDER,                NULL, 'n'}
135};
136
137static void loc_default_parameters(void)
138{
139   /*Defaults for gps.conf*/
140   gps_conf.INTERMEDIATE_POS = 0;
141   gps_conf.ACCURACY_THRES = 0;
142   gps_conf.NMEA_PROVIDER = 0;
143   gps_conf.GPS_LOCK = 0;
144   gps_conf.SUPL_VER = 0x10000;
145   gps_conf.SUPL_MODE = 0x3;
146   gps_conf.CAPABILITIES = 0x7;
147   /* LTE Positioning Profile configuration is disable by default*/
148   gps_conf.LPP_PROFILE = 0;
149   /*By default no positioning protocol is selected on A-GLONASS system*/
150   gps_conf.A_GLONASS_POS_PROTOCOL_SELECT = 0;
151   /*XTRA version check is disabled by default*/
152   gps_conf.XTRA_VERSION_CHECK=0;
153   /*Use emergency PDN by default*/
154   gps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL = 1;
155
156   /*Defaults for sap.conf*/
157   sap_conf.GYRO_BIAS_RANDOM_WALK = 0;
158   sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC = 2;
159   sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH = 5;
160   sap_conf.SENSOR_GYRO_BATCHES_PER_SEC = 2;
161   sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH = 5;
162   sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH = 4;
163   sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH = 25;
164   sap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH = 4;
165   sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH = 25;
166   sap_conf.SENSOR_CONTROL_MODE = 0; /* AUTO */
167   sap_conf.SENSOR_USAGE = 0; /* Enabled */
168   sap_conf.SENSOR_ALGORITHM_CONFIG_MASK = 0; /* INS Disabled = FALSE*/
169   /* Values MUST be set by OEMs in configuration for sensor-assisted
170      navigation to work. There are NO default values */
171   sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY = 0;
172   sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
173   sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
174   sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY = 0;
175   sap_conf.GYRO_BIAS_RANDOM_WALK_VALID = 0;
176   sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
177   sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
178   sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
179   sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
180   /* default provider is SSC */
181   sap_conf.SENSOR_PROVIDER = 1;
182
183   /* None of the 10 slots for agps certificates are writable by default */
184   gps_conf.AGPS_CERT_WRITABLE_MASK = 0;
185}
186
187// 2nd half of init(), singled out for
188// modem restart to use.
189static int loc_eng_reinit(loc_eng_data_s_type &loc_eng_data);
190static void loc_eng_agps_reinit(loc_eng_data_s_type &loc_eng_data);
191
192static int loc_eng_set_server(loc_eng_data_s_type &loc_eng_data,
193                              LocServerType type, const char *hostname, int port);
194// Internal functions
195static void loc_inform_gps_status(loc_eng_data_s_type &loc_eng_data,
196                                  GpsStatusValue status);
197static void loc_eng_report_status(loc_eng_data_s_type &loc_eng_data,
198                                  GpsStatusValue status);
199static void loc_eng_process_conn_request(loc_eng_data_s_type &loc_eng_data,
200                                         int connHandle, AGpsType agps_type);
201static void loc_eng_agps_close_status(loc_eng_data_s_type &loc_eng_data, int is_succ);
202static void loc_eng_handle_engine_down(loc_eng_data_s_type &loc_eng_data) ;
203static void loc_eng_handle_engine_up(loc_eng_data_s_type &loc_eng_data) ;
204
205static int loc_eng_start_handler(loc_eng_data_s_type &loc_eng_data);
206static int loc_eng_stop_handler(loc_eng_data_s_type &loc_eng_data);
207static int loc_eng_get_zpp_handler(loc_eng_data_s_type &loc_eng_data);
208static void deleteAidingData(loc_eng_data_s_type &logEng);
209static AgpsStateMachine*
210getAgpsStateMachine(loc_eng_data_s_type& logEng, AGpsExtType agpsType);
211static int dataCallCb(void *cb_data);
212static void update_aiding_data_for_deletion(loc_eng_data_s_type& loc_eng_data) {
213    if (loc_eng_data.engine_status != GPS_STATUS_ENGINE_ON &&
214        loc_eng_data.aiding_data_for_deletion != 0)
215    {
216        loc_eng_data.adapter->deleteAidingData(loc_eng_data.aiding_data_for_deletion);
217        loc_eng_data.aiding_data_for_deletion = 0;
218    }
219}
220
221static void* noProc(void* data)
222{
223    return NULL;
224}
225
226
227/*********************************************************************
228 * definitions of the static messages used in the file
229 *********************************************************************/
230//        case LOC_ENG_MSG_REQUEST_NI:
231LocEngRequestNi::LocEngRequestNi(void* locEng,
232                                 GpsNiNotification &notif,
233                                 const void* data) :
234    LocMsg(), mLocEng(locEng), mNotify(notif), mPayload(data) {
235    locallog();
236}
237void LocEngRequestNi::proc() const {
238    loc_eng_ni_request_handler(*((loc_eng_data_s_type*)mLocEng),
239                               &mNotify, mPayload);
240}
241void LocEngRequestNi::locallog() const
242{
243    LOC_LOGV("id: %d\n  type: %s\n  flags: %d\n  time out: %d\n  "
244             "default response: %s\n  requestor id encoding: %s\n"
245             "  text encoding: %s\n  passThroughData: %p",
246             mNotify.notification_id,
247             loc_get_ni_type_name(mNotify.ni_type),
248             mNotify.notify_flags,
249             mNotify.timeout,
250             loc_get_ni_response_name(mNotify.default_response),
251             loc_get_ni_encoding_name(mNotify.requestor_id_encoding),
252             loc_get_ni_encoding_name(mNotify.text_encoding),
253             mPayload);
254}
255inline void LocEngRequestNi::log() const {
256    locallog();
257}
258
259//        case LOC_ENG_MSG_INFORM_NI_RESPONSE:
260// in loc_eng_ni.cpp
261
262//        case LOC_ENG_MSG_START_FIX:
263LocEngStartFix::LocEngStartFix(LocEngAdapter* adapter) :
264    LocMsg(), mAdapter(adapter)
265{
266    locallog();
267}
268inline void LocEngStartFix::proc() const
269{
270    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mAdapter->getOwner();
271    loc_eng_start_handler(*locEng);
272}
273inline void LocEngStartFix::locallog() const
274{
275    LOC_LOGV("LocEngStartFix");
276}
277inline void LocEngStartFix::log() const
278{
279    locallog();
280}
281void LocEngStartFix::send() const {
282    mAdapter->sendMsg(this);
283}
284
285//        case LOC_ENG_MSG_STOP_FIX:
286LocEngStopFix::LocEngStopFix(LocEngAdapter* adapter) :
287    LocMsg(), mAdapter(adapter)
288{
289    locallog();
290}
291inline void LocEngStopFix::proc() const
292{
293    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mAdapter->getOwner();
294    loc_eng_stop_handler(*locEng);
295}
296inline void LocEngStopFix::locallog() const
297{
298    LOC_LOGV("LocEngStopFix");
299}
300inline void LocEngStopFix::log() const
301{
302    locallog();
303}
304void LocEngStopFix::send() const {
305    mAdapter->sendMsg(this);
306}
307
308//        case LOC_ENG_MSG_SET_POSITION_MODE:
309LocEngPositionMode::LocEngPositionMode(LocEngAdapter* adapter,
310                                       LocPosMode &mode) :
311    LocMsg(), mAdapter(adapter), mPosMode(mode)
312{
313    mPosMode.logv();
314}
315inline void LocEngPositionMode::proc() const {
316    mAdapter->setPositionMode(&mPosMode);
317}
318inline void LocEngPositionMode::log() const {
319    mPosMode.logv();
320}
321void LocEngPositionMode::send() const {
322    mAdapter->sendMsg(this);
323}
324
325LocEngGetZpp::LocEngGetZpp(LocEngAdapter* adapter) :
326    LocMsg(), mAdapter(adapter)
327{
328    locallog();
329}
330inline void LocEngGetZpp::proc() const
331{
332    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mAdapter->getOwner();
333    loc_eng_get_zpp_handler(*locEng);
334}
335inline void LocEngGetZpp::locallog() const
336{
337    LOC_LOGV("LocEngGetZpp");
338}
339inline void LocEngGetZpp::log() const
340{
341    locallog();
342}
343void LocEngGetZpp::send() const {
344    mAdapter->sendMsg(this);
345}
346
347struct LocEngSetTime : public LocMsg {
348    LocEngAdapter* mAdapter;
349    const GpsUtcTime mTime;
350    const int64_t mTimeReference;
351    const int mUncertainty;
352    inline LocEngSetTime(LocEngAdapter* adapter,
353                         GpsUtcTime t, int64_t tf, int unc) :
354        LocMsg(), mAdapter(adapter),
355        mTime(t), mTimeReference(tf), mUncertainty(unc)
356    {
357        locallog();
358    }
359    inline virtual void proc() const {
360        mAdapter->setTime(mTime, mTimeReference, mUncertainty);
361    }
362    inline void locallog() const {
363        LOC_LOGV("time: %lld\n  timeReference: %lld\n  uncertainty: %d",
364                 mTime, mTimeReference, mUncertainty);
365    }
366    inline virtual void log() const {
367        locallog();
368    }
369};
370
371 //       case LOC_ENG_MSG_INJECT_LOCATION:
372struct LocEngInjectLocation : public LocMsg {
373    LocEngAdapter* mAdapter;
374    const double mLatitude;
375    const double mLongitude;
376    const float mAccuracy;
377    inline LocEngInjectLocation(LocEngAdapter* adapter,
378                                double lat, double lon, float accur) :
379        LocMsg(), mAdapter(adapter),
380        mLatitude(lat), mLongitude(lon), mAccuracy(accur)
381    {
382        locallog();
383    }
384    inline virtual void proc() const {
385        mAdapter->injectPosition(mLatitude, mLongitude, mAccuracy);
386    }
387    inline void locallog() const {
388        LOC_LOGV("latitude: %f\n  longitude: %f\n  accuracy: %f",
389                 mLatitude, mLongitude, mAccuracy);
390    }
391    inline virtual void log() const {
392        locallog();
393    }
394};
395
396//        case LOC_ENG_MSG_SET_SERVER_IPV4:
397struct LocEngSetServerIpv4 : public LocMsg {
398    LocEngAdapter* mAdapter;
399    const unsigned int mNlAddr;
400    const int mPort;
401    const LocServerType mServerType;
402    inline LocEngSetServerIpv4(LocEngAdapter* adapter,
403                               unsigned int ip,
404                               int port,
405                               LocServerType type) :
406        LocMsg(), mAdapter(adapter),
407        mNlAddr(ip), mPort(port), mServerType(type)
408    {
409        locallog();
410    }
411    inline virtual void proc() const {
412        mAdapter->setServer(mNlAddr, mPort, mServerType);
413    }
414    inline void locallog() const {
415        LOC_LOGV("LocEngSetServerIpv4 - addr: %x, port: %d, type: %s",
416                 mNlAddr, mPort, loc_get_server_type_name(mServerType));
417    }
418    inline virtual void log() const {
419        locallog();
420    }
421};
422
423//        case LOC_ENG_MSG_SET_SERVER_URL:
424struct LocEngSetServerUrl : public LocMsg {
425    LocEngAdapter* mAdapter;
426    const int mLen;
427    char* mUrl;
428    inline LocEngSetServerUrl(LocEngAdapter* adapter,
429                              char* urlString,
430                              int url_len) :
431        LocMsg(), mAdapter(adapter),
432        mLen(url_len), mUrl(new char[mLen+1])
433    {
434        memcpy((void*)mUrl, (void*)urlString, url_len);
435        mUrl[mLen] = 0;
436        locallog();
437    }
438    inline ~LocEngSetServerUrl()
439    {
440        delete[] mUrl;
441    }
442    inline virtual void proc() const {
443        mAdapter->setServer(mUrl, mLen);
444    }
445    inline void locallog() const {
446        LOC_LOGV("LocEngSetServerUrl - url: %s", mUrl);
447    }
448    inline virtual void log() const {
449        locallog();
450    }
451};
452
453//        case LOC_ENG_MSG_A_GLONASS_PROTOCOL:
454struct LocEngAGlonassProtocol : public LocMsg {
455    LocEngAdapter* mAdapter;
456    const unsigned long mAGlonassProtocl;
457    inline LocEngAGlonassProtocol(LocEngAdapter* adapter,
458                                  unsigned long protocol) :
459        LocMsg(), mAdapter(adapter), mAGlonassProtocl(protocol)
460    {
461        locallog();
462    }
463    inline virtual void proc() const {
464        mAdapter->setAGLONASSProtocol(mAGlonassProtocl);
465    }
466    inline  void locallog() const {
467        LOC_LOGV("A-GLONASS protocol: 0x%lx", mAGlonassProtocl);
468    }
469    inline virtual void log() const {
470        locallog();
471    }
472};
473
474//        case LOC_ENG_MSG_SUPL_VERSION:
475struct LocEngSuplVer : public LocMsg {
476    LocEngAdapter* mAdapter;
477    const int mSuplVer;
478    inline LocEngSuplVer(LocEngAdapter* adapter,
479                         int suplVer) :
480        LocMsg(), mAdapter(adapter), mSuplVer(suplVer)
481    {
482        locallog();
483    }
484    inline virtual void proc() const {
485        mAdapter->setSUPLVersion(mSuplVer);
486    }
487    inline  void locallog() const {
488        LOC_LOGV("SUPL Version: %d", mSuplVer);
489    }
490    inline virtual void log() const {
491        locallog();
492    }
493};
494
495struct LocEngSuplMode : public LocMsg {
496    UlpProxyBase* mUlp;
497
498    inline LocEngSuplMode(UlpProxyBase* ulp) :
499        LocMsg(), mUlp(ulp)
500    {
501        locallog();
502    }
503    inline virtual void proc() const {
504        mUlp->setCapabilities(getCarrierCapabilities());
505    }
506    inline  void locallog() const {
507    }
508    inline virtual void log() const {
509        locallog();
510    }
511};
512
513//        case LOC_ENG_MSG_LPP_CONFIG:
514struct LocEngLppConfig : public LocMsg {
515    LocEngAdapter* mAdapter;
516    const int mLppConfig;
517    inline LocEngLppConfig(LocEngAdapter* adapter,
518                           int lppConfig) :
519        LocMsg(), mAdapter(adapter), mLppConfig(lppConfig)
520    {
521        locallog();
522    }
523    inline virtual void proc() const {
524        mAdapter->setLPPConfig(mLppConfig);
525    }
526    inline void locallog() const {
527        LOC_LOGV("LocEngLppConfig - profile: %d", mLppConfig);
528    }
529    inline virtual void log() const {
530        locallog();
531    }
532};
533
534//        case LOC_ENG_MSG_SET_SENSOR_CONTROL_CONFIG:
535struct LocEngSensorControlConfig : public LocMsg {
536    LocEngAdapter* mAdapter;
537    const int mSensorsDisabled;
538    const int mSensorProvider;
539    inline LocEngSensorControlConfig(LocEngAdapter* adapter,
540                                     int sensorsDisabled, int sensorProvider) :
541        LocMsg(), mAdapter(adapter), mSensorsDisabled(sensorsDisabled),
542        mSensorProvider(sensorProvider)
543    {
544        locallog();
545    }
546    inline virtual void proc() const {
547        mAdapter->setSensorControlConfig(mSensorsDisabled, mSensorProvider);
548    }
549    inline  void locallog() const {
550        LOC_LOGV("LocEngSensorControlConfig - Sensors Disabled: %d, Sensor Provider: %d",
551                 mSensorsDisabled, mSensorProvider);
552    }
553    inline virtual void log() const {
554        locallog();
555    }
556};
557
558//        case LOC_ENG_MSG_SET_SENSOR_PROPERTIES:
559struct LocEngSensorProperties : public LocMsg {
560    LocEngAdapter* mAdapter;
561    const bool mGyroBiasVarianceRandomWalkValid;
562    const float mGyroBiasVarianceRandomWalk;
563    const bool mAccelRandomWalkValid;
564    const float mAccelRandomWalk;
565    const bool mAngleRandomWalkValid;
566    const float mAngleRandomWalk;
567    const bool mRateRandomWalkValid;
568    const float mRateRandomWalk;
569    const bool mVelocityRandomWalkValid;
570    const float mVelocityRandomWalk;
571    inline LocEngSensorProperties(LocEngAdapter* adapter,
572                                  bool gyroBiasRandomWalk_valid,
573                                  float gyroBiasRandomWalk,
574                                  bool accelRandomWalk_valid,
575                                  float accelRandomWalk,
576                                  bool angleRandomWalk_valid,
577                                  float angleRandomWalk,
578                                  bool rateRandomWalk_valid,
579                                  float rateRandomWalk,
580                                  bool velocityRandomWalk_valid,
581                                  float velocityRandomWalk) :
582        LocMsg(), mAdapter(adapter),
583        mGyroBiasVarianceRandomWalkValid(gyroBiasRandomWalk_valid),
584        mGyroBiasVarianceRandomWalk(gyroBiasRandomWalk),
585        mAccelRandomWalkValid(accelRandomWalk_valid),
586        mAccelRandomWalk(accelRandomWalk),
587        mAngleRandomWalkValid(angleRandomWalk_valid),
588        mAngleRandomWalk(angleRandomWalk),
589        mRateRandomWalkValid(rateRandomWalk_valid),
590        mRateRandomWalk(rateRandomWalk),
591        mVelocityRandomWalkValid(velocityRandomWalk_valid),
592        mVelocityRandomWalk(velocityRandomWalk)
593    {
594        locallog();
595    }
596    inline virtual void proc() const {
597        mAdapter->setSensorProperties(mGyroBiasVarianceRandomWalkValid,
598                                      mGyroBiasVarianceRandomWalk,
599                                      mAccelRandomWalkValid,
600                                      mAccelRandomWalk,
601                                      mAngleRandomWalkValid,
602                                      mAngleRandomWalk,
603                                      mRateRandomWalkValid,
604                                      mRateRandomWalk,
605                                      mVelocityRandomWalkValid,
606                                      mVelocityRandomWalk);
607    }
608    inline  void locallog() const {
609        LOC_LOGV("Sensor properties validity, Gyro Random walk: %d "
610                 "Accel Random Walk: %d "
611                 "Angle Random Walk: %d Rate Random Walk: %d "
612                 "Velocity Random Walk: %d\n"
613                 "Sensor properties, Gyro Random walk: %f "
614                 "Accel Random Walk: %f "
615                 "Angle Random Walk: %f Rate Random Walk: %f "
616                 "Velocity Random Walk: %f",
617                 mGyroBiasVarianceRandomWalkValid,
618                 mAccelRandomWalkValid,
619                 mAngleRandomWalkValid,
620                 mRateRandomWalkValid,
621                 mVelocityRandomWalkValid,
622                 mGyroBiasVarianceRandomWalk,
623                 mAccelRandomWalk,
624                 mAngleRandomWalk,
625                 mRateRandomWalk,
626                 mVelocityRandomWalk
627            );
628    }
629    inline virtual void log() const {
630        locallog();
631    }
632};
633
634//        case LOC_ENG_MSG_SET_SENSOR_PERF_CONTROL_CONFIG:
635struct LocEngSensorPerfControlConfig : public LocMsg {
636    LocEngAdapter* mAdapter;
637    const int mControlMode;
638    const int mAccelSamplesPerBatch;
639    const int mAccelBatchesPerSec;
640    const int mGyroSamplesPerBatch;
641    const int mGyroBatchesPerSec;
642    const int mAccelSamplesPerBatchHigh;
643    const int mAccelBatchesPerSecHigh;
644    const int mGyroSamplesPerBatchHigh;
645    const int mGyroBatchesPerSecHigh;
646    const int mAlgorithmConfig;
647    inline LocEngSensorPerfControlConfig(LocEngAdapter* adapter,
648                                         int controlMode,
649                                         int accelSamplesPerBatch,
650                                         int accelBatchesPerSec,
651                                         int gyroSamplesPerBatch,
652                                         int gyroBatchesPerSec,
653                                         int accelSamplesPerBatchHigh,
654                                         int accelBatchesPerSecHigh,
655                                         int gyroSamplesPerBatchHigh,
656                                         int gyroBatchesPerSecHigh,
657                                         int algorithmConfig) :
658        LocMsg(), mAdapter(adapter),
659        mControlMode(controlMode),
660        mAccelSamplesPerBatch(accelSamplesPerBatch),
661        mAccelBatchesPerSec(accelBatchesPerSec),
662        mGyroSamplesPerBatch(gyroSamplesPerBatch),
663        mGyroBatchesPerSec(gyroBatchesPerSec),
664        mAccelSamplesPerBatchHigh(accelSamplesPerBatchHigh),
665        mAccelBatchesPerSecHigh(accelBatchesPerSecHigh),
666        mGyroSamplesPerBatchHigh(gyroSamplesPerBatchHigh),
667        mGyroBatchesPerSecHigh(gyroBatchesPerSecHigh),
668        mAlgorithmConfig(algorithmConfig)
669    {
670        locallog();
671    }
672    inline virtual void proc() const {
673        mAdapter->setSensorPerfControlConfig(mControlMode,
674                                             mAccelSamplesPerBatch,
675                                             mAccelBatchesPerSec,
676                                             mGyroSamplesPerBatch,
677                                             mGyroBatchesPerSec,
678                                             mAccelSamplesPerBatchHigh,
679                                             mAccelBatchesPerSecHigh,
680                                             mGyroSamplesPerBatchHigh,
681                                             mGyroBatchesPerSecHigh,
682                                             mAlgorithmConfig);
683    }
684    inline void locallog() const {
685        LOC_LOGV("Sensor Perf Control Config (performanceControlMode)(%u) "
686                 "accel(#smp,#batches) (%u,%u) "
687                 "gyro(#smp,#batches) (%u,%u), "
688                 "accel_high(#smp,#batches) (%u,%u) "
689                 "gyro_high(#smp,#batches) (%u,%u), "
690                 "algorithmConfig(%u)\n",
691                 mControlMode,
692                 mAccelSamplesPerBatch, mAccelBatchesPerSec,
693                 mGyroSamplesPerBatch, mGyroBatchesPerSec,
694                 mAccelSamplesPerBatchHigh, mAccelBatchesPerSecHigh,
695                 mGyroSamplesPerBatchHigh, mGyroBatchesPerSecHigh,
696                 mAlgorithmConfig);
697    }
698    inline virtual void log() const {
699        locallog();
700    }
701};
702
703//        case LOC_ENG_MSG_EXT_POWER_CONFIG:
704struct LocEngExtPowerConfig : public LocMsg {
705    LocEngAdapter* mAdapter;
706    const int mIsBatteryCharging;
707    inline LocEngExtPowerConfig(LocEngAdapter* adapter,
708                                int isBatteryCharging) :
709        LocMsg(), mAdapter(adapter),
710        mIsBatteryCharging(isBatteryCharging)
711    {
712        locallog();
713    }
714    inline virtual void proc() const {
715        mAdapter->setExtPowerConfig(mIsBatteryCharging);
716    }
717    inline void locallog() const {
718        LOC_LOGV("LocEngExtPowerConfig - isBatteryCharging: %d",
719                 mIsBatteryCharging);
720    }
721    inline virtual void log() const {
722        locallog();
723    }
724};
725
726//        case LOC_ENG_MSG_REPORT_POSITION:
727LocEngReportPosition::LocEngReportPosition(LocAdapterBase* adapter,
728                                           UlpLocation &loc,
729                                           GpsLocationExtended &locExtended,
730                                           void* locExt,
731                                           enum loc_sess_status st,
732                                           LocPosTechMask technology) :
733    LocMsg(), mAdapter(adapter), mLocation(loc),
734    mLocationExtended(locExtended),
735    mLocationExt(((loc_eng_data_s_type*)
736                  ((LocEngAdapter*)
737                   (mAdapter))->getOwner())->location_ext_parser(locExt)),
738    mStatus(st), mTechMask(technology)
739{
740    locallog();
741}
742void LocEngReportPosition::proc() const {
743    LocEngAdapter* adapter = (LocEngAdapter*)mAdapter;
744    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)adapter->getOwner();
745
746    if (locEng->mute_session_state != LOC_MUTE_SESS_IN_SESSION) {
747        bool reported = false;
748        if (locEng->location_cb != NULL) {
749            if (LOC_SESS_FAILURE == mStatus) {
750                // in case we want to handle the failure case
751                locEng->location_cb(NULL, NULL);
752                reported = true;
753            }
754            // what's in the else if is... (line by line)
755            // 1. this is a final fix; and
756            //   1.1 it is a Satellite fix; or
757            //   1.2 it is a sensor fix
758            // 2. (must be intermediate fix... implicit)
759            //   2.1 we accepte intermediate; and
760            //   2.2 it is NOT the case that
761            //   2.2.1 there is inaccuracy; and
762            //   2.2.2 we care about inaccuracy; and
763            //   2.2.3 the inaccuracy exceeds our tolerance
764            else if ((LOC_SESS_SUCCESS == mStatus &&
765                      ((LOC_POS_TECH_MASK_SATELLITE |
766                        LOC_POS_TECH_MASK_SENSORS   |
767                        LOC_POS_TECH_MASK_HYBRID) &
768                       mTechMask)) ||
769                     (LOC_SESS_INTERMEDIATE == locEng->intermediateFix &&
770                      !((mLocation.gpsLocation.flags &
771                         GPS_LOCATION_HAS_ACCURACY) &&
772                        (gps_conf.ACCURACY_THRES != 0) &&
773                        (mLocation.gpsLocation.accuracy >
774                         gps_conf.ACCURACY_THRES)))) {
775                locEng->location_cb((UlpLocation*)&(mLocation),
776                                    (void*)mLocationExt);
777                reported = true;
778            }
779        }
780
781        // if we have reported this fix
782        if (reported &&
783            // and if this is a singleshot
784            GPS_POSITION_RECURRENCE_SINGLE ==
785            locEng->adapter->getPositionMode().recurrence) {
786            if (LOC_SESS_INTERMEDIATE == mStatus) {
787                // modem could be still working for a final fix,
788                // although we no longer need it.  So stopFix().
789                locEng->adapter->stopFix();
790            }
791            // turn off the session flag.
792            locEng->adapter->setInSession(false);
793        }
794
795        if (locEng->generateNmea &&
796            mLocation.position_source == ULP_LOCATION_IS_FROM_GNSS &&
797            mTechMask & (LOC_POS_TECH_MASK_SATELLITE |
798                         LOC_POS_TECH_MASK_SENSORS |
799                         LOC_POS_TECH_MASK_HYBRID))
800        {
801            unsigned char generate_nmea = reported &&
802                                          (mStatus != LOC_SESS_FAILURE);
803            loc_eng_nmea_generate_pos(locEng, mLocation, mLocationExtended,
804                                      generate_nmea);
805        }
806
807        // Free the allocated memory for rawData
808        UlpLocation* gp = (UlpLocation*)&(mLocation);
809        if (gp != NULL && gp->rawData != NULL)
810        {
811            delete (char*)gp->rawData;
812            gp->rawData = NULL;
813            gp->rawDataSize = 0;
814        }
815    }
816}
817void LocEngReportPosition::locallog() const {
818    LOC_LOGV("LocEngReportPosition");
819}
820void LocEngReportPosition::log() const {
821    locallog();
822}
823void LocEngReportPosition::send() const {
824    mAdapter->sendMsg(this);
825}
826
827
828//        case LOC_ENG_MSG_REPORT_SV:
829LocEngReportSv::LocEngReportSv(LocAdapterBase* adapter,
830                               GpsSvStatus &sv,
831                               GpsLocationExtended &locExtended,
832                               void* svExt) :
833    LocMsg(), mAdapter(adapter), mSvStatus(sv),
834    mLocationExtended(locExtended),
835    mSvExt(((loc_eng_data_s_type*)
836            ((LocEngAdapter*)
837             (mAdapter))->getOwner())->sv_ext_parser(svExt))
838{
839    locallog();
840}
841void LocEngReportSv::proc() const {
842    LocEngAdapter* adapter = (LocEngAdapter*)mAdapter;
843    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)adapter->getOwner();
844
845    if (locEng->mute_session_state != LOC_MUTE_SESS_IN_SESSION)
846    {
847        if (locEng->sv_status_cb != NULL) {
848            locEng->sv_status_cb((GpsSvStatus*)&(mSvStatus),
849                                 (void*)mSvExt);
850        }
851
852        if (locEng->generateNmea)
853        {
854            loc_eng_nmea_generate_sv(locEng, mSvStatus, mLocationExtended);
855        }
856    }
857}
858void LocEngReportSv::locallog() const {
859    LOC_LOGV("%s:%d] LocEngReportSv",__func__, __LINE__);
860}
861inline void LocEngReportSv::log() const {
862    locallog();
863}
864void LocEngReportSv::send() const {
865    mAdapter->sendMsg(this);
866}
867
868//        case LOC_ENG_MSG_REPORT_STATUS:
869LocEngReportStatus::LocEngReportStatus(LocAdapterBase* adapter,
870                                       GpsStatusValue engineStatus) :
871    LocMsg(),  mAdapter(adapter), mStatus(engineStatus)
872{
873    locallog();
874}
875inline void LocEngReportStatus::proc() const
876{
877    LocEngAdapter* adapter = (LocEngAdapter*)mAdapter;
878    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)adapter->getOwner();
879
880    loc_eng_report_status(*locEng, mStatus);
881    update_aiding_data_for_deletion(*locEng);
882}
883inline void LocEngReportStatus::locallog() const {
884    LOC_LOGV("LocEngReportStatus");
885}
886inline void LocEngReportStatus::log() const {
887    locallog();
888}
889
890//        case LOC_ENG_MSG_REPORT_NMEA:
891LocEngReportNmea::LocEngReportNmea(void* locEng,
892                                   const char* data, int len) :
893    LocMsg(), mLocEng(locEng), mNmea(new char[len]), mLen(len)
894{
895    memcpy((void*)mNmea, (void*)data, len);
896    locallog();
897}
898void LocEngReportNmea::proc() const {
899    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*) mLocEng;
900
901    struct timeval tv;
902    gettimeofday(&tv, (struct timezone *) NULL);
903    int64_t now = tv.tv_sec * 1000LL + tv.tv_usec / 1000;
904
905    if (locEng->nmea_cb != NULL)
906        locEng->nmea_cb(now, mNmea, mLen);
907}
908inline void LocEngReportNmea::locallog() const {
909    LOC_LOGV("LocEngReportNmea");
910}
911inline void LocEngReportNmea::log() const {
912    locallog();
913}
914
915//        case LOC_ENG_MSG_REPORT_XTRA_SERVER:
916LocEngReportXtraServer::LocEngReportXtraServer(void* locEng,
917                                               const char *url1,
918                                               const char *url2,
919                                               const char *url3,
920                                               const int maxlength) :
921    LocMsg(), mLocEng(locEng), mMaxLen(maxlength),
922    mServers(new char[3*(mMaxLen+1)])
923{
924    char * cptr = mServers;
925    memset(mServers, 0, 3*(mMaxLen+1));
926
927    // Override modem URLs with uncommented gps.conf urls
928    if( gps_conf.XTRA_SERVER_1[0] != '\0' ) {
929        url1 = &gps_conf.XTRA_SERVER_1[0];
930    }
931    if( gps_conf.XTRA_SERVER_2[0] != '\0' ) {
932        url2 = &gps_conf.XTRA_SERVER_2[0];
933    }
934    if( gps_conf.XTRA_SERVER_3[0] != '\0' ) {
935        url3 = &gps_conf.XTRA_SERVER_3[0];
936    }
937    // copy non xtra1.gpsonextra.net URLs into the forwarding buffer.
938    if( NULL == strcasestr(url1, XTRA1_GPSONEXTRA) ) {
939        strlcpy(cptr, url1, mMaxLen + 1);
940        cptr += mMaxLen + 1;
941    }
942    if( NULL == strcasestr(url2, XTRA1_GPSONEXTRA) ) {
943        strlcpy(cptr, url2, mMaxLen + 1);
944        cptr += mMaxLen + 1;
945    }
946    if( NULL == strcasestr(url3, XTRA1_GPSONEXTRA) ) {
947        strlcpy(cptr, url3, mMaxLen + 1);
948    }
949    locallog();
950}
951
952void LocEngReportXtraServer::proc() const {
953    loc_eng_xtra_data_s_type* locEngXtra =
954        &(((loc_eng_data_s_type*)mLocEng)->xtra_module_data);
955
956    if (locEngXtra->report_xtra_server_cb != NULL) {
957        CALLBACK_LOG_CALLFLOW("report_xtra_server_cb", %s, mServers);
958        locEngXtra->report_xtra_server_cb(mServers,
959                                          &(mServers[mMaxLen+1]),
960                                          &(mServers[(mMaxLen+1)<<1]));
961    } else {
962        LOC_LOGE("Callback function for request xtra is NULL");
963    }
964}
965inline void LocEngReportXtraServer::locallog() const {
966    LOC_LOGV("LocEngReportXtraServers: server1: %s\n  server2: %s\n"
967             "  server3: %s\n",
968             mServers, &mServers[mMaxLen+1], &mServers[(mMaxLen+1)<<1]);
969}
970inline void LocEngReportXtraServer::log() const {
971    locallog();
972}
973
974//        case LOC_ENG_MSG_REQUEST_BIT:
975//        case LOC_ENG_MSG_RELEASE_BIT:
976LocEngReqRelBIT::LocEngReqRelBIT(void* locEng, AGpsExtType type,
977                                 int ipv4, char* ipv6, bool isReq) :
978    LocMsg(), mLocEng(locEng), mType(type), mIPv4Addr(ipv4),
979    mIPv6Addr(ipv6 ? new char[16] : NULL), mIsReq(isReq) {
980    if (NULL != ipv6)
981        memcpy(mIPv6Addr, ipv6, 16);
982    locallog();
983}
984inline LocEngReqRelBIT::~LocEngReqRelBIT() {
985    if (mIPv6Addr) {
986        delete[] mIPv6Addr;
987    }
988}
989void LocEngReqRelBIT::proc() const {
990    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
991    BITSubscriber s(getAgpsStateMachine(*locEng, mType),
992                    mIPv4Addr, mIPv6Addr);
993    AgpsStateMachine* sm = (AgpsStateMachine*)s.mStateMachine;
994
995    if (mIsReq) {
996        sm->subscribeRsrc((Subscriber*)&s);
997    } else {
998        sm->unsubscribeRsrc((Subscriber*)&s);
999    }
1000}
1001inline void LocEngReqRelBIT::locallog() const {
1002    LOC_LOGV("LocEngRequestBIT - ipv4: %d.%d.%d.%d, ipv6: %s",
1003             (unsigned char)mIPv4Addr,
1004             (unsigned char)(mIPv4Addr>>8),
1005             (unsigned char)(mIPv4Addr>>16),
1006             (unsigned char)(mIPv4Addr>>24),
1007             NULL != mIPv6Addr ? mIPv6Addr : "");
1008}
1009inline void LocEngReqRelBIT::log() const {
1010    locallog();
1011}
1012void LocEngReqRelBIT::send() const {
1013    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1014    locEng->adapter->sendMsg(this);
1015}
1016
1017//        case LOC_ENG_MSG_RELEASE_BIT:
1018struct LocEngReleaseBIT : public LocMsg {
1019    const BITSubscriber mSubscriber;
1020    inline LocEngReleaseBIT(const AgpsStateMachine* stateMachine,
1021                            unsigned int ipv4, char* ipv6) :
1022        LocMsg(),
1023        mSubscriber(stateMachine, ipv4, ipv6)
1024    {
1025        locallog();
1026    }
1027    inline virtual void proc() const
1028    {
1029        AgpsStateMachine* sm = (AgpsStateMachine*)mSubscriber.mStateMachine;
1030        sm->unsubscribeRsrc((Subscriber*)&mSubscriber);
1031    }
1032    inline void locallog() const {
1033        LOC_LOGV("LocEngReleaseBIT - ipv4: %d.%d.%d.%d, ipv6: %s",
1034                 (unsigned char)(mSubscriber.ID>>24),
1035                 (unsigned char)(mSubscriber.ID>>16),
1036                 (unsigned char)(mSubscriber.ID>>8),
1037                 (unsigned char)mSubscriber.ID,
1038                 NULL != mSubscriber.mIPv6Addr ? mSubscriber.mIPv6Addr : "");
1039    }
1040    virtual void log() const {
1041        locallog();
1042    }
1043};
1044
1045//        LocEngSuplEsOpened
1046LocEngSuplEsOpened::LocEngSuplEsOpened(void* locEng) :
1047    LocMsg(), mLocEng(locEng) {
1048    locallog();
1049}
1050void LocEngSuplEsOpened::proc() const {
1051    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1052    if (locEng->ds_nif) {
1053        AgpsStateMachine* sm = locEng->ds_nif;
1054        sm->onRsrcEvent(RSRC_GRANTED);
1055    }
1056}
1057void LocEngSuplEsOpened::locallog() const {
1058    LOC_LOGV("LocEngSuplEsOpened");
1059}
1060void LocEngSuplEsOpened::log() const {
1061    locallog();
1062}
1063
1064//        LocEngSuplEsClosed
1065LocEngSuplEsClosed::LocEngSuplEsClosed(void* locEng) :
1066    LocMsg(), mLocEng(locEng) {
1067    locallog();
1068}
1069void LocEngSuplEsClosed::proc() const {
1070    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1071    if (locEng->ds_nif) {
1072        AgpsStateMachine* sm = locEng->ds_nif;
1073        sm->onRsrcEvent(RSRC_RELEASED);
1074    }
1075}
1076void LocEngSuplEsClosed::locallog() const {
1077    LOC_LOGV("LocEngSuplEsClosed");
1078}
1079void LocEngSuplEsClosed::log() const {
1080    locallog();
1081}
1082
1083
1084//        case LOC_ENG_MSG_REQUEST_SUPL_ES:
1085LocEngRequestSuplEs::LocEngRequestSuplEs(void* locEng, int id) :
1086    LocMsg(), mLocEng(locEng), mID(id) {
1087    locallog();
1088}
1089void LocEngRequestSuplEs::proc() const {
1090    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1091    if (locEng->ds_nif) {
1092        AgpsStateMachine* sm = locEng->ds_nif;
1093        DSSubscriber s(sm, mID);
1094        sm->subscribeRsrc((Subscriber*)&s);
1095    }
1096    else if (locEng->agnss_nif) {
1097        AgpsStateMachine *sm = locEng->agnss_nif;
1098        ATLSubscriber s(mID,
1099                        sm,
1100                        locEng->adapter,
1101                        false);
1102        sm->subscribeRsrc((Subscriber*)&s);
1103        LOC_LOGD("%s:%d]: Using regular ATL for SUPL ES", __func__, __LINE__);
1104    }
1105    else {
1106        locEng->adapter->atlOpenStatus(mID, 0, NULL, -1, -1);
1107    }
1108}
1109inline void LocEngRequestSuplEs::locallog() const {
1110    LOC_LOGV("LocEngRequestSuplEs");
1111}
1112inline void LocEngRequestSuplEs::log() const {
1113    locallog();
1114}
1115
1116//        case LOC_ENG_MSG_REQUEST_ATL:
1117LocEngRequestATL::LocEngRequestATL(void* locEng, int id,
1118                                   AGpsExtType agps_type) :
1119    LocMsg(), mLocEng(locEng), mID(id), mType(agps_type) {
1120    locallog();
1121}
1122void LocEngRequestATL::proc() const {
1123    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1124    AgpsStateMachine* sm = (AgpsStateMachine*)
1125                           getAgpsStateMachine(*locEng, mType);
1126    if (sm) {
1127        ATLSubscriber s(mID,
1128                        sm,
1129                        locEng->adapter,
1130                        AGPS_TYPE_INVALID == mType);
1131        sm->subscribeRsrc((Subscriber*)&s);
1132    } else {
1133        locEng->adapter->atlOpenStatus(mID, 0, NULL, -1, mType);
1134    }
1135}
1136inline void LocEngRequestATL::locallog() const {
1137    LOC_LOGV("LocEngRequestATL");
1138}
1139inline void LocEngRequestATL::log() const {
1140    locallog();
1141}
1142
1143//        case LOC_ENG_MSG_RELEASE_ATL:
1144LocEngReleaseATL::LocEngReleaseATL(void* locEng, int id) :
1145    LocMsg(), mLocEng(locEng), mID(id) {
1146    locallog();
1147}
1148void LocEngReleaseATL::proc() const {
1149    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1150
1151   if (locEng->agnss_nif) {
1152        ATLSubscriber s1(mID, locEng->agnss_nif, locEng->adapter, false);
1153        if (locEng->agnss_nif->unsubscribeRsrc((Subscriber*)&s1)) {
1154            LOC_LOGD("%s:%d]: Unsubscribed from agnss_nif",
1155                     __func__, __LINE__);
1156            return;
1157        }
1158    }
1159
1160    if (locEng->internet_nif) {
1161        ATLSubscriber s2(mID, locEng->internet_nif, locEng->adapter, false);
1162        if (locEng->internet_nif->unsubscribeRsrc((Subscriber*)&s2)) {
1163            LOC_LOGD("%s:%d]: Unsubscribed from internet_nif",
1164                     __func__, __LINE__);
1165            return;
1166        }
1167    }
1168
1169    if (locEng->ds_nif) {
1170        DSSubscriber s3(locEng->ds_nif, mID);
1171        if (locEng->ds_nif->unsubscribeRsrc((Subscriber*)&s3)) {
1172            LOC_LOGD("%s:%d]: Unsubscribed from ds_nif",
1173                     __func__, __LINE__);
1174            return;
1175        }
1176    }
1177
1178    LOC_LOGW("%s:%d]: Could not release ATL. "
1179             "No subscribers found\n",
1180             __func__, __LINE__);
1181    locEng->adapter->atlCloseStatus(mID, 0);
1182}
1183inline void LocEngReleaseATL::locallog() const {
1184    LOC_LOGV("LocEngReleaseATL");
1185}
1186inline void LocEngReleaseATL::log() const {
1187    locallog();
1188}
1189
1190//        case LOC_ENG_MSG_REQUEST_WIFI:
1191//        case LOC_ENG_MSG_RELEASE_WIFI:
1192LocEngReqRelWifi::LocEngReqRelWifi(void* locEng, AGpsExtType type,
1193                                   loc_if_req_sender_id_e_type sender_id,
1194                                   char* s, char* p, bool isReq) :
1195    LocMsg(), mLocEng(locEng), mType(type), mSenderId(sender_id),
1196    mSSID(NULL == s ? NULL : new char[SSID_BUF_SIZE]),
1197    mPassword(NULL == p ? NULL : new char[SSID_BUF_SIZE]),
1198    mIsReq(isReq) {
1199    if (NULL != s)
1200        strlcpy(mSSID, s, SSID_BUF_SIZE);
1201    if (NULL != p)
1202        strlcpy(mPassword, p, SSID_BUF_SIZE);
1203    locallog();
1204}
1205LocEngReqRelWifi::~LocEngReqRelWifi() {
1206    if (NULL != mSSID) {
1207        delete[] mSSID;
1208    }
1209    if (NULL != mPassword) {
1210        delete[] mPassword;
1211    }
1212}
1213void LocEngReqRelWifi::proc() const {
1214    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1215    if (locEng->wifi_nif) {
1216        WIFISubscriber s(locEng->wifi_nif, mSSID, mPassword, mSenderId);
1217        if (mIsReq) {
1218            locEng->wifi_nif->subscribeRsrc((Subscriber*)&s);
1219        } else {
1220            locEng->wifi_nif->unsubscribeRsrc((Subscriber*)&s);
1221        }
1222    } else {
1223        locEng->adapter->atlOpenStatus(mSenderId, 0, NULL, -1, mType);
1224    }
1225}
1226inline void LocEngReqRelWifi::locallog() const {
1227    LOC_LOGV("%s - senderId: %d, ssid: %s, password: %s",
1228             mIsReq ? "LocEngRequestWifi" : "LocEngReleaseWifi",
1229             mSenderId,
1230             NULL != mSSID ? mSSID : "",
1231             NULL != mPassword ? mPassword : "");
1232}
1233inline void LocEngReqRelWifi::log() const {
1234    locallog();
1235}
1236void LocEngReqRelWifi::send() const {
1237    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1238    locEng->adapter->sendMsg(this);
1239}
1240
1241//        case LOC_ENG_MSG_REQUEST_XTRA_DATA:
1242LocEngRequestXtra::LocEngRequestXtra(void* locEng) :
1243    mLocEng(locEng) {
1244    locallog();
1245}
1246void LocEngRequestXtra::proc() const
1247{
1248    loc_eng_xtra_data_s_type* locEngXtra =
1249        &(((loc_eng_data_s_type*)mLocEng)->xtra_module_data);
1250
1251    if (locEngXtra->download_request_cb != NULL) {
1252        CALLBACK_LOG_CALLFLOW("download_request_cb", %p, mLocEng);
1253        locEngXtra->download_request_cb();
1254    } else {
1255        LOC_LOGE("Callback function for request xtra is NULL");
1256    }
1257}
1258inline void LocEngRequestXtra::locallog() const {
1259    LOC_LOGV("LocEngReqXtra");
1260}
1261inline void LocEngRequestXtra::log() const {
1262    locallog();
1263}
1264
1265//        case LOC_ENG_MSG_REQUEST_TIME:
1266LocEngRequestTime::LocEngRequestTime(void* locEng) :
1267    LocMsg(), mLocEng(locEng)
1268{
1269    locallog();
1270}
1271void LocEngRequestTime::proc() const {
1272    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1273    if (gps_conf.CAPABILITIES & GPS_CAPABILITY_ON_DEMAND_TIME) {
1274        if (locEng->request_utc_time_cb != NULL) {
1275            locEng->request_utc_time_cb();
1276        } else {
1277            LOC_LOGE("Callback function for request time is NULL");
1278        }
1279    }
1280}
1281inline void LocEngRequestTime::locallog() const {
1282    LOC_LOGV("LocEngReqTime");
1283}
1284inline void LocEngRequestTime::log() const {
1285    locallog();
1286}
1287
1288//        case LOC_ENG_MSG_DELETE_AIDING_DATA:
1289struct LocEngDelAidData : public LocMsg {
1290    loc_eng_data_s_type* mLocEng;
1291    const GpsAidingData mType;
1292    inline LocEngDelAidData(loc_eng_data_s_type* locEng,
1293                            GpsAidingData f) :
1294        LocMsg(), mLocEng(locEng), mType(f)
1295    {
1296        locallog();
1297    }
1298    inline virtual void proc() const {
1299        mLocEng->aiding_data_for_deletion = mType;
1300        update_aiding_data_for_deletion(*mLocEng);
1301    }
1302    inline void locallog() const {
1303        LOC_LOGV("aiding data msak %d", mType);
1304    }
1305    virtual void log() const {
1306        locallog();
1307    }
1308};
1309
1310//        case LOC_ENG_MSG_ENABLE_DATA:
1311struct LocEngEnableData : public LocMsg {
1312    LocEngAdapter* mAdapter;
1313    const int mEnable;
1314    char* mAPN;
1315    const int mLen;
1316    inline LocEngEnableData(LocEngAdapter* adapter,
1317                            const char* name, int len, int enable) :
1318        LocMsg(), mAdapter(adapter),
1319        mEnable(enable), mAPN(NULL), mLen(len)
1320    {
1321        if (NULL != name) {
1322            mAPN = new char[len+1];
1323            memcpy((void*)mAPN, (void*)name, len);
1324            mAPN[len] = 0;
1325        }
1326        locallog();
1327    }
1328    inline ~LocEngEnableData() {
1329        if (NULL != mAPN) {
1330            delete[] mAPN;
1331        }
1332    }
1333    inline virtual void proc() const {
1334        mAdapter->enableData(mEnable);
1335        if (NULL != mAPN) {
1336            mAdapter->setAPN(mAPN, mLen);
1337        }
1338    }
1339    inline void locallog() const {
1340        LOC_LOGV("apn: %s\n  enable: %d",
1341                 (NULL == mAPN) ? "NULL" : mAPN, mEnable);
1342    }
1343    inline virtual void log() const {
1344        locallog();
1345    }
1346};
1347
1348//        case LOC_ENG_MSG_INJECT_XTRA_DATA:
1349// loc_eng_xtra.cpp
1350
1351//        case LOC_ENG_MSG_SET_CAPABILITIES:
1352struct LocEngSetCapabilities : public LocMsg {
1353    loc_eng_data_s_type* mLocEng;
1354    inline LocEngSetCapabilities(loc_eng_data_s_type* locEng) :
1355        LocMsg(), mLocEng(locEng)
1356    {
1357        locallog();
1358    }
1359    inline virtual void proc() const {
1360        if (NULL != mLocEng->set_capabilities_cb) {
1361            LOC_LOGV("calling set_capabilities_cb 0x%x",
1362                     gps_conf.CAPABILITIES);
1363            mLocEng->set_capabilities_cb(gps_conf.CAPABILITIES);
1364        } else {
1365            LOC_LOGV("set_capabilities_cb is NULL.\n");
1366        }
1367    }
1368    inline void locallog() const
1369    {
1370        LOC_LOGV("LocEngSetCapabilities");
1371    }
1372    inline virtual void log() const
1373    {
1374        locallog();
1375    }
1376};
1377
1378//        case LOC_ENG_MSG_LOC_INIT:
1379struct LocEngInit : public LocMsg {
1380    loc_eng_data_s_type* mLocEng;
1381    inline LocEngInit(loc_eng_data_s_type* locEng) :
1382        LocMsg(), mLocEng(locEng)
1383    {
1384        locallog();
1385    }
1386    inline virtual void proc() const {
1387        loc_eng_reinit(*mLocEng);
1388        // set the capabilities
1389        mLocEng->adapter->sendMsg(new LocEngSetCapabilities(mLocEng));
1390    }
1391    inline void locallog() const
1392    {
1393        LOC_LOGV("LocEngInit");
1394    }
1395    inline virtual void log() const
1396    {
1397        locallog();
1398    }
1399};
1400
1401//        case LOC_ENG_MSG_REQUEST_XTRA_SERVER:
1402// loc_eng_xtra.cpp
1403
1404//        case LOC_ENG_MSG_ATL_OPEN_SUCCESS:
1405struct LocEngAtlOpenSuccess : public LocMsg {
1406    AgpsStateMachine* mStateMachine;
1407    const int mLen;
1408    char* mAPN;
1409    const AGpsBearerType mBearerType;
1410    inline LocEngAtlOpenSuccess(AgpsStateMachine* statemachine,
1411                                const char* name,
1412                                int len,
1413                                AGpsBearerType btype) :
1414        LocMsg(),
1415        mStateMachine(statemachine), mLen(len),
1416        mAPN(new char[len+1]), mBearerType(btype)
1417    {
1418        memcpy((void*)mAPN, (void*)name, len);
1419        mAPN[len] = 0;
1420        locallog();
1421    }
1422    inline ~LocEngAtlOpenSuccess()
1423    {
1424        delete[] mAPN;
1425    }
1426    inline virtual void proc() const {
1427        mStateMachine->setBearer(mBearerType);
1428        mStateMachine->setAPN(mAPN, mLen);
1429        mStateMachine->onRsrcEvent(RSRC_GRANTED);
1430    }
1431    inline void locallog() const {
1432        LOC_LOGV("LocEngAtlOpenSuccess agps type: %s\n  apn: %s\n"
1433                 "  bearer type: %s",
1434                 loc_get_agps_type_name(mStateMachine->getType()),
1435                 mAPN,
1436                 loc_get_agps_bear_name(mBearerType));
1437    }
1438    inline virtual void log() const {
1439        locallog();
1440    }
1441};
1442
1443//        case LOC_ENG_MSG_ATL_CLOSED:
1444struct LocEngAtlClosed : public LocMsg {
1445    AgpsStateMachine* mStateMachine;
1446    inline LocEngAtlClosed(AgpsStateMachine* statemachine) :
1447        LocMsg(), mStateMachine(statemachine) {
1448        locallog();
1449    }
1450    inline virtual void proc() const {
1451        mStateMachine->onRsrcEvent(RSRC_RELEASED);
1452    }
1453    inline void locallog() const {
1454        LOC_LOGV("LocEngAtlClosed");
1455    }
1456    inline virtual void log() const {
1457        locallog();
1458    }
1459};
1460
1461//        case LOC_ENG_MSG_ATL_OPEN_FAILED:
1462struct LocEngAtlOpenFailed : public LocMsg {
1463    AgpsStateMachine* mStateMachine;
1464    inline LocEngAtlOpenFailed(AgpsStateMachine* statemachine) :
1465        LocMsg(), mStateMachine(statemachine) {
1466        locallog();
1467    }
1468    inline virtual void proc() const {
1469        mStateMachine->onRsrcEvent(RSRC_DENIED);
1470    }
1471    inline void locallog() const {
1472        LOC_LOGV("LocEngAtlOpenFailed");
1473    }
1474    inline virtual void log() const {
1475        locallog();
1476    }
1477};
1478
1479//        case LOC_ENG_MSG_ENGINE_DOWN:
1480LocEngDown::LocEngDown(void* locEng) :
1481    LocMsg(), mLocEng(locEng) {
1482    locallog();
1483}
1484inline void LocEngDown::proc() const {
1485    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1486    loc_eng_handle_engine_down(*locEng);
1487}
1488inline void LocEngDown::locallog() const {
1489    LOC_LOGV("LocEngDown");
1490}
1491inline void LocEngDown::log() const {
1492    locallog();
1493}
1494
1495//        case LOC_ENG_MSG_ENGINE_UP:
1496LocEngUp::LocEngUp(void* locEng) :
1497    LocMsg(), mLocEng(locEng) {
1498    locallog();
1499}
1500inline void LocEngUp::proc() const {
1501    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
1502    loc_eng_handle_engine_up(*locEng);
1503}
1504inline void LocEngUp::locallog() const {
1505    LOC_LOGV("LocEngUp");
1506}
1507inline void LocEngUp::log() const {
1508    locallog();
1509}
1510
1511struct LocEngDataClientInit : public LocMsg {
1512    loc_eng_data_s_type* mLocEng;
1513    inline LocEngDataClientInit(loc_eng_data_s_type* locEng) :
1514        LocMsg(), mLocEng(locEng) {
1515        locallog();
1516    }
1517    virtual void proc() const {
1518        loc_eng_data_s_type *locEng = (loc_eng_data_s_type *)mLocEng;
1519        if(!locEng->adapter->initDataServiceClient()) {
1520            locEng->ds_nif = new DSStateMachine(servicerTypeExt,
1521                                               (void *)dataCallCb,
1522                                               locEng->adapter);
1523        }
1524    }
1525    void locallog() const {
1526        LOC_LOGV("LocEngDataClientInit\n");
1527    }
1528    virtual void log() const {
1529        locallog();
1530    }
1531};
1532
1533struct LocEngInstallAGpsCert : public LocMsg {
1534    LocEngAdapter* mpAdapter;
1535    const size_t mNumberOfCerts;
1536    const uint32_t mSlotBitMask;
1537    DerEncodedCertificate* mpData;
1538    inline LocEngInstallAGpsCert(LocEngAdapter* adapter,
1539                              const DerEncodedCertificate* pData,
1540                              size_t numberOfCerts,
1541                              uint32_t slotBitMask) :
1542        LocMsg(), mpAdapter(adapter),
1543        mNumberOfCerts(numberOfCerts), mSlotBitMask(slotBitMask),
1544        mpData(new DerEncodedCertificate[mNumberOfCerts])
1545    {
1546        for (int i=0; i < mNumberOfCerts; i++) {
1547            mpData[i].data = new u_char[pData[i].length];
1548            if (mpData[i].data) {
1549                memcpy(mpData[i].data, (void*)pData[i].data, pData[i].length);
1550                mpData[i].length = pData[i].length;
1551            } else {
1552                LOC_LOGE("malloc failed for cert#%d", i);
1553                break;
1554            }
1555        }
1556        locallog();
1557    }
1558    inline ~LocEngInstallAGpsCert()
1559    {
1560        for (int i=0; i < mNumberOfCerts; i++) {
1561            if (mpData[i].data) {
1562                delete[] mpData[i].data;
1563            }
1564        }
1565        delete[] mpData;
1566    }
1567    inline virtual void proc() const {
1568        mpAdapter->installAGpsCert(mpData, mNumberOfCerts, mSlotBitMask);
1569    }
1570    inline void locallog() const {
1571        LOC_LOGV("LocEngInstallAGpsCert - certs=%u mask=%u",
1572                 mNumberOfCerts, mSlotBitMask);
1573    }
1574    inline virtual void log() const {
1575        locallog();
1576    }
1577};
1578
1579struct LocEngUpdateRegistrationMask : public LocMsg {
1580    loc_eng_data_s_type* mLocEng;
1581    LOC_API_ADAPTER_EVENT_MASK_T mMask;
1582    loc_registration_mask_status mIsEnabled;
1583    inline LocEngUpdateRegistrationMask(loc_eng_data_s_type* locEng,
1584                                        LOC_API_ADAPTER_EVENT_MASK_T mask,
1585                                        loc_registration_mask_status isEnabled) :
1586        LocMsg(), mLocEng(locEng), mMask(mask), mIsEnabled(isEnabled) {
1587        locallog();
1588    }
1589    inline virtual void proc() const {
1590        loc_eng_data_s_type *locEng = (loc_eng_data_s_type *)mLocEng;
1591        locEng->adapter->updateRegistrationMask(mMask,
1592                                                mIsEnabled);
1593    }
1594    void locallog() const {
1595        LOC_LOGV("LocEngUpdateRegistrationMask\n");
1596    }
1597    virtual void log() const {
1598        locallog();
1599    }
1600};
1601
1602struct LocEngGnssConstellationConfig : public LocMsg {
1603    LocEngAdapter* mAdapter;
1604    inline LocEngGnssConstellationConfig(LocEngAdapter* adapter) :
1605        LocMsg(), mAdapter(adapter) {
1606        locallog();
1607    }
1608    inline virtual void proc() const {
1609        if (mAdapter->gnssConstellationConfig()) {
1610            LOC_LOGV("Modem supports GNSS measurements\n");
1611            gps_conf.CAPABILITIES |= GPS_CAPABILITY_MEASUREMENTS;
1612        } else {
1613            LOC_LOGV("Modem does not support GNSS measurements\n");
1614        }
1615    }
1616    void locallog() const {
1617        LOC_LOGV("LocEngGnssConstellationConfig\n");
1618    }
1619    virtual void log() const {
1620        locallog();
1621    }
1622};
1623
1624//        case LOC_ENG_MSG_REPORT_GNSS_MEASUREMENT:
1625LocEngReportGpsMeasurement::LocEngReportGpsMeasurement(void* locEng,
1626                                                       GpsData &gpsData) :
1627    LocMsg(), mLocEng(locEng), mGpsData(gpsData)
1628{
1629    locallog();
1630}
1631void LocEngReportGpsMeasurement::proc() const {
1632    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*) mLocEng;
1633    if (locEng->mute_session_state != LOC_MUTE_SESS_IN_SESSION)
1634    {
1635        if (locEng->gps_measurement_cb != NULL) {
1636            locEng->gps_measurement_cb((GpsData*)&(mGpsData));
1637        }
1638    }
1639}
1640void LocEngReportGpsMeasurement::locallog() const {
1641    IF_LOC_LOGV {
1642        LOC_LOGV("%s:%d]: Received in GPS HAL."
1643                 "GNSS Measurements count: %d \n",
1644                 __func__, __LINE__, mGpsData.measurement_count);
1645        for (int i =0; i< mGpsData.measurement_count && i < GPS_MAX_SVS; i++) {
1646                LOC_LOGV(" GNSS measurement data in GPS HAL: \n"
1647                         " GPS_HAL => Measurement ID | prn | time_offset_ns | state |"
1648                         " received_gps_tow_ns| c_n0_dbhz | pseudorange_rate_mps |"
1649                         " pseudorange_rate_uncertainty_mps |"
1650                         " accumulated_delta_range_state | flags \n"
1651                         " GPS_HAL => %d | %d | %f | %d | %lld | %f | %f | %f | %d | %d \n",
1652                         i,
1653                         mGpsData.measurements[i].prn,
1654                         mGpsData.measurements[i].time_offset_ns,
1655                         mGpsData.measurements[i].state,
1656                         mGpsData.measurements[i].received_gps_tow_ns,
1657                         mGpsData.measurements[i].c_n0_dbhz,
1658                         mGpsData.measurements[i].pseudorange_rate_mps,
1659                         mGpsData.measurements[i].pseudorange_rate_uncertainty_mps,
1660                         mGpsData.measurements[i].accumulated_delta_range_state,
1661                         mGpsData.measurements[i].flags);
1662        }
1663        LOC_LOGV(" GPS_HAL => Clocks Info: type | time_ns \n"
1664                 " GPS_HAL => Clocks Info: %d | %lld", mGpsData.clock.type,
1665                 mGpsData.clock.time_ns);
1666    }
1667}
1668inline void LocEngReportGpsMeasurement::log() const {
1669    locallog();
1670}
1671
1672/*********************************************************************
1673 * Initialization checking macros
1674 *********************************************************************/
1675#define STATE_CHECK(ctx, x, ret) \
1676    if (!(ctx))                  \
1677  {                              \
1678      /* Not intialized, abort */\
1679      LOC_LOGE("%s: log_eng state error: %s", __func__, x); \
1680      EXIT_LOG(%s, x);                                            \
1681      ret;                                                        \
1682  }
1683#define INIT_CHECK(ctx, ret) STATE_CHECK(ctx, "instance not initialized", ret)
1684
1685uint32_t getCarrierCapabilities() {
1686    #define carrierMSA (uint32_t)0x2
1687    #define carrierMSB (uint32_t)0x1
1688    #define gpsConfMSA (uint32_t)0x4
1689    #define gpsConfMSB (uint32_t)0x2
1690    uint32_t capabilities = gps_conf.CAPABILITIES;
1691    if ((gps_conf.SUPL_MODE & carrierMSA) != carrierMSA) {
1692        capabilities &= ~gpsConfMSA;
1693    }
1694    if ((gps_conf.SUPL_MODE & carrierMSB) != carrierMSB) {
1695        capabilities &= ~gpsConfMSB;
1696    }
1697
1698    LOC_LOGV("getCarrierCapabilities: CAPABILITIES %x, SUPL_MODE %x, carrier capabilities %x",
1699             gps_conf.CAPABILITIES, gps_conf.SUPL_MODE, capabilities);
1700    return capabilities;
1701}
1702
1703/*===========================================================================
1704FUNCTION    loc_eng_init
1705
1706DESCRIPTION
1707   Initialize the location engine, this include setting up global datas
1708   and registers location engien with loc api service.
1709
1710DEPENDENCIES
1711   None
1712
1713RETURN VALUE
1714   0: success
1715
1716SIDE EFFECTS
1717   N/A
1718
1719===========================================================================*/
1720int loc_eng_init(loc_eng_data_s_type &loc_eng_data, LocCallbacks* callbacks,
1721                 LOC_API_ADAPTER_EVENT_MASK_T event, ContextBase* context)
1722
1723{
1724    int ret_val = 0;
1725
1726    ENTRY_LOG_CALLFLOW();
1727    if (NULL == callbacks || 0 == event) {
1728        LOC_LOGE("loc_eng_init: bad parameters cb %p eMask %d", callbacks, event);
1729        ret_val = -1;
1730        EXIT_LOG(%d, ret_val);
1731        return ret_val;
1732    }
1733
1734    STATE_CHECK((NULL == loc_eng_data.adapter),
1735                "instance already initialized", return 0);
1736
1737    memset(&loc_eng_data, 0, sizeof (loc_eng_data));
1738
1739    // Save callbacks
1740    loc_eng_data.location_cb  = callbacks->location_cb;
1741    loc_eng_data.sv_status_cb = callbacks->sv_status_cb;
1742    loc_eng_data.status_cb    = callbacks->status_cb;
1743    loc_eng_data.nmea_cb      = callbacks->nmea_cb;
1744    loc_eng_data.set_capabilities_cb = callbacks->set_capabilities_cb;
1745    loc_eng_data.acquire_wakelock_cb = callbacks->acquire_wakelock_cb;
1746    loc_eng_data.release_wakelock_cb = callbacks->release_wakelock_cb;
1747    loc_eng_data.request_utc_time_cb = callbacks->request_utc_time_cb;
1748    loc_eng_data.location_ext_parser = callbacks->location_ext_parser ?
1749        callbacks->location_ext_parser : noProc;
1750    loc_eng_data.sv_ext_parser = callbacks->sv_ext_parser ?
1751        callbacks->sv_ext_parser : noProc;
1752    loc_eng_data.intermediateFix = gps_conf.INTERMEDIATE_POS;
1753    // initial states taken care of by the memset above
1754    // loc_eng_data.engine_status -- GPS_STATUS_NONE;
1755    // loc_eng_data.fix_session_status -- GPS_STATUS_NONE;
1756    // loc_eng_data.mute_session_state -- LOC_MUTE_SESS_NONE;
1757
1758    if ((event & LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT) && (gps_conf.NMEA_PROVIDER == NMEA_PROVIDER_AP))
1759    {
1760        event = event ^ LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT; // unregister for modem NMEA report
1761        loc_eng_data.generateNmea = true;
1762    }
1763    else
1764    {
1765        loc_eng_data.generateNmea = false;
1766    }
1767
1768    loc_eng_data.adapter =
1769        new LocEngAdapter(event, &loc_eng_data, context,
1770                          (MsgTask::tCreate)callbacks->create_thread_cb);
1771
1772    LOC_LOGD("loc_eng_init created client, id = %p\n",
1773             loc_eng_data.adapter);
1774    loc_eng_data.adapter->sendMsg(new LocEngInit(&loc_eng_data));
1775
1776    EXIT_LOG(%d, ret_val);
1777    return ret_val;
1778}
1779
1780static int loc_eng_reinit(loc_eng_data_s_type &loc_eng_data)
1781{
1782    ENTRY_LOG();
1783    int ret_val = LOC_API_ADAPTER_ERR_SUCCESS;
1784    LocEngAdapter* adapter = loc_eng_data.adapter;
1785
1786    adapter->sendMsg(new LocEngGnssConstellationConfig(adapter));
1787    adapter->sendMsg(new LocEngSuplVer(adapter, gps_conf.SUPL_VER));
1788    adapter->sendMsg(new LocEngLppConfig(adapter, gps_conf.LPP_PROFILE));
1789    adapter->sendMsg(new LocEngSensorControlConfig(adapter, sap_conf.SENSOR_USAGE,
1790                                                   sap_conf.SENSOR_PROVIDER));
1791    adapter->sendMsg(new LocEngAGlonassProtocol(adapter, gps_conf.A_GLONASS_POS_PROTOCOL_SELECT));
1792
1793    /* Make sure at least one of the sensor property is specified by the user in the gps.conf file. */
1794    if( sap_conf.GYRO_BIAS_RANDOM_WALK_VALID ||
1795        sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
1796        sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
1797        sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
1798        sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID ) {
1799        adapter->sendMsg(new LocEngSensorProperties(adapter,
1800                                                    sap_conf.GYRO_BIAS_RANDOM_WALK_VALID,
1801                                                    sap_conf.GYRO_BIAS_RANDOM_WALK,
1802                                                    sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
1803                                                    sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY,
1804                                                    sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
1805                                                    sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY,
1806                                                    sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
1807                                                    sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY,
1808                                                    sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
1809                                                    sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY));
1810    }
1811
1812    adapter->sendMsg(new LocEngSensorPerfControlConfig(adapter,
1813                                                       sap_conf.SENSOR_CONTROL_MODE,
1814                                                       sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH,
1815                                                       sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC,
1816                                                       sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH,
1817                                                       sap_conf.SENSOR_GYRO_BATCHES_PER_SEC,
1818                                                       sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH,
1819                                                       sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH,
1820                                                       sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH,
1821                                                       sap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH,
1822                                                       sap_conf.SENSOR_ALGORITHM_CONFIG_MASK));
1823
1824    adapter->sendMsg(new LocEngEnableData(adapter, NULL, 0, (agpsStatus ? 1:0)));
1825
1826    loc_eng_xtra_version_check(loc_eng_data, gps_conf.XTRA_VERSION_CHECK);
1827
1828    LOC_LOGD("loc_eng_reinit reinit() successful");
1829    EXIT_LOG(%d, ret_val);
1830    return ret_val;
1831}
1832
1833/*===========================================================================
1834FUNCTION    loc_eng_cleanup
1835
1836DESCRIPTION
1837   Cleans location engine. The location client handle will be released.
1838
1839DEPENDENCIES
1840   None
1841
1842RETURN VALUE
1843   None
1844
1845SIDE EFFECTS
1846   N/A
1847
1848===========================================================================*/
1849void loc_eng_cleanup(loc_eng_data_s_type &loc_eng_data)
1850{
1851    ENTRY_LOG_CALLFLOW();
1852    INIT_CHECK(loc_eng_data.adapter, return);
1853
1854    // XTRA has no state, so we are fine with it.
1855
1856    // we need to check and clear NI
1857#if 0
1858    // we need to check and clear ATL
1859    if (NULL != loc_eng_data.agnss_nif) {
1860        delete loc_eng_data.agnss_nif;
1861        loc_eng_data.agnss_nif = NULL;
1862    }
1863    if (NULL != loc_eng_data.internet_nif) {
1864        delete loc_eng_data.internet_nif;
1865        loc_eng_data.internet_nif = NULL;
1866    }
1867#endif
1868    if (loc_eng_data.adapter->isInSession())
1869    {
1870        LOC_LOGD("loc_eng_cleanup: fix not stopped. stop it now.");
1871        loc_eng_stop(loc_eng_data);
1872    }
1873
1874#if 0 // can't afford to actually clean up, for many reason.
1875
1876    LOC_LOGD("loc_eng_init: client opened. close it now.");
1877    delete loc_eng_data.adapter;
1878    loc_eng_data.adapter = NULL;
1879
1880    loc_eng_dmn_conn_loc_api_server_unblock();
1881    loc_eng_dmn_conn_loc_api_server_join();
1882
1883#endif
1884
1885    EXIT_LOG(%s, VOID_RET);
1886}
1887
1888
1889/*===========================================================================
1890FUNCTION    loc_eng_start
1891
1892DESCRIPTION
1893   Starts the tracking session
1894
1895DEPENDENCIES
1896   None
1897
1898RETURN VALUE
1899   0: success
1900
1901SIDE EFFECTS
1902   N/A
1903
1904===========================================================================*/
1905int loc_eng_start(loc_eng_data_s_type &loc_eng_data)
1906{
1907   ENTRY_LOG_CALLFLOW();
1908   INIT_CHECK(loc_eng_data.adapter, return -1);
1909
1910   if(! loc_eng_data.adapter->getUlpProxy()->sendStartFix())
1911   {
1912       loc_eng_data.adapter->sendMsg(new LocEngStartFix(loc_eng_data.adapter));
1913   }
1914
1915   EXIT_LOG(%d, 0);
1916   return 0;
1917}
1918
1919static int loc_eng_start_handler(loc_eng_data_s_type &loc_eng_data)
1920{
1921   ENTRY_LOG();
1922   int ret_val = LOC_API_ADAPTER_ERR_SUCCESS;
1923
1924   if (!loc_eng_data.adapter->isInSession()) {
1925       ret_val = loc_eng_data.adapter->startFix();
1926
1927       if (ret_val == LOC_API_ADAPTER_ERR_SUCCESS ||
1928           ret_val == LOC_API_ADAPTER_ERR_ENGINE_DOWN ||
1929           ret_val == LOC_API_ADAPTER_ERR_PHONE_OFFLINE ||
1930           ret_val == LOC_API_ADAPTER_ERR_INTERNAL)
1931       {
1932           loc_eng_data.adapter->setInSession(TRUE);
1933       }
1934   }
1935
1936   EXIT_LOG(%d, ret_val);
1937   return ret_val;
1938}
1939
1940/*===========================================================================
1941FUNCTION    loc_eng_stop_wrapper
1942
1943DESCRIPTION
1944   Stops the tracking session
1945
1946DEPENDENCIES
1947   None
1948
1949RETURN VALUE
1950   0: success
1951
1952SIDE EFFECTS
1953   N/A
1954
1955===========================================================================*/
1956int loc_eng_stop(loc_eng_data_s_type &loc_eng_data)
1957{
1958    ENTRY_LOG_CALLFLOW();
1959    INIT_CHECK(loc_eng_data.adapter, return -1);
1960
1961    if(! loc_eng_data.adapter->getUlpProxy()->sendStopFix())
1962    {
1963        loc_eng_data.adapter->sendMsg(new LocEngStopFix(loc_eng_data.adapter));
1964    }
1965
1966    EXIT_LOG(%d, 0);
1967    return 0;
1968}
1969
1970static int loc_eng_stop_handler(loc_eng_data_s_type &loc_eng_data)
1971{
1972   ENTRY_LOG();
1973   int ret_val = LOC_API_ADAPTER_ERR_SUCCESS;
1974
1975   if (loc_eng_data.adapter->isInSession()) {
1976
1977       ret_val = loc_eng_data.adapter->stopFix();
1978       loc_eng_data.adapter->setInSession(FALSE);
1979   }
1980
1981    EXIT_LOG(%d, ret_val);
1982    return ret_val;
1983}
1984
1985/*===========================================================================
1986FUNCTION    loc_eng_mute_one_session
1987
1988DESCRIPTION
1989   Mutes one session
1990
1991DEPENDENCIES
1992   None
1993
1994RETURN VALUE
1995   0: Success
1996
1997SIDE EFFECTS
1998   N/A
1999
2000===========================================================================*/
2001void loc_eng_mute_one_session(loc_eng_data_s_type &loc_eng_data)
2002{
2003    ENTRY_LOG();
2004    loc_eng_data.mute_session_state = LOC_MUTE_SESS_WAIT;
2005    EXIT_LOG(%s, VOID_RET);
2006}
2007
2008/*===========================================================================
2009FUNCTION    loc_eng_set_position_mode
2010
2011DESCRIPTION
2012   Sets the mode and fix frequency for the tracking session.
2013
2014DEPENDENCIES
2015   None
2016
2017RETURN VALUE
2018   0: success
2019
2020SIDE EFFECTS
2021   N/A
2022
2023===========================================================================*/
2024int loc_eng_set_position_mode(loc_eng_data_s_type &loc_eng_data,
2025                              LocPosMode &params)
2026{
2027    ENTRY_LOG_CALLFLOW();
2028    INIT_CHECK(loc_eng_data.adapter, return -1);
2029
2030    // The position mode for AUTO/GSS/QCA1530 can only be standalone
2031    if (!(gps_conf.CAPABILITIES & GPS_CAPABILITY_MSB) &&
2032        !(gps_conf.CAPABILITIES & GPS_CAPABILITY_MSA) &&
2033        (params.mode != LOC_POSITION_MODE_STANDALONE)) {
2034        params.mode = LOC_POSITION_MODE_STANDALONE;
2035        LOC_LOGD("Position mode changed to standalone for target with AUTO/GSS/qca1530.");
2036    }
2037
2038    if(! loc_eng_data.adapter->getUlpProxy()->sendFixMode(params))
2039    {
2040        LocEngAdapter* adapter = loc_eng_data.adapter;
2041        adapter->sendMsg(new LocEngPositionMode(adapter, params));
2042    }
2043
2044    EXIT_LOG(%d, 0);
2045    return 0;
2046}
2047
2048/*===========================================================================
2049FUNCTION    loc_eng_inject_time
2050
2051DESCRIPTION
2052   This is used by Java native function to do time injection.
2053
2054DEPENDENCIES
2055   None
2056
2057RETURN VALUE
2058   0
2059
2060SIDE EFFECTS
2061   N/A
2062
2063===========================================================================*/
2064int loc_eng_inject_time(loc_eng_data_s_type &loc_eng_data, GpsUtcTime time,
2065                        int64_t timeReference, int uncertainty)
2066{
2067    ENTRY_LOG_CALLFLOW();
2068    INIT_CHECK(loc_eng_data.adapter, return -1);
2069    LocEngAdapter* adapter = loc_eng_data.adapter;
2070
2071    adapter->sendMsg(new LocEngSetTime(adapter, time, timeReference,
2072                                       uncertainty));
2073
2074    EXIT_LOG(%d, 0);
2075    return 0;
2076}
2077
2078
2079/*===========================================================================
2080FUNCTION    loc_eng_inject_location
2081
2082DESCRIPTION
2083   This is used by Java native function to do location injection.
2084
2085DEPENDENCIES
2086   None
2087
2088RETURN VALUE
2089   0          : Successful
2090   error code : Failure
2091
2092SIDE EFFECTS
2093   N/A
2094===========================================================================*/
2095int loc_eng_inject_location(loc_eng_data_s_type &loc_eng_data, double latitude,
2096                            double longitude, float accuracy)
2097{
2098    ENTRY_LOG_CALLFLOW();
2099    INIT_CHECK(loc_eng_data.adapter, return -1);
2100    LocEngAdapter* adapter = loc_eng_data.adapter;
2101    if(adapter->mSupportsPositionInjection)
2102    {
2103        adapter->sendMsg(new LocEngInjectLocation(adapter, latitude, longitude,
2104                                                  accuracy));
2105    }
2106
2107    EXIT_LOG(%d, 0);
2108    return 0;
2109}
2110
2111
2112/*===========================================================================
2113FUNCTION    loc_eng_delete_aiding_data
2114
2115DESCRIPTION
2116   This is used by Java native function to delete the aiding data. The function
2117   updates the global variable for the aiding data to be deleted. If the GPS
2118   engine is off, the aiding data will be deleted. Otherwise, the actual action
2119   will happen when gps engine is turned off.
2120
2121DEPENDENCIES
2122   Assumes the aiding data type specified in GpsAidingData matches with
2123   LOC API specification.
2124
2125RETURN VALUE
2126   None
2127
2128SIDE EFFECTS
2129   N/A
2130
2131===========================================================================*/
2132void loc_eng_delete_aiding_data(loc_eng_data_s_type &loc_eng_data, GpsAidingData f)
2133{
2134    ENTRY_LOG_CALLFLOW();
2135    INIT_CHECK(loc_eng_data.adapter, return);
2136
2137    loc_eng_data.adapter->sendMsg(new LocEngDelAidData(&loc_eng_data, f));
2138
2139    EXIT_LOG(%s, VOID_RET);
2140}
2141
2142/*===========================================================================
2143
2144FUNCTION    loc_inform_gps_state
2145
2146DESCRIPTION
2147   Informs the GPS Provider about the GPS status
2148
2149DEPENDENCIES
2150   None
2151
2152RETURN VALUE
2153   None
2154
2155SIDE EFFECTS
2156   N/A
2157
2158===========================================================================*/
2159static void loc_inform_gps_status(loc_eng_data_s_type &loc_eng_data, GpsStatusValue status)
2160{
2161    ENTRY_LOG();
2162
2163    if (loc_eng_data.status_cb)
2164    {
2165        GpsStatus gs = { sizeof(gs),status };
2166        CALLBACK_LOG_CALLFLOW("status_cb", %s,
2167                              loc_get_gps_status_name(gs.status));
2168        loc_eng_data.status_cb(&gs);
2169    }
2170
2171    EXIT_LOG(%s, VOID_RET);
2172}
2173
2174static int loc_eng_get_zpp_handler(loc_eng_data_s_type &loc_eng_data)
2175{
2176   ENTRY_LOG();
2177   int ret_val = LOC_API_ADAPTER_ERR_SUCCESS;
2178   UlpLocation location;
2179   LocPosTechMask tech_mask = LOC_POS_TECH_MASK_DEFAULT;
2180   GpsLocationExtended locationExtended;
2181   memset(&locationExtended, 0, sizeof (GpsLocationExtended));
2182   locationExtended.size = sizeof(locationExtended);
2183
2184   ret_val = loc_eng_data.adapter->getZpp(location.gpsLocation, tech_mask);
2185  //Mark the location source as from ZPP
2186  location.gpsLocation.flags |= LOCATION_HAS_SOURCE_INFO;
2187  location.position_source = ULP_LOCATION_IS_FROM_ZPP;
2188
2189  loc_eng_data.adapter->getUlpProxy()->reportPosition(location,
2190                                     locationExtended,
2191                                     NULL,
2192                                     LOC_SESS_SUCCESS,
2193                                     tech_mask);
2194
2195  EXIT_LOG(%d, ret_val);
2196  return ret_val;
2197}
2198
2199/*
2200  Callback function passed to Data Services State Machine
2201  This becomes part of the state machine's servicer and
2202  is used to send requests to the data services client
2203*/
2204static int dataCallCb(void *cb_data)
2205{
2206    LOC_LOGD("Enter dataCallCb\n");
2207    int ret=0;
2208    if(cb_data != NULL) {
2209        dsCbData *cbData = (dsCbData *)cb_data;
2210        LocEngAdapter *locAdapter = (LocEngAdapter *)cbData->mAdapter;
2211        if(cbData->action == GPS_REQUEST_AGPS_DATA_CONN) {
2212            LOC_LOGD("dataCallCb GPS_REQUEST_AGPS_DATA_CONN\n");
2213            ret =  locAdapter->openAndStartDataCall();
2214        }
2215        else if(cbData->action == GPS_RELEASE_AGPS_DATA_CONN) {
2216            LOC_LOGD("dataCallCb GPS_RELEASE_AGPS_DATA_CONN\n");
2217            locAdapter->stopDataCall();
2218        }
2219    }
2220    else {
2221        LOC_LOGE("NULL argument received. Failing.\n");
2222        ret = -1;
2223        goto err;
2224    }
2225
2226err:
2227    LOC_LOGD("Exit dataCallCb ret = %d\n", ret);
2228    return ret;
2229}
2230
2231/*===========================================================================
2232FUNCTION    loc_eng_agps_reinit
2233
2234DESCRIPTION
2235   2nd half of loc_eng_agps_init(), singled out for modem restart to use.
2236
2237DEPENDENCIES
2238   NONE
2239
2240RETURN VALUE
2241   0
2242
2243SIDE EFFECTS
2244   N/A
2245
2246===========================================================================*/
2247static void loc_eng_agps_reinit(loc_eng_data_s_type &loc_eng_data)
2248{
2249    ENTRY_LOG();
2250
2251    // Set server addresses which came before init
2252    if (loc_eng_data.supl_host_set)
2253    {
2254        loc_eng_set_server(loc_eng_data, LOC_AGPS_SUPL_SERVER,
2255                           loc_eng_data.supl_host_buf,
2256                           loc_eng_data.supl_port_buf);
2257    }
2258
2259    if (loc_eng_data.c2k_host_set)
2260    {
2261        loc_eng_set_server(loc_eng_data, LOC_AGPS_CDMA_PDE_SERVER,
2262                           loc_eng_data.c2k_host_buf,
2263                           loc_eng_data.c2k_port_buf);
2264    }
2265    EXIT_LOG(%s, VOID_RET);
2266}
2267/*===========================================================================
2268FUNCTION    loc_eng_agps_init
2269
2270DESCRIPTION
2271   Initialize the AGps interface.
2272
2273DEPENDENCIES
2274   NONE
2275
2276RETURN VALUE
2277   0
2278
2279SIDE EFFECTS
2280   N/A
2281
2282===========================================================================*/
2283void loc_eng_agps_init(loc_eng_data_s_type &loc_eng_data, AGpsExtCallbacks* callbacks)
2284{
2285    ENTRY_LOG_CALLFLOW();
2286    INIT_CHECK(loc_eng_data.adapter, return);
2287    STATE_CHECK((NULL == loc_eng_data.agps_status_cb),
2288                "agps instance already initialized",
2289                return);
2290    if (callbacks == NULL) {
2291        LOC_LOGE("loc_eng_agps_init: bad parameters cb %p", callbacks);
2292        EXIT_LOG(%s, VOID_RET);
2293        return;
2294    }
2295    LocEngAdapter* adapter = loc_eng_data.adapter;
2296    loc_eng_data.agps_status_cb = callbacks->status_cb;
2297
2298    loc_eng_data.internet_nif = new AgpsStateMachine(servicerTypeAgps,
2299                                                     (void *)loc_eng_data.agps_status_cb,
2300                                                     AGPS_TYPE_WWAN_ANY,
2301                                                     false);
2302    loc_eng_data.wifi_nif = new AgpsStateMachine(servicerTypeAgps,
2303                                                 (void *)loc_eng_data.agps_status_cb,
2304                                                 AGPS_TYPE_WIFI,
2305                                                 true);
2306
2307    if ((gps_conf.CAPABILITIES & GPS_CAPABILITY_MSA) ||
2308        (gps_conf.CAPABILITIES & GPS_CAPABILITY_MSB)) {
2309        loc_eng_data.agnss_nif = new AgpsStateMachine(servicerTypeAgps,
2310                                                      (void *)loc_eng_data.agps_status_cb,
2311                                                      AGPS_TYPE_SUPL,
2312                                                      false);
2313
2314        if (adapter->mSupportsAgpsRequests) {
2315            if(gps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
2316                loc_eng_data.adapter->sendMsg(new LocEngDataClientInit(&loc_eng_data));
2317            }
2318            loc_eng_dmn_conn_loc_api_server_launch(callbacks->create_thread_cb,
2319                                                   NULL, NULL, &loc_eng_data);
2320        }
2321        loc_eng_agps_reinit(loc_eng_data);
2322    }
2323
2324    EXIT_LOG(%s, VOID_RET);
2325}
2326
2327static void deleteAidingData(loc_eng_data_s_type &logEng) {
2328    if (logEng.engine_status != GPS_STATUS_ENGINE_ON &&
2329        logEng.aiding_data_for_deletion != 0) {
2330        logEng.adapter->deleteAidingData(logEng.aiding_data_for_deletion);
2331        logEng.aiding_data_for_deletion = 0;
2332    }
2333}
2334
2335static AgpsStateMachine*
2336getAgpsStateMachine(loc_eng_data_s_type &locEng, AGpsExtType agpsType) {
2337    AgpsStateMachine* stateMachine;
2338    switch (agpsType) {
2339    case AGPS_TYPE_WIFI: {
2340        stateMachine = locEng.wifi_nif;
2341        break;
2342    }
2343    case AGPS_TYPE_INVALID:
2344    case AGPS_TYPE_SUPL: {
2345        stateMachine = locEng.agnss_nif;
2346        break;
2347    }
2348    case AGPS_TYPE_SUPL_ES: {
2349        locEng.ds_nif ?
2350            stateMachine = locEng.ds_nif:
2351            stateMachine = locEng.agnss_nif;
2352        break;
2353    }
2354    default:
2355        stateMachine  = locEng.internet_nif;
2356    }
2357    return stateMachine;
2358}
2359
2360/*===========================================================================
2361FUNCTION    loc_eng_agps_open
2362
2363DESCRIPTION
2364   This function is called when on-demand data connection opening is successful.
2365It should inform engine about the data open result.
2366
2367DEPENDENCIES
2368   NONE
2369
2370RETURN VALUE
2371   0
2372
2373SIDE EFFECTS
2374   N/A
2375
2376===========================================================================*/
2377int loc_eng_agps_open(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType,
2378                     const char* apn, AGpsBearerType bearerType)
2379{
2380    ENTRY_LOG_CALLFLOW();
2381    INIT_CHECK(loc_eng_data.adapter && loc_eng_data.agps_status_cb,
2382               return -1);
2383
2384    if (apn == NULL)
2385    {
2386        LOC_LOGE("APN Name NULL\n");
2387        return 0;
2388    }
2389
2390    LOC_LOGD("loc_eng_agps_open APN name = [%s]", apn);
2391
2392    int apn_len = smaller_of(strlen (apn), MAX_APN_LEN);
2393    AgpsStateMachine* sm = getAgpsStateMachine(loc_eng_data, agpsType);
2394
2395    loc_eng_data.adapter->sendMsg(
2396        new LocEngAtlOpenSuccess(sm, apn, apn_len, bearerType));
2397
2398    EXIT_LOG(%d, 0);
2399    return 0;
2400}
2401
2402/*===========================================================================
2403FUNCTION    loc_eng_agps_closed
2404
2405DESCRIPTION
2406   This function is called when on-demand data connection closing is done.
2407It should inform engine about the data close result.
2408
2409DEPENDENCIES
2410   NONE
2411
2412RETURN VALUE
2413   0
2414
2415SIDE EFFECTS
2416   N/A
2417
2418===========================================================================*/
2419int loc_eng_agps_closed(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType)
2420{
2421    ENTRY_LOG_CALLFLOW();
2422    INIT_CHECK(loc_eng_data.adapter && loc_eng_data.agps_status_cb,
2423               return -1);
2424
2425    AgpsStateMachine* sm = getAgpsStateMachine(loc_eng_data, agpsType);
2426    loc_eng_data.adapter->sendMsg(new LocEngAtlClosed(sm));
2427
2428    EXIT_LOG(%d, 0);
2429    return 0;
2430}
2431
2432/*===========================================================================
2433FUNCTION    loc_eng_agps_open_failed
2434
2435DESCRIPTION
2436   This function is called when on-demand data connection opening has failed.
2437It should inform engine about the data open result.
2438
2439DEPENDENCIES
2440   NONE
2441
2442RETURN VALUE
2443   0
2444
2445SIDE EFFECTS
2446   N/A
2447
2448===========================================================================*/
2449int loc_eng_agps_open_failed(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType)
2450{
2451    ENTRY_LOG_CALLFLOW();
2452    INIT_CHECK(loc_eng_data.adapter && loc_eng_data.agps_status_cb,
2453               return -1);
2454
2455    AgpsStateMachine* sm = getAgpsStateMachine(loc_eng_data, agpsType);
2456    loc_eng_data.adapter->sendMsg(new LocEngAtlOpenFailed(sm));
2457
2458    EXIT_LOG(%d, 0);
2459    return 0;
2460}
2461
2462/*===========================================================================
2463
2464FUNCTION resolve_in_addr
2465
2466DESCRIPTION
2467   Translates a hostname to in_addr struct
2468
2469DEPENDENCIES
2470   n/a
2471
2472RETURN VALUE
2473   TRUE if successful
2474
2475SIDE EFFECTS
2476   n/a
2477
2478===========================================================================*/
2479static boolean resolve_in_addr(const char *host_addr, struct in_addr *in_addr_ptr)
2480{
2481    ENTRY_LOG();
2482    boolean ret_val = TRUE;
2483
2484    struct hostent             *hp;
2485    hp = gethostbyname(host_addr);
2486    if (hp != NULL) /* DNS OK */
2487    {
2488        memcpy(in_addr_ptr, hp->h_addr_list[0], hp->h_length);
2489    }
2490    else
2491    {
2492        /* Try IP representation */
2493        if (inet_aton(host_addr, in_addr_ptr) == 0)
2494        {
2495            /* IP not valid */
2496            LOC_LOGE("DNS query on '%s' failed\n", host_addr);
2497            ret_val = FALSE;
2498        }
2499    }
2500
2501    EXIT_LOG(%s, loc_logger_boolStr[ret_val!=0]);
2502    return ret_val;
2503}
2504
2505/*===========================================================================
2506FUNCTION    loc_eng_set_server
2507
2508DESCRIPTION
2509   This is used to set the default AGPS server. Server address is obtained
2510   from gps.conf.
2511
2512DEPENDENCIES
2513   NONE
2514
2515RETURN VALUE
2516   0
2517
2518SIDE EFFECTS
2519   N/A
2520
2521===========================================================================*/
2522static int loc_eng_set_server(loc_eng_data_s_type &loc_eng_data,
2523                              LocServerType type, const char* hostname, int port)
2524{
2525    ENTRY_LOG();
2526    int ret = 0;
2527    LocEngAdapter* adapter = loc_eng_data.adapter;
2528
2529    if (LOC_AGPS_SUPL_SERVER == type) {
2530        char url[MAX_URL_LEN];
2531        unsigned int len = 0;
2532        const char nohost[] = "NONE";
2533        if (hostname == NULL ||
2534            strncasecmp(nohost, hostname, sizeof(nohost)) == 0) {
2535            url[0] = NULL;
2536        } else {
2537            len = snprintf(url, sizeof(url), "%s:%u", hostname, (unsigned) port);
2538        }
2539
2540        if (sizeof(url) > len) {
2541            adapter->sendMsg(new LocEngSetServerUrl(adapter, url, len));
2542        }
2543    } else if (LOC_AGPS_CDMA_PDE_SERVER == type ||
2544               LOC_AGPS_CUSTOM_PDE_SERVER == type ||
2545               LOC_AGPS_MPC_SERVER == type) {
2546        struct in_addr addr;
2547        if (!resolve_in_addr(hostname, &addr))
2548        {
2549            LOC_LOGE("loc_eng_set_server, hostname %s cannot be resolved.\n", hostname);
2550            ret = -2;
2551        } else {
2552            unsigned int ip = htonl(addr.s_addr);
2553            adapter->sendMsg(new LocEngSetServerIpv4(adapter, ip, port, type));
2554        }
2555    } else {
2556        LOC_LOGE("loc_eng_set_server, type %d cannot be resolved.\n", type);
2557    }
2558
2559    EXIT_LOG(%d, ret);
2560    return ret;
2561}
2562
2563/*===========================================================================
2564FUNCTION    loc_eng_set_server_proxy
2565
2566DESCRIPTION
2567   If loc_eng_set_server is called before loc_eng_init, it doesn't work. This
2568   proxy buffers server settings and calls loc_eng_set_server when the client is
2569   open.
2570
2571DEPENDENCIES
2572   NONE
2573
2574RETURN VALUE
2575   0
2576
2577SIDE EFFECTS
2578   N/A
2579
2580===========================================================================*/
2581int loc_eng_set_server_proxy(loc_eng_data_s_type &loc_eng_data,
2582                             LocServerType type,
2583                             const char* hostname, int port)
2584{
2585    ENTRY_LOG_CALLFLOW();
2586    int ret_val = 0;
2587
2588    if (NULL != loc_eng_data.adapter)
2589    {
2590        ret_val = loc_eng_set_server(loc_eng_data, type, hostname, port);
2591    } else {
2592        LOC_LOGW("set_server called before init. save the address, type: %d, hostname: %s, port: %d",
2593                 (int) type, hostname, port);
2594        switch (type)
2595        {
2596        case LOC_AGPS_SUPL_SERVER:
2597            strlcpy(loc_eng_data.supl_host_buf, hostname,
2598                    sizeof(loc_eng_data.supl_host_buf));
2599            loc_eng_data.supl_port_buf = port;
2600            loc_eng_data.supl_host_set = 1;
2601            break;
2602        case LOC_AGPS_CDMA_PDE_SERVER:
2603            strlcpy(loc_eng_data.c2k_host_buf, hostname,
2604                    sizeof(loc_eng_data.c2k_host_buf));
2605            loc_eng_data.c2k_port_buf = port;
2606            loc_eng_data.c2k_host_set = 1;
2607            break;
2608        default:
2609            LOC_LOGE("loc_eng_set_server_proxy, unknown server type = %d", (int) type);
2610        }
2611    }
2612
2613    EXIT_LOG(%d, ret_val);
2614    return ret_val;
2615}
2616
2617/*===========================================================================
2618FUNCTION    loc_eng_agps_ril_update_network_availability
2619
2620DESCRIPTION
2621   Sets data call allow vs disallow flag to modem
2622   This is the only member of sLocEngAGpsRilInterface implemented.
2623
2624DEPENDENCIES
2625   None
2626
2627RETURN VALUE
2628   0: success
2629
2630SIDE EFFECTS
2631   N/A
2632
2633===========================================================================*/
2634void loc_eng_agps_ril_update_network_availability(loc_eng_data_s_type &loc_eng_data,
2635                                                  int available, const char* apn)
2636{
2637    ENTRY_LOG_CALLFLOW();
2638
2639    //This is to store the status of data availability over the network.
2640    //If GPS is not enabled, the INIT_CHECK will fail and the modem will
2641    //not be updated with the network's availability. Since the data status
2642    //can change before GPS is enabled the, storing the status will enable
2643    //us to inform the modem after GPS is enabled
2644    agpsStatus = available;
2645
2646    INIT_CHECK(loc_eng_data.adapter, return);
2647    if (apn != NULL)
2648    {
2649        LOC_LOGD("loc_eng_agps_ril_update_network_availability: APN Name = [%s]\n", apn);
2650        int apn_len = smaller_of(strlen (apn), MAX_APN_LEN);
2651        LocEngAdapter* adapter = loc_eng_data.adapter;
2652        adapter->sendMsg(new LocEngEnableData(adapter, apn,  apn_len, available));
2653    }
2654    EXIT_LOG(%s, VOID_RET);
2655}
2656
2657int loc_eng_agps_install_certificates(loc_eng_data_s_type &loc_eng_data,
2658                                      const DerEncodedCertificate* certificates,
2659                                      size_t numberOfCerts)
2660{
2661    ENTRY_LOG_CALLFLOW();
2662    int ret_val = AGPS_CERTIFICATE_OPERATION_SUCCESS;
2663
2664    uint32_t slotBitMask = gps_conf.AGPS_CERT_WRITABLE_MASK;
2665    uint32_t slotCount = 0;
2666    for (uint32_t slotBitMaskCounter=slotBitMask; slotBitMaskCounter; slotCount++) {
2667        slotBitMaskCounter &= slotBitMaskCounter - 1;
2668    }
2669    LOC_LOGD("SlotBitMask=%u SlotCount=%u NumberOfCerts=%u",
2670             slotBitMask, slotCount, numberOfCerts);
2671
2672    LocEngAdapter* adapter = loc_eng_data.adapter;
2673
2674    if (numberOfCerts == 0) {
2675        LOC_LOGE("No certs to install, since numberOfCerts is zero");
2676        ret_val = AGPS_CERTIFICATE_OPERATION_SUCCESS;
2677    } else if (!adapter) {
2678        LOC_LOGE("adapter is null!");
2679        ret_val = AGPS_CERTIFICATE_ERROR_GENERIC;
2680    } else if (slotCount < numberOfCerts) {
2681        LOC_LOGE("Not enough cert slots (%u) to install %u certs!",
2682                 slotCount, numberOfCerts);
2683        ret_val = AGPS_CERTIFICATE_ERROR_TOO_MANY_CERTIFICATES;
2684    } else {
2685        for (int i=0; i < numberOfCerts; ++i)
2686        {
2687            if (certificates[i].length > AGPS_CERTIFICATE_MAX_LENGTH) {
2688                LOC_LOGE("cert#(%u) length of %u is too big! greater than %u",
2689                        certificates[i].length, AGPS_CERTIFICATE_MAX_LENGTH);
2690                ret_val = AGPS_CERTIFICATE_ERROR_GENERIC;
2691                break;
2692            }
2693        }
2694
2695        if (ret_val == AGPS_CERTIFICATE_OPERATION_SUCCESS) {
2696            adapter->sendMsg(new LocEngInstallAGpsCert(adapter,
2697                                                       certificates,
2698                                                       numberOfCerts,
2699                                                       slotBitMask));
2700        }
2701    }
2702
2703    EXIT_LOG(%d, ret_val);
2704    return ret_val;
2705}
2706
2707void loc_eng_configuration_update (loc_eng_data_s_type &loc_eng_data,
2708                                   const char* config_data, int32_t length)
2709{
2710    ENTRY_LOG_CALLFLOW();
2711
2712    if (config_data && length > 0) {
2713        loc_gps_cfg_s_type gps_conf_tmp = gps_conf;
2714        UTIL_UPDATE_CONF(config_data, length, gps_conf_table);
2715        LocEngAdapter* adapter = loc_eng_data.adapter;
2716
2717        // it is possible that HAL is not init'ed at this time
2718        if (adapter) {
2719            if (gps_conf_tmp.SUPL_VER != gps_conf.SUPL_VER) {
2720                adapter->sendMsg(new LocEngSuplVer(adapter, gps_conf.SUPL_VER));
2721            }
2722            if (gps_conf_tmp.LPP_PROFILE != gps_conf.LPP_PROFILE) {
2723                adapter->sendMsg(new LocEngLppConfig(adapter, gps_conf.LPP_PROFILE));
2724            }
2725            if (gps_conf_tmp.A_GLONASS_POS_PROTOCOL_SELECT != gps_conf.A_GLONASS_POS_PROTOCOL_SELECT) {
2726                adapter->sendMsg(new LocEngAGlonassProtocol(adapter,
2727                                                            gps_conf.A_GLONASS_POS_PROTOCOL_SELECT));
2728            }
2729            if (gps_conf_tmp.SUPL_MODE != gps_conf.SUPL_MODE) {
2730                adapter->sendMsg(new LocEngSuplMode(adapter->getUlpProxy()));
2731            }
2732        }
2733
2734        gps_conf_tmp.SUPL_VER = gps_conf.SUPL_VER;
2735        gps_conf_tmp.LPP_PROFILE = gps_conf.LPP_PROFILE;
2736        gps_conf_tmp.A_GLONASS_POS_PROTOCOL_SELECT = gps_conf.A_GLONASS_POS_PROTOCOL_SELECT;
2737        gps_conf_tmp.GPS_LOCK = gps_conf.GPS_LOCK;
2738        gps_conf = gps_conf_tmp;
2739    }
2740
2741    EXIT_LOG(%s, VOID_RET);
2742}
2743
2744/*===========================================================================
2745FUNCTION    loc_eng_report_status
2746
2747DESCRIPTION
2748   Reports GPS engine state to Java layer.
2749
2750DEPENDENCIES
2751   N/A
2752
2753RETURN VALUE
2754   N/A
2755
2756SIDE EFFECTS
2757   N/A
2758
2759===========================================================================*/
2760static void loc_eng_report_status (loc_eng_data_s_type &loc_eng_data, GpsStatusValue status)
2761{
2762    ENTRY_LOG();
2763    // Switch from WAIT to MUTE, for "engine on" or "session begin" event
2764    if (status == GPS_STATUS_SESSION_BEGIN || status == GPS_STATUS_ENGINE_ON)
2765    {
2766        if (loc_eng_data.mute_session_state == LOC_MUTE_SESS_WAIT)
2767        {
2768            LOC_LOGD("loc_eng_report_status: mute_session_state changed from WAIT to IN SESSION");
2769            loc_eng_data.mute_session_state = LOC_MUTE_SESS_IN_SESSION;
2770        }
2771    }
2772
2773    // Switch off MUTE session
2774    if (loc_eng_data.mute_session_state == LOC_MUTE_SESS_IN_SESSION &&
2775        (status == GPS_STATUS_SESSION_END || status == GPS_STATUS_ENGINE_OFF))
2776    {
2777        LOC_LOGD("loc_eng_report_status: mute_session_state changed from IN SESSION to NONE");
2778        loc_eng_data.mute_session_state = LOC_MUTE_SESS_NONE;
2779    }
2780
2781    // Session End is not reported during Android navigating state
2782    boolean navigating = loc_eng_data.adapter->isInSession();
2783    if (status != GPS_STATUS_NONE &&
2784        !(status == GPS_STATUS_SESSION_END && navigating) &&
2785        !(status == GPS_STATUS_SESSION_BEGIN && !navigating))
2786    {
2787        if (loc_eng_data.mute_session_state != LOC_MUTE_SESS_IN_SESSION)
2788        {
2789            // Inform GpsLocationProvider about mNavigating status
2790            loc_inform_gps_status(loc_eng_data, status);
2791        }
2792        else {
2793            LOC_LOGD("loc_eng_report_status: muting the status report.");
2794        }
2795    }
2796
2797    // Only keeps ENGINE ON/OFF in engine_status
2798    if (status == GPS_STATUS_ENGINE_ON || status == GPS_STATUS_ENGINE_OFF)
2799    {
2800        loc_eng_data.engine_status = status;
2801    }
2802
2803    // Only keeps SESSION BEGIN/END in fix_session_status
2804    if (status == GPS_STATUS_SESSION_BEGIN || status == GPS_STATUS_SESSION_END)
2805    {
2806        loc_eng_data.fix_session_status = status;
2807    }
2808    EXIT_LOG(%s, VOID_RET);
2809}
2810
2811/*===========================================================================
2812FUNCTION loc_eng_handle_engine_down
2813         loc_eng_handle_engine_up
2814
2815DESCRIPTION
2816   Calls this function when it is detected that modem restart is happening.
2817   Either we detected the modem is down or received modem up event.
2818   This must be called from the deferred thread to avoid race condition.
2819
2820DEPENDENCIES
2821   None
2822
2823RETURN VALUE
2824   None
2825
2826SIDE EFFECTS
2827   N/A
2828
2829===========================================================================*/
2830void loc_eng_handle_engine_down(loc_eng_data_s_type &loc_eng_data)
2831{
2832    ENTRY_LOG();
2833    loc_eng_ni_reset_on_engine_restart(loc_eng_data);
2834    loc_eng_report_status(loc_eng_data, GPS_STATUS_ENGINE_OFF);
2835    EXIT_LOG(%s, VOID_RET);
2836}
2837
2838void loc_eng_handle_engine_up(loc_eng_data_s_type &loc_eng_data)
2839{
2840    ENTRY_LOG();
2841    loc_eng_reinit(loc_eng_data);
2842
2843    loc_eng_data.adapter->requestPowerVote();
2844
2845    if (loc_eng_data.agps_status_cb != NULL) {
2846        if (loc_eng_data.agnss_nif)
2847            loc_eng_data.agnss_nif->dropAllSubscribers();
2848        if (loc_eng_data.internet_nif)
2849            loc_eng_data.internet_nif->dropAllSubscribers();
2850
2851        loc_eng_agps_reinit(loc_eng_data);
2852    }
2853
2854    // modem is back up.  If we crashed in the middle of navigating, we restart.
2855    if (loc_eng_data.adapter->isInSession()) {
2856        // This sets the copy in adapter to modem
2857        loc_eng_data.adapter->setPositionMode(NULL);
2858        loc_eng_data.adapter->setInSession(false);
2859        loc_eng_start_handler(loc_eng_data);
2860    }
2861    EXIT_LOG(%s, VOID_RET);
2862}
2863
2864#ifdef USE_GLIB
2865/*===========================================================================
2866FUNCTION set_sched_policy
2867
2868DESCRIPTION
2869   Local copy of this function which bypasses android set_sched_policy
2870
2871DEPENDENCIES
2872   None
2873
2874RETURN VALUE
2875   0
2876
2877SIDE EFFECTS
2878   N/A
2879
2880===========================================================================*/
2881static int set_sched_policy(int tid, SchedPolicy policy)
2882{
2883    return 0;
2884}
2885#endif /* USE_GLIB */
2886
2887/*===========================================================================
2888FUNCTION    loc_eng_read_config
2889
2890DESCRIPTION
2891   Initiates the reading of the gps config file stored in /etc dir
2892
2893DEPENDENCIES
2894   None
2895
2896RETURN VALUE
2897   0: success
2898
2899SIDE EFFECTS
2900   N/A
2901
2902===========================================================================*/
2903int loc_eng_read_config(void)
2904{
2905    ENTRY_LOG_CALLFLOW();
2906    if(configAlreadyRead == false)
2907    {
2908      // Initialize our defaults before reading of configuration file overwrites them.
2909      loc_default_parameters();
2910      // We only want to parse the conf file once. This is a good place to ensure that.
2911      // In fact one day the conf file should go into context.
2912      UTIL_READ_CONF(GPS_CONF_FILE, gps_conf_table);
2913      UTIL_READ_CONF(SAP_CONF_FILE, sap_conf_table);
2914      configAlreadyRead = true;
2915    } else {
2916      LOC_LOGV("GPS Config file has already been read\n");
2917    }
2918
2919    EXIT_LOG(%d, 0);
2920    return 0;
2921}
2922
2923/*===========================================================================
2924FUNCTION    loc_eng_gps_measurement_init
2925
2926DESCRIPTION
2927   Initialize gps measurement module.
2928
2929DEPENDENCIES
2930   N/A
2931
2932RETURN VALUE
2933   0: success
2934
2935SIDE EFFECTS
2936   N/A
2937
2938===========================================================================*/
2939int loc_eng_gps_measurement_init(loc_eng_data_s_type &loc_eng_data,
2940                                 GpsMeasurementCallbacks* callbacks)
2941{
2942    ENTRY_LOG_CALLFLOW();
2943
2944    STATE_CHECK((NULL == loc_eng_data.gps_measurement_cb),
2945                "gps measurement already initialized",
2946                return GPS_MEASUREMENT_ERROR_ALREADY_INIT);
2947    STATE_CHECK((callbacks != NULL),
2948                "callbacks can not be NULL",
2949                return GPS_MEASUREMENT_ERROR_GENERIC);
2950    STATE_CHECK(loc_eng_data.adapter,
2951                "GpsInterface must be initialized first",
2952                return GPS_MEASUREMENT_ERROR_GENERIC);
2953
2954    // updated the mask
2955    LOC_API_ADAPTER_EVENT_MASK_T event = LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT;
2956    loc_eng_data.adapter->sendMsg(new LocEngUpdateRegistrationMask(
2957                                                        &loc_eng_data,
2958                                                        event,
2959                                                        LOC_REGISTRATION_MASK_ENABLED));
2960    // set up the callback
2961    loc_eng_data.gps_measurement_cb = callbacks->measurement_callback;
2962    LOC_LOGD ("%s, event masks updated successfully", __func__);
2963
2964    return GPS_MEASUREMENT_OPERATION_SUCCESS;
2965}
2966
2967/*===========================================================================
2968FUNCTION    loc_eng_gps_measurement_close
2969
2970DESCRIPTION
2971   Close gps measurement module.
2972
2973DEPENDENCIES
2974   N/A
2975
2976RETURN VALUE
2977   N/A
2978
2979SIDE EFFECTS
2980   N/A
2981
2982===========================================================================*/
2983void loc_eng_gps_measurement_close(loc_eng_data_s_type &loc_eng_data)
2984{
2985    ENTRY_LOG_CALLFLOW();
2986
2987    INIT_CHECK(loc_eng_data.adapter, return);
2988
2989    // updated the mask
2990    LOC_API_ADAPTER_EVENT_MASK_T event = LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT;
2991    loc_eng_data.adapter->sendMsg(new LocEngUpdateRegistrationMask(
2992                                                          &loc_eng_data,
2993                                                          event,
2994                                                          LOC_REGISTRATION_MASK_DISABLED));
2995    // set up the callback
2996    loc_eng_data.gps_measurement_cb = NULL;
2997    EXIT_LOG(%d, 0);
2998}
2999