/* Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation, nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#define LOG_NDDEBUG 0
#define LOG_TAG "LocSvc_eng"

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dlfcn.h>
#include <ctype.h>
#include <math.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <netinet/in.h>         /* struct sockaddr_in */
#include <sys/socket.h>
#include <sys/time.h>
#include <netdb.h>
#include <time.h>
#include <new>
#include <LocEngAdapter.h>

#include <cutils/sched_policy.h>
#ifndef USE_GLIB
#include <utils/SystemClock.h>
#include <utils/Log.h>
#endif /* USE_GLIB */

#ifdef USE_GLIB
#include <glib.h>
#include <sys/syscall.h>
#endif /* USE_GLIB */

#include <string.h>

#include <loc_eng.h>
#include <loc_eng_ni.h>
#include <loc_eng_dmn_conn.h>
#include <loc_eng_dmn_conn_handler.h>
#include <loc_eng_msg.h>
#include <loc_eng_nmea.h>
#include <msg_q.h>
#include <loc.h>
#include "log_util.h"
#include "platform_lib_includes.h"
#include "loc_core_log.h"
#include "loc_eng_log.h"

#define SUCCESS TRUE
#define FAILURE FALSE

#ifndef GPS_CONF_FILE
#define GPS_CONF_FILE            "/etc/gps.conf"   //??? platform independent
#endif

#ifndef SAP_CONF_FILE
#define SAP_CONF_FILE            "/etc/sap.conf"
#endif

#define XTRA1_GPSONEXTRA         "xtra1.gpsonextra.net"

using namespace loc_core;

boolean configAlreadyRead = false;
unsigned int agpsStatus = 0;
loc_gps_cfg_s_type gps_conf;
loc_sap_cfg_s_type sap_conf;

/* Parameter spec table */
static loc_param_s_type gps_conf_table[] =
{
  {"GPS_LOCK",                       &gps_conf.GPS_LOCK,                       NULL, 'n'},
  {"SUPL_VER",                       &gps_conf.SUPL_VER,                       NULL, 'n'},
  {"LPP_PROFILE",                    &gps_conf.LPP_PROFILE,                    NULL, 'n'},
  {"A_GLONASS_POS_PROTOCOL_SELECT",  &gps_conf.A_GLONASS_POS_PROTOCOL_SELECT,  NULL, 'n'},
  {"AGPS_CERT_WRITABLE_MASK",        &gps_conf.AGPS_CERT_WRITABLE_MASK,        NULL, 'n'},
  {"SUPL_MODE",                      &gps_conf.SUPL_MODE,                      NULL, 'n'},
  {"INTERMEDIATE_POS",               &gps_conf.INTERMEDIATE_POS,               NULL, 'n'},
  {"ACCURACY_THRES",                 &gps_conf.ACCURACY_THRES,                 NULL, 'n'},
  {"NMEA_PROVIDER",                  &gps_conf.NMEA_PROVIDER,                  NULL, 'n'},
  {"CAPABILITIES",                   &gps_conf.CAPABILITIES,                   NULL, 'n'},
  {"XTRA_VERSION_CHECK",             &gps_conf.XTRA_VERSION_CHECK,             NULL, 'n'},
  {"XTRA_SERVER_1",                  &gps_conf.XTRA_SERVER_1,                  NULL, 's'},
  {"XTRA_SERVER_2",                  &gps_conf.XTRA_SERVER_2,                  NULL, 's'},
  {"XTRA_SERVER_3",                  &gps_conf.XTRA_SERVER_3,                  NULL, 's'},
  {"USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL",  &gps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL,          NULL, 'n'},
};

static loc_param_s_type sap_conf_table[] =
{
  {"GYRO_BIAS_RANDOM_WALK",          &sap_conf.GYRO_BIAS_RANDOM_WALK,          &sap_conf.GYRO_BIAS_RANDOM_WALK_VALID, 'f'},
  {"ACCEL_RANDOM_WALK_SPECTRAL_DENSITY",     &sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY,    &sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
  {"ANGLE_RANDOM_WALK_SPECTRAL_DENSITY",     &sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY,    &sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
  {"RATE_RANDOM_WALK_SPECTRAL_DENSITY",      &sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY,     &sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
  {"VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY",  &sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY, &sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'},
  {"SENSOR_ACCEL_BATCHES_PER_SEC",   &sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC,   NULL, 'n'},
  {"SENSOR_ACCEL_SAMPLES_PER_BATCH", &sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH, NULL, 'n'},
  {"SENSOR_GYRO_BATCHES_PER_SEC",    &sap_conf.SENSOR_GYRO_BATCHES_PER_SEC,    NULL, 'n'},
  {"SENSOR_GYRO_SAMPLES_PER_BATCH",  &sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH,  NULL, 'n'},
  {"SENSOR_ACCEL_BATCHES_PER_SEC_HIGH",   &sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH,   NULL, 'n'},
  {"SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH", &sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH, NULL, 'n'},
  {"SENSOR_GYRO_BATCHES_PER_SEC_HIGH",    &sap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH,    NULL, 'n'},
  {"SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH",  &sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH,  NULL, 'n'},
  {"SENSOR_CONTROL_MODE",            &sap_conf.SENSOR_CONTROL_MODE,            NULL, 'n'},
  {"SENSOR_USAGE",                   &sap_conf.SENSOR_USAGE,                   NULL, 'n'},
  {"SENSOR_ALGORITHM_CONFIG_MASK",   &sap_conf.SENSOR_ALGORITHM_CONFIG_MASK,   NULL, 'n'},
  {"SENSOR_PROVIDER",                &sap_conf.SENSOR_PROVIDER,                NULL, 'n'}
};

static void loc_default_parameters(void)
{
   /*Defaults for gps.conf*/
   gps_conf.INTERMEDIATE_POS = 0;
   gps_conf.ACCURACY_THRES = 0;
   gps_conf.NMEA_PROVIDER = 0;
   gps_conf.GPS_LOCK = 0;
   gps_conf.SUPL_VER = 0x10000;
   gps_conf.SUPL_MODE = 0x3;
   gps_conf.CAPABILITIES = 0x7;
   /* LTE Positioning Profile configuration is disable by default*/
   gps_conf.LPP_PROFILE = 0;
   /*By default no positioning protocol is selected on A-GLONASS system*/
   gps_conf.A_GLONASS_POS_PROTOCOL_SELECT = 0;
   /*XTRA version check is disabled by default*/
   gps_conf.XTRA_VERSION_CHECK=0;
   /*Use emergency PDN by default*/
   gps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL = 1;

   /*Defaults for sap.conf*/
   sap_conf.GYRO_BIAS_RANDOM_WALK = 0;
   sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC = 2;
   sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH = 5;
   sap_conf.SENSOR_GYRO_BATCHES_PER_SEC = 2;
   sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH = 5;
   sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH = 4;
   sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH = 25;
   sap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH = 4;
   sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH = 25;
   sap_conf.SENSOR_CONTROL_MODE = 0; /* AUTO */
   sap_conf.SENSOR_USAGE = 0; /* Enabled */
   sap_conf.SENSOR_ALGORITHM_CONFIG_MASK = 0; /* INS Disabled = FALSE*/
   /* Values MUST be set by OEMs in configuration for sensor-assisted
      navigation to work. There are NO default values */
   sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY = 0;
   sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
   sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
   sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY = 0;
   sap_conf.GYRO_BIAS_RANDOM_WALK_VALID = 0;
   sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
   sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
   sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
   sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
   /* default provider is SSC */
   sap_conf.SENSOR_PROVIDER = 1;

   /* None of the 10 slots for agps certificates are writable by default */
   gps_conf.AGPS_CERT_WRITABLE_MASK = 0;
}

// 2nd half of init(), singled out for
// modem restart to use.
static int loc_eng_reinit(loc_eng_data_s_type &loc_eng_data);
static void loc_eng_agps_reinit(loc_eng_data_s_type &loc_eng_data);

static int loc_eng_set_server(loc_eng_data_s_type &loc_eng_data,
                              LocServerType type, const char *hostname, int port);
// Internal functions
static void loc_inform_gps_status(loc_eng_data_s_type &loc_eng_data,
                                  GpsStatusValue status);
static void loc_eng_report_status(loc_eng_data_s_type &loc_eng_data,
                                  GpsStatusValue status);
static void loc_eng_process_conn_request(loc_eng_data_s_type &loc_eng_data,
                                         int connHandle, AGpsType agps_type);
static void loc_eng_agps_close_status(loc_eng_data_s_type &loc_eng_data, int is_succ);
static void loc_eng_handle_engine_down(loc_eng_data_s_type &loc_eng_data) ;
static void loc_eng_handle_engine_up(loc_eng_data_s_type &loc_eng_data) ;

static int loc_eng_start_handler(loc_eng_data_s_type &loc_eng_data);
static int loc_eng_stop_handler(loc_eng_data_s_type &loc_eng_data);
static int loc_eng_get_zpp_handler(loc_eng_data_s_type &loc_eng_data);
static void deleteAidingData(loc_eng_data_s_type &logEng);
static AgpsStateMachine*
getAgpsStateMachine(loc_eng_data_s_type& logEng, AGpsExtType agpsType);
static int dataCallCb(void *cb_data);
static void update_aiding_data_for_deletion(loc_eng_data_s_type& loc_eng_data) {
    if (loc_eng_data.engine_status != GPS_STATUS_ENGINE_ON &&
        loc_eng_data.aiding_data_for_deletion != 0)
    {
        loc_eng_data.adapter->deleteAidingData(loc_eng_data.aiding_data_for_deletion);
        loc_eng_data.aiding_data_for_deletion = 0;
    }
}

static void* noProc(void* data)
{
    return NULL;
}


/*********************************************************************
 * definitions of the static messages used in the file
 *********************************************************************/
//        case LOC_ENG_MSG_REQUEST_NI:
LocEngRequestNi::LocEngRequestNi(void* locEng,
                                 GpsNiNotification &notif,
                                 const void* data) :
    LocMsg(), mLocEng(locEng), mNotify(notif), mPayload(data) {
    locallog();
}
void LocEngRequestNi::proc() const {
    loc_eng_ni_request_handler(*((loc_eng_data_s_type*)mLocEng),
                               &mNotify, mPayload);
}
void LocEngRequestNi::locallog() const
{
    LOC_LOGV("id: %d\n  type: %s\n  flags: %d\n  time out: %d\n  "
             "default response: %s\n  requestor id encoding: %s\n"
             "  text encoding: %s\n  passThroughData: %p",
             mNotify.notification_id,
             loc_get_ni_type_name(mNotify.ni_type),
             mNotify.notify_flags,
             mNotify.timeout,
             loc_get_ni_response_name(mNotify.default_response),
             loc_get_ni_encoding_name(mNotify.requestor_id_encoding),
             loc_get_ni_encoding_name(mNotify.text_encoding),
             mPayload);
}
inline void LocEngRequestNi::log() const {
    locallog();
}

//        case LOC_ENG_MSG_INFORM_NI_RESPONSE:
// in loc_eng_ni.cpp

//        case LOC_ENG_MSG_START_FIX:
LocEngStartFix::LocEngStartFix(LocEngAdapter* adapter) :
    LocMsg(), mAdapter(adapter)
{
    locallog();
}
inline void LocEngStartFix::proc() const
{
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mAdapter->getOwner();
    loc_eng_start_handler(*locEng);
}
inline void LocEngStartFix::locallog() const
{
    LOC_LOGV("LocEngStartFix");
}
inline void LocEngStartFix::log() const
{
    locallog();
}
void LocEngStartFix::send() const {
    mAdapter->sendMsg(this);
}

//        case LOC_ENG_MSG_STOP_FIX:
LocEngStopFix::LocEngStopFix(LocEngAdapter* adapter) :
    LocMsg(), mAdapter(adapter)
{
    locallog();
}
inline void LocEngStopFix::proc() const
{
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mAdapter->getOwner();
    loc_eng_stop_handler(*locEng);
}
inline void LocEngStopFix::locallog() const
{
    LOC_LOGV("LocEngStopFix");
}
inline void LocEngStopFix::log() const
{
    locallog();
}
void LocEngStopFix::send() const {
    mAdapter->sendMsg(this);
}

//        case LOC_ENG_MSG_SET_POSITION_MODE:
LocEngPositionMode::LocEngPositionMode(LocEngAdapter* adapter,
                                       LocPosMode &mode) :
    LocMsg(), mAdapter(adapter), mPosMode(mode)
{
    mPosMode.logv();
}
inline void LocEngPositionMode::proc() const {
    mAdapter->setPositionMode(&mPosMode);
}
inline void LocEngPositionMode::log() const {
    mPosMode.logv();
}
void LocEngPositionMode::send() const {
    mAdapter->sendMsg(this);
}

LocEngGetZpp::LocEngGetZpp(LocEngAdapter* adapter) :
    LocMsg(), mAdapter(adapter)
{
    locallog();
}
inline void LocEngGetZpp::proc() const
{
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mAdapter->getOwner();
    loc_eng_get_zpp_handler(*locEng);
}
inline void LocEngGetZpp::locallog() const
{
    LOC_LOGV("LocEngGetZpp");
}
inline void LocEngGetZpp::log() const
{
    locallog();
}
void LocEngGetZpp::send() const {
    mAdapter->sendMsg(this);
}

struct LocEngSetTime : public LocMsg {
    LocEngAdapter* mAdapter;
    const GpsUtcTime mTime;
    const int64_t mTimeReference;
    const int mUncertainty;
    inline LocEngSetTime(LocEngAdapter* adapter,
                         GpsUtcTime t, int64_t tf, int unc) :
        LocMsg(), mAdapter(adapter),
        mTime(t), mTimeReference(tf), mUncertainty(unc)
    {
        locallog();
    }
    inline virtual void proc() const {
        mAdapter->setTime(mTime, mTimeReference, mUncertainty);
    }
    inline void locallog() const {
        LOC_LOGV("time: %lld\n  timeReference: %lld\n  uncertainty: %d",
                 mTime, mTimeReference, mUncertainty);
    }
    inline virtual void log() const {
        locallog();
    }
};

 //       case LOC_ENG_MSG_INJECT_LOCATION:
struct LocEngInjectLocation : public LocMsg {
    LocEngAdapter* mAdapter;
    const double mLatitude;
    const double mLongitude;
    const float mAccuracy;
    inline LocEngInjectLocation(LocEngAdapter* adapter,
                                double lat, double lon, float accur) :
        LocMsg(), mAdapter(adapter),
        mLatitude(lat), mLongitude(lon), mAccuracy(accur)
    {
        locallog();
    }
    inline virtual void proc() const {
        mAdapter->injectPosition(mLatitude, mLongitude, mAccuracy);
    }
    inline void locallog() const {
        LOC_LOGV("latitude: %f\n  longitude: %f\n  accuracy: %f",
                 mLatitude, mLongitude, mAccuracy);
    }
    inline virtual void log() const {
        locallog();
    }
};

//        case LOC_ENG_MSG_SET_SERVER_IPV4:
struct LocEngSetServerIpv4 : public LocMsg {
    LocEngAdapter* mAdapter;
    const unsigned int mNlAddr;
    const int mPort;
    const LocServerType mServerType;
    inline LocEngSetServerIpv4(LocEngAdapter* adapter,
                               unsigned int ip,
                               int port,
                               LocServerType type) :
        LocMsg(), mAdapter(adapter),
        mNlAddr(ip), mPort(port), mServerType(type)
    {
        locallog();
    }
    inline virtual void proc() const {
        mAdapter->setServer(mNlAddr, mPort, mServerType);
    }
    inline void locallog() const {
        LOC_LOGV("LocEngSetServerIpv4 - addr: %x, port: %d, type: %s",
                 mNlAddr, mPort, loc_get_server_type_name(mServerType));
    }
    inline virtual void log() const {
        locallog();
    }
};

//        case LOC_ENG_MSG_SET_SERVER_URL:
struct LocEngSetServerUrl : public LocMsg {
    LocEngAdapter* mAdapter;
    const int mLen;
    char* mUrl;
    inline LocEngSetServerUrl(LocEngAdapter* adapter,
                              char* urlString,
                              int url_len) :
        LocMsg(), mAdapter(adapter),
        mLen(url_len), mUrl(new char[mLen+1])
    {
        memcpy((void*)mUrl, (void*)urlString, url_len);
        mUrl[mLen] = 0;
        locallog();
    }
    inline ~LocEngSetServerUrl()
    {
        delete[] mUrl;
    }
    inline virtual void proc() const {
        mAdapter->setServer(mUrl, mLen);
    }
    inline void locallog() const {
        LOC_LOGV("LocEngSetServerUrl - url: %s", mUrl);
    }
    inline virtual void log() const {
        locallog();
    }
};

//        case LOC_ENG_MSG_A_GLONASS_PROTOCOL:
struct LocEngAGlonassProtocol : public LocMsg {
    LocEngAdapter* mAdapter;
    const unsigned long mAGlonassProtocl;
    inline LocEngAGlonassProtocol(LocEngAdapter* adapter,
                                  unsigned long protocol) :
        LocMsg(), mAdapter(adapter), mAGlonassProtocl(protocol)
    {
        locallog();
    }
    inline virtual void proc() const {
        mAdapter->setAGLONASSProtocol(mAGlonassProtocl);
    }
    inline  void locallog() const {
        LOC_LOGV("A-GLONASS protocol: 0x%lx", mAGlonassProtocl);
    }
    inline virtual void log() const {
        locallog();
    }
};

//        case LOC_ENG_MSG_SUPL_VERSION:
struct LocEngSuplVer : public LocMsg {
    LocEngAdapter* mAdapter;
    const int mSuplVer;
    inline LocEngSuplVer(LocEngAdapter* adapter,
                         int suplVer) :
        LocMsg(), mAdapter(adapter), mSuplVer(suplVer)
    {
        locallog();
    }
    inline virtual void proc() const {
        mAdapter->setSUPLVersion(mSuplVer);
    }
    inline  void locallog() const {
        LOC_LOGV("SUPL Version: %d", mSuplVer);
    }
    inline virtual void log() const {
        locallog();
    }
};

struct LocEngSuplMode : public LocMsg {
    UlpProxyBase* mUlp;

    inline LocEngSuplMode(UlpProxyBase* ulp) :
        LocMsg(), mUlp(ulp)
    {
        locallog();
    }
    inline virtual void proc() const {
        mUlp->setCapabilities(getCarrierCapabilities());
    }
    inline  void locallog() const {
    }
    inline virtual void log() const {
        locallog();
    }
};

//        case LOC_ENG_MSG_LPP_CONFIG:
struct LocEngLppConfig : public LocMsg {
    LocEngAdapter* mAdapter;
    const int mLppConfig;
    inline LocEngLppConfig(LocEngAdapter* adapter,
                           int lppConfig) :
        LocMsg(), mAdapter(adapter), mLppConfig(lppConfig)
    {
        locallog();
    }
    inline virtual void proc() const {
        mAdapter->setLPPConfig(mLppConfig);
    }
    inline void locallog() const {
        LOC_LOGV("LocEngLppConfig - profile: %d", mLppConfig);
    }
    inline virtual void log() const {
        locallog();
    }
};

//        case LOC_ENG_MSG_SET_SENSOR_CONTROL_CONFIG:
struct LocEngSensorControlConfig : public LocMsg {
    LocEngAdapter* mAdapter;
    const int mSensorsDisabled;
    const int mSensorProvider;
    inline LocEngSensorControlConfig(LocEngAdapter* adapter,
                                     int sensorsDisabled, int sensorProvider) :
        LocMsg(), mAdapter(adapter), mSensorsDisabled(sensorsDisabled),
        mSensorProvider(sensorProvider)
    {
        locallog();
    }
    inline virtual void proc() const {
        mAdapter->setSensorControlConfig(mSensorsDisabled, mSensorProvider);
    }
    inline  void locallog() const {
        LOC_LOGV("LocEngSensorControlConfig - Sensors Disabled: %d, Sensor Provider: %d",
                 mSensorsDisabled, mSensorProvider);
    }
    inline virtual void log() const {
        locallog();
    }
};

//        case LOC_ENG_MSG_SET_SENSOR_PROPERTIES:
struct LocEngSensorProperties : public LocMsg {
    LocEngAdapter* mAdapter;
    const bool mGyroBiasVarianceRandomWalkValid;
    const float mGyroBiasVarianceRandomWalk;
    const bool mAccelRandomWalkValid;
    const float mAccelRandomWalk;
    const bool mAngleRandomWalkValid;
    const float mAngleRandomWalk;
    const bool mRateRandomWalkValid;
    const float mRateRandomWalk;
    const bool mVelocityRandomWalkValid;
    const float mVelocityRandomWalk;
    inline LocEngSensorProperties(LocEngAdapter* adapter,
                                  bool gyroBiasRandomWalk_valid,
                                  float gyroBiasRandomWalk,
                                  bool accelRandomWalk_valid,
                                  float accelRandomWalk,
                                  bool angleRandomWalk_valid,
                                  float angleRandomWalk,
                                  bool rateRandomWalk_valid,
                                  float rateRandomWalk,
                                  bool velocityRandomWalk_valid,
                                  float velocityRandomWalk) :
        LocMsg(), mAdapter(adapter),
        mGyroBiasVarianceRandomWalkValid(gyroBiasRandomWalk_valid),
        mGyroBiasVarianceRandomWalk(gyroBiasRandomWalk),
        mAccelRandomWalkValid(accelRandomWalk_valid),
        mAccelRandomWalk(accelRandomWalk),
        mAngleRandomWalkValid(angleRandomWalk_valid),
        mAngleRandomWalk(angleRandomWalk),
        mRateRandomWalkValid(rateRandomWalk_valid),
        mRateRandomWalk(rateRandomWalk),
        mVelocityRandomWalkValid(velocityRandomWalk_valid),
        mVelocityRandomWalk(velocityRandomWalk)
    {
        locallog();
    }
    inline virtual void proc() const {
        mAdapter->setSensorProperties(mGyroBiasVarianceRandomWalkValid,
                                      mGyroBiasVarianceRandomWalk,
                                      mAccelRandomWalkValid,
                                      mAccelRandomWalk,
                                      mAngleRandomWalkValid,
                                      mAngleRandomWalk,
                                      mRateRandomWalkValid,
                                      mRateRandomWalk,
                                      mVelocityRandomWalkValid,
                                      mVelocityRandomWalk);
    }
    inline  void locallog() const {
        LOC_LOGV("Sensor properties validity, Gyro Random walk: %d "
                 "Accel Random Walk: %d "
                 "Angle Random Walk: %d Rate Random Walk: %d "
                 "Velocity Random Walk: %d\n"
                 "Sensor properties, Gyro Random walk: %f "
                 "Accel Random Walk: %f "
                 "Angle Random Walk: %f Rate Random Walk: %f "
                 "Velocity Random Walk: %f",
                 mGyroBiasVarianceRandomWalkValid,
                 mAccelRandomWalkValid,
                 mAngleRandomWalkValid,
                 mRateRandomWalkValid,
                 mVelocityRandomWalkValid,
                 mGyroBiasVarianceRandomWalk,
                 mAccelRandomWalk,
                 mAngleRandomWalk,
                 mRateRandomWalk,
                 mVelocityRandomWalk
            );
    }
    inline virtual void log() const {
        locallog();
    }
};

//        case LOC_ENG_MSG_SET_SENSOR_PERF_CONTROL_CONFIG:
struct LocEngSensorPerfControlConfig : public LocMsg {
    LocEngAdapter* mAdapter;
    const int mControlMode;
    const int mAccelSamplesPerBatch;
    const int mAccelBatchesPerSec;
    const int mGyroSamplesPerBatch;
    const int mGyroBatchesPerSec;
    const int mAccelSamplesPerBatchHigh;
    const int mAccelBatchesPerSecHigh;
    const int mGyroSamplesPerBatchHigh;
    const int mGyroBatchesPerSecHigh;
    const int mAlgorithmConfig;
    inline LocEngSensorPerfControlConfig(LocEngAdapter* adapter,
                                         int controlMode,
                                         int accelSamplesPerBatch,
                                         int accelBatchesPerSec,
                                         int gyroSamplesPerBatch,
                                         int gyroBatchesPerSec,
                                         int accelSamplesPerBatchHigh,
                                         int accelBatchesPerSecHigh,
                                         int gyroSamplesPerBatchHigh,
                                         int gyroBatchesPerSecHigh,
                                         int algorithmConfig) :
        LocMsg(), mAdapter(adapter),
        mControlMode(controlMode),
        mAccelSamplesPerBatch(accelSamplesPerBatch),
        mAccelBatchesPerSec(accelBatchesPerSec),
        mGyroSamplesPerBatch(gyroSamplesPerBatch),
        mGyroBatchesPerSec(gyroBatchesPerSec),
        mAccelSamplesPerBatchHigh(accelSamplesPerBatchHigh),
        mAccelBatchesPerSecHigh(accelBatchesPerSecHigh),
        mGyroSamplesPerBatchHigh(gyroSamplesPerBatchHigh),
        mGyroBatchesPerSecHigh(gyroBatchesPerSecHigh),
        mAlgorithmConfig(algorithmConfig)
    {
        locallog();
    }
    inline virtual void proc() const {
        mAdapter->setSensorPerfControlConfig(mControlMode,
                                             mAccelSamplesPerBatch,
                                             mAccelBatchesPerSec,
                                             mGyroSamplesPerBatch,
                                             mGyroBatchesPerSec,
                                             mAccelSamplesPerBatchHigh,
                                             mAccelBatchesPerSecHigh,
                                             mGyroSamplesPerBatchHigh,
                                             mGyroBatchesPerSecHigh,
                                             mAlgorithmConfig);
    }
    inline void locallog() const {
        LOC_LOGV("Sensor Perf Control Config (performanceControlMode)(%u) "
                 "accel(#smp,#batches) (%u,%u) "
                 "gyro(#smp,#batches) (%u,%u), "
                 "accel_high(#smp,#batches) (%u,%u) "
                 "gyro_high(#smp,#batches) (%u,%u), "
                 "algorithmConfig(%u)\n",
                 mControlMode,
                 mAccelSamplesPerBatch, mAccelBatchesPerSec,
                 mGyroSamplesPerBatch, mGyroBatchesPerSec,
                 mAccelSamplesPerBatchHigh, mAccelBatchesPerSecHigh,
                 mGyroSamplesPerBatchHigh, mGyroBatchesPerSecHigh,
                 mAlgorithmConfig);
    }
    inline virtual void log() const {
        locallog();
    }
};

//        case LOC_ENG_MSG_EXT_POWER_CONFIG:
struct LocEngExtPowerConfig : public LocMsg {
    LocEngAdapter* mAdapter;
    const int mIsBatteryCharging;
    inline LocEngExtPowerConfig(LocEngAdapter* adapter,
                                int isBatteryCharging) :
        LocMsg(), mAdapter(adapter),
        mIsBatteryCharging(isBatteryCharging)
    {
        locallog();
    }
    inline virtual void proc() const {
        mAdapter->setExtPowerConfig(mIsBatteryCharging);
    }
    inline void locallog() const {
        LOC_LOGV("LocEngExtPowerConfig - isBatteryCharging: %d",
                 mIsBatteryCharging);
    }
    inline virtual void log() const {
        locallog();
    }
};

//        case LOC_ENG_MSG_REPORT_POSITION:
LocEngReportPosition::LocEngReportPosition(LocAdapterBase* adapter,
                                           UlpLocation &loc,
                                           GpsLocationExtended &locExtended,
                                           void* locExt,
                                           enum loc_sess_status st,
                                           LocPosTechMask technology) :
    LocMsg(), mAdapter(adapter), mLocation(loc),
    mLocationExtended(locExtended),
    mLocationExt(((loc_eng_data_s_type*)
                  ((LocEngAdapter*)
                   (mAdapter))->getOwner())->location_ext_parser(locExt)),
    mStatus(st), mTechMask(technology)
{
    locallog();
}
void LocEngReportPosition::proc() const {
    LocEngAdapter* adapter = (LocEngAdapter*)mAdapter;
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)adapter->getOwner();

    if (locEng->mute_session_state != LOC_MUTE_SESS_IN_SESSION) {
        bool reported = false;
        if (locEng->location_cb != NULL) {
            if (LOC_SESS_FAILURE == mStatus) {
                // in case we want to handle the failure case
                locEng->location_cb(NULL, NULL);
                reported = true;
            }
            // what's in the else if is... (line by line)
            // 1. this is a final fix; and
            //   1.1 it is a Satellite fix; or
            //   1.2 it is a sensor fix
            // 2. (must be intermediate fix... implicit)
            //   2.1 we accepte intermediate; and
            //   2.2 it is NOT the case that
            //   2.2.1 there is inaccuracy; and
            //   2.2.2 we care about inaccuracy; and
            //   2.2.3 the inaccuracy exceeds our tolerance
            else if ((LOC_SESS_SUCCESS == mStatus &&
                      ((LOC_POS_TECH_MASK_SATELLITE |
                        LOC_POS_TECH_MASK_SENSORS   |
                        LOC_POS_TECH_MASK_HYBRID) &
                       mTechMask)) ||
                     (LOC_SESS_INTERMEDIATE == locEng->intermediateFix &&
                      !((mLocation.gpsLocation.flags &
                         GPS_LOCATION_HAS_ACCURACY) &&
                        (gps_conf.ACCURACY_THRES != 0) &&
                        (mLocation.gpsLocation.accuracy >
                         gps_conf.ACCURACY_THRES)))) {
                locEng->location_cb((UlpLocation*)&(mLocation),
                                    (void*)mLocationExt);
                reported = true;
            }
        }

        // if we have reported this fix
        if (reported &&
            // and if this is a singleshot
            GPS_POSITION_RECURRENCE_SINGLE ==
            locEng->adapter->getPositionMode().recurrence) {
            if (LOC_SESS_INTERMEDIATE == mStatus) {
                // modem could be still working for a final fix,
                // although we no longer need it.  So stopFix().
                locEng->adapter->stopFix();
            }
            // turn off the session flag.
            locEng->adapter->setInSession(false);
        }

        if (locEng->generateNmea &&
            mLocation.position_source == ULP_LOCATION_IS_FROM_GNSS &&
            mTechMask & (LOC_POS_TECH_MASK_SATELLITE |
                         LOC_POS_TECH_MASK_SENSORS |
                         LOC_POS_TECH_MASK_HYBRID))
        {
            unsigned char generate_nmea = reported &&
                                          (mStatus != LOC_SESS_FAILURE);
            loc_eng_nmea_generate_pos(locEng, mLocation, mLocationExtended,
                                      generate_nmea);
        }

        // Free the allocated memory for rawData
        UlpLocation* gp = (UlpLocation*)&(mLocation);
        if (gp != NULL && gp->rawData != NULL)
        {
            delete (char*)gp->rawData;
            gp->rawData = NULL;
            gp->rawDataSize = 0;
        }
    }
}
void LocEngReportPosition::locallog() const {
    LOC_LOGV("LocEngReportPosition");
}
void LocEngReportPosition::log() const {
    locallog();
}
void LocEngReportPosition::send() const {
    mAdapter->sendMsg(this);
}


//        case LOC_ENG_MSG_REPORT_SV:
LocEngReportSv::LocEngReportSv(LocAdapterBase* adapter,
                               GpsSvStatus &sv,
                               GpsLocationExtended &locExtended,
                               void* svExt) :
    LocMsg(), mAdapter(adapter), mSvStatus(sv),
    mLocationExtended(locExtended),
    mSvExt(((loc_eng_data_s_type*)
            ((LocEngAdapter*)
             (mAdapter))->getOwner())->sv_ext_parser(svExt))
{
    locallog();
}
void LocEngReportSv::proc() const {
    LocEngAdapter* adapter = (LocEngAdapter*)mAdapter;
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)adapter->getOwner();

    if (locEng->mute_session_state != LOC_MUTE_SESS_IN_SESSION)
    {
        if (locEng->sv_status_cb != NULL) {
            locEng->sv_status_cb((GpsSvStatus*)&(mSvStatus),
                                 (void*)mSvExt);
        }

        if (locEng->generateNmea)
        {
            loc_eng_nmea_generate_sv(locEng, mSvStatus, mLocationExtended);
        }
    }
}
void LocEngReportSv::locallog() const {
    LOC_LOGV("%s:%d] LocEngReportSv",__func__, __LINE__);
}
inline void LocEngReportSv::log() const {
    locallog();
}
void LocEngReportSv::send() const {
    mAdapter->sendMsg(this);
}

//        case LOC_ENG_MSG_REPORT_STATUS:
LocEngReportStatus::LocEngReportStatus(LocAdapterBase* adapter,
                                       GpsStatusValue engineStatus) :
    LocMsg(),  mAdapter(adapter), mStatus(engineStatus)
{
    locallog();
}
inline void LocEngReportStatus::proc() const
{
    LocEngAdapter* adapter = (LocEngAdapter*)mAdapter;
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)adapter->getOwner();

    loc_eng_report_status(*locEng, mStatus);
    update_aiding_data_for_deletion(*locEng);
}
inline void LocEngReportStatus::locallog() const {
    LOC_LOGV("LocEngReportStatus");
}
inline void LocEngReportStatus::log() const {
    locallog();
}

//        case LOC_ENG_MSG_REPORT_NMEA:
LocEngReportNmea::LocEngReportNmea(void* locEng,
                                   const char* data, int len) :
    LocMsg(), mLocEng(locEng), mNmea(new char[len]), mLen(len)
{
    memcpy((void*)mNmea, (void*)data, len);
    locallog();
}
void LocEngReportNmea::proc() const {
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*) mLocEng;

    struct timeval tv;
    gettimeofday(&tv, (struct timezone *) NULL);
    int64_t now = tv.tv_sec * 1000LL + tv.tv_usec / 1000;

    if (locEng->nmea_cb != NULL)
        locEng->nmea_cb(now, mNmea, mLen);
}
inline void LocEngReportNmea::locallog() const {
    LOC_LOGV("LocEngReportNmea");
}
inline void LocEngReportNmea::log() const {
    locallog();
}

//        case LOC_ENG_MSG_REPORT_XTRA_SERVER:
LocEngReportXtraServer::LocEngReportXtraServer(void* locEng,
                                               const char *url1,
                                               const char *url2,
                                               const char *url3,
                                               const int maxlength) :
    LocMsg(), mLocEng(locEng), mMaxLen(maxlength),
    mServers(new char[3*(mMaxLen+1)])
{
    char * cptr = mServers;
    memset(mServers, 0, 3*(mMaxLen+1));

    // Override modem URLs with uncommented gps.conf urls
    if( gps_conf.XTRA_SERVER_1[0] != '\0' ) {
        url1 = &gps_conf.XTRA_SERVER_1[0];
    }
    if( gps_conf.XTRA_SERVER_2[0] != '\0' ) {
        url2 = &gps_conf.XTRA_SERVER_2[0];
    }
    if( gps_conf.XTRA_SERVER_3[0] != '\0' ) {
        url3 = &gps_conf.XTRA_SERVER_3[0];
    }
    // copy non xtra1.gpsonextra.net URLs into the forwarding buffer.
    if( NULL == strcasestr(url1, XTRA1_GPSONEXTRA) ) {
        strlcpy(cptr, url1, mMaxLen + 1);
        cptr += mMaxLen + 1;
    }
    if( NULL == strcasestr(url2, XTRA1_GPSONEXTRA) ) {
        strlcpy(cptr, url2, mMaxLen + 1);
        cptr += mMaxLen + 1;
    }
    if( NULL == strcasestr(url3, XTRA1_GPSONEXTRA) ) {
        strlcpy(cptr, url3, mMaxLen + 1);
    }
    locallog();
}

void LocEngReportXtraServer::proc() const {
    loc_eng_xtra_data_s_type* locEngXtra =
        &(((loc_eng_data_s_type*)mLocEng)->xtra_module_data);

    if (locEngXtra->report_xtra_server_cb != NULL) {
        CALLBACK_LOG_CALLFLOW("report_xtra_server_cb", %s, mServers);
        locEngXtra->report_xtra_server_cb(mServers,
                                          &(mServers[mMaxLen+1]),
                                          &(mServers[(mMaxLen+1)<<1]));
    } else {
        LOC_LOGE("Callback function for request xtra is NULL");
    }
}
inline void LocEngReportXtraServer::locallog() const {
    LOC_LOGV("LocEngReportXtraServers: server1: %s\n  server2: %s\n"
             "  server3: %s\n",
             mServers, &mServers[mMaxLen+1], &mServers[(mMaxLen+1)<<1]);
}
inline void LocEngReportXtraServer::log() const {
    locallog();
}

//        case LOC_ENG_MSG_REQUEST_BIT:
//        case LOC_ENG_MSG_RELEASE_BIT:
LocEngReqRelBIT::LocEngReqRelBIT(void* locEng, AGpsExtType type,
                                 int ipv4, char* ipv6, bool isReq) :
    LocMsg(), mLocEng(locEng), mType(type), mIPv4Addr(ipv4),
    mIPv6Addr(ipv6 ? new char[16] : NULL), mIsReq(isReq) {
    if (NULL != ipv6)
        memcpy(mIPv6Addr, ipv6, 16);
    locallog();
}
inline LocEngReqRelBIT::~LocEngReqRelBIT() {
    if (mIPv6Addr) {
        delete[] mIPv6Addr;
    }
}
void LocEngReqRelBIT::proc() const {
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
    BITSubscriber s(getAgpsStateMachine(*locEng, mType),
                    mIPv4Addr, mIPv6Addr);
    AgpsStateMachine* sm = (AgpsStateMachine*)s.mStateMachine;

    if (mIsReq) {
        sm->subscribeRsrc((Subscriber*)&s);
    } else {
        sm->unsubscribeRsrc((Subscriber*)&s);
    }
}
inline void LocEngReqRelBIT::locallog() const {
    LOC_LOGV("LocEngRequestBIT - ipv4: %d.%d.%d.%d, ipv6: %s",
             (unsigned char)mIPv4Addr,
             (unsigned char)(mIPv4Addr>>8),
             (unsigned char)(mIPv4Addr>>16),
             (unsigned char)(mIPv4Addr>>24),
             NULL != mIPv6Addr ? mIPv6Addr : "");
}
inline void LocEngReqRelBIT::log() const {
    locallog();
}
void LocEngReqRelBIT::send() const {
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
    locEng->adapter->sendMsg(this);
}

//        case LOC_ENG_MSG_RELEASE_BIT:
struct LocEngReleaseBIT : public LocMsg {
    const BITSubscriber mSubscriber;
    inline LocEngReleaseBIT(const AgpsStateMachine* stateMachine,
                            unsigned int ipv4, char* ipv6) :
        LocMsg(),
        mSubscriber(stateMachine, ipv4, ipv6)
    {
        locallog();
    }
    inline virtual void proc() const
    {
        AgpsStateMachine* sm = (AgpsStateMachine*)mSubscriber.mStateMachine;
        sm->unsubscribeRsrc((Subscriber*)&mSubscriber);
    }
    inline void locallog() const {
        LOC_LOGV("LocEngReleaseBIT - ipv4: %d.%d.%d.%d, ipv6: %s",
                 (unsigned char)(mSubscriber.ID>>24),
                 (unsigned char)(mSubscriber.ID>>16),
                 (unsigned char)(mSubscriber.ID>>8),
                 (unsigned char)mSubscriber.ID,
                 NULL != mSubscriber.mIPv6Addr ? mSubscriber.mIPv6Addr : "");
    }
    virtual void log() const {
        locallog();
    }
};

//        LocEngSuplEsOpened
LocEngSuplEsOpened::LocEngSuplEsOpened(void* locEng) :
    LocMsg(), mLocEng(locEng) {
    locallog();
}
void LocEngSuplEsOpened::proc() const {
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
    if (locEng->ds_nif) {
        AgpsStateMachine* sm = locEng->ds_nif;
        sm->onRsrcEvent(RSRC_GRANTED);
    }
}
void LocEngSuplEsOpened::locallog() const {
    LOC_LOGV("LocEngSuplEsOpened");
}
void LocEngSuplEsOpened::log() const {
    locallog();
}

//        LocEngSuplEsClosed
LocEngSuplEsClosed::LocEngSuplEsClosed(void* locEng) :
    LocMsg(), mLocEng(locEng) {
    locallog();
}
void LocEngSuplEsClosed::proc() const {
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
    if (locEng->ds_nif) {
        AgpsStateMachine* sm = locEng->ds_nif;
        sm->onRsrcEvent(RSRC_RELEASED);
    }
}
void LocEngSuplEsClosed::locallog() const {
    LOC_LOGV("LocEngSuplEsClosed");
}
void LocEngSuplEsClosed::log() const {
    locallog();
}


//        case LOC_ENG_MSG_REQUEST_SUPL_ES:
LocEngRequestSuplEs::LocEngRequestSuplEs(void* locEng, int id) :
    LocMsg(), mLocEng(locEng), mID(id) {
    locallog();
}
void LocEngRequestSuplEs::proc() const {
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
    if (locEng->ds_nif) {
        AgpsStateMachine* sm = locEng->ds_nif;
        DSSubscriber s(sm, mID);
        sm->subscribeRsrc((Subscriber*)&s);
    }
    else if (locEng->agnss_nif) {
        AgpsStateMachine *sm = locEng->agnss_nif;
        ATLSubscriber s(mID,
                        sm,
                        locEng->adapter,
                        false);
        sm->subscribeRsrc((Subscriber*)&s);
        LOC_LOGD("%s:%d]: Using regular ATL for SUPL ES", __func__, __LINE__);
    }
    else {
        locEng->adapter->atlOpenStatus(mID, 0, NULL, -1, -1);
    }
}
inline void LocEngRequestSuplEs::locallog() const {
    LOC_LOGV("LocEngRequestSuplEs");
}
inline void LocEngRequestSuplEs::log() const {
    locallog();
}

//        case LOC_ENG_MSG_REQUEST_ATL:
LocEngRequestATL::LocEngRequestATL(void* locEng, int id,
                                   AGpsExtType agps_type) :
    LocMsg(), mLocEng(locEng), mID(id), mType(agps_type) {
    locallog();
}
void LocEngRequestATL::proc() const {
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
    AgpsStateMachine* sm = (AgpsStateMachine*)
                           getAgpsStateMachine(*locEng, mType);
    if (sm) {
        ATLSubscriber s(mID,
                        sm,
                        locEng->adapter,
                        AGPS_TYPE_INVALID == mType);
        sm->subscribeRsrc((Subscriber*)&s);
    } else {
        locEng->adapter->atlOpenStatus(mID, 0, NULL, -1, mType);
    }
}
inline void LocEngRequestATL::locallog() const {
    LOC_LOGV("LocEngRequestATL");
}
inline void LocEngRequestATL::log() const {
    locallog();
}

//        case LOC_ENG_MSG_RELEASE_ATL:
LocEngReleaseATL::LocEngReleaseATL(void* locEng, int id) :
    LocMsg(), mLocEng(locEng), mID(id) {
    locallog();
}
void LocEngReleaseATL::proc() const {
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;

   if (locEng->agnss_nif) {
        ATLSubscriber s1(mID, locEng->agnss_nif, locEng->adapter, false);
        if (locEng->agnss_nif->unsubscribeRsrc((Subscriber*)&s1)) {
            LOC_LOGD("%s:%d]: Unsubscribed from agnss_nif",
                     __func__, __LINE__);
            return;
        }
    }

    if (locEng->internet_nif) {
        ATLSubscriber s2(mID, locEng->internet_nif, locEng->adapter, false);
        if (locEng->internet_nif->unsubscribeRsrc((Subscriber*)&s2)) {
            LOC_LOGD("%s:%d]: Unsubscribed from internet_nif",
                     __func__, __LINE__);
            return;
        }
    }

    if (locEng->ds_nif) {
        DSSubscriber s3(locEng->ds_nif, mID);
        if (locEng->ds_nif->unsubscribeRsrc((Subscriber*)&s3)) {
            LOC_LOGD("%s:%d]: Unsubscribed from ds_nif",
                     __func__, __LINE__);
            return;
        }
    }

    LOC_LOGW("%s:%d]: Could not release ATL. "
             "No subscribers found\n",
             __func__, __LINE__);
    locEng->adapter->atlCloseStatus(mID, 0);
}
inline void LocEngReleaseATL::locallog() const {
    LOC_LOGV("LocEngReleaseATL");
}
inline void LocEngReleaseATL::log() const {
    locallog();
}

//        case LOC_ENG_MSG_REQUEST_WIFI:
//        case LOC_ENG_MSG_RELEASE_WIFI:
LocEngReqRelWifi::LocEngReqRelWifi(void* locEng, AGpsExtType type,
                                   loc_if_req_sender_id_e_type sender_id,
                                   char* s, char* p, bool isReq) :
    LocMsg(), mLocEng(locEng), mType(type), mSenderId(sender_id),
    mSSID(NULL == s ? NULL : new char[SSID_BUF_SIZE]),
    mPassword(NULL == p ? NULL : new char[SSID_BUF_SIZE]),
    mIsReq(isReq) {
    if (NULL != s)
        strlcpy(mSSID, s, SSID_BUF_SIZE);
    if (NULL != p)
        strlcpy(mPassword, p, SSID_BUF_SIZE);
    locallog();
}
LocEngReqRelWifi::~LocEngReqRelWifi() {
    if (NULL != mSSID) {
        delete[] mSSID;
    }
    if (NULL != mPassword) {
        delete[] mPassword;
    }
}
void LocEngReqRelWifi::proc() const {
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
    if (locEng->wifi_nif) {
        WIFISubscriber s(locEng->wifi_nif, mSSID, mPassword, mSenderId);
        if (mIsReq) {
            locEng->wifi_nif->subscribeRsrc((Subscriber*)&s);
        } else {
            locEng->wifi_nif->unsubscribeRsrc((Subscriber*)&s);
        }
    } else {
        locEng->adapter->atlOpenStatus(mSenderId, 0, NULL, -1, mType);
    }
}
inline void LocEngReqRelWifi::locallog() const {
    LOC_LOGV("%s - senderId: %d, ssid: %s, password: %s",
             mIsReq ? "LocEngRequestWifi" : "LocEngReleaseWifi",
             mSenderId,
             NULL != mSSID ? mSSID : "",
             NULL != mPassword ? mPassword : "");
}
inline void LocEngReqRelWifi::log() const {
    locallog();
}
void LocEngReqRelWifi::send() const {
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
    locEng->adapter->sendMsg(this);
}

//        case LOC_ENG_MSG_REQUEST_XTRA_DATA:
LocEngRequestXtra::LocEngRequestXtra(void* locEng) :
    mLocEng(locEng) {
    locallog();
}
void LocEngRequestXtra::proc() const
{
    loc_eng_xtra_data_s_type* locEngXtra =
        &(((loc_eng_data_s_type*)mLocEng)->xtra_module_data);

    if (locEngXtra->download_request_cb != NULL) {
        CALLBACK_LOG_CALLFLOW("download_request_cb", %p, mLocEng);
        locEngXtra->download_request_cb();
    } else {
        LOC_LOGE("Callback function for request xtra is NULL");
    }
}
inline void LocEngRequestXtra::locallog() const {
    LOC_LOGV("LocEngReqXtra");
}
inline void LocEngRequestXtra::log() const {
    locallog();
}

//        case LOC_ENG_MSG_REQUEST_TIME:
LocEngRequestTime::LocEngRequestTime(void* locEng) :
    LocMsg(), mLocEng(locEng)
{
    locallog();
}
void LocEngRequestTime::proc() const {
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
    if (gps_conf.CAPABILITIES & GPS_CAPABILITY_ON_DEMAND_TIME) {
        if (locEng->request_utc_time_cb != NULL) {
            locEng->request_utc_time_cb();
        } else {
            LOC_LOGE("Callback function for request time is NULL");
        }
    }
}
inline void LocEngRequestTime::locallog() const {
    LOC_LOGV("LocEngReqTime");
}
inline void LocEngRequestTime::log() const {
    locallog();
}

//        case LOC_ENG_MSG_DELETE_AIDING_DATA:
struct LocEngDelAidData : public LocMsg {
    loc_eng_data_s_type* mLocEng;
    const GpsAidingData mType;
    inline LocEngDelAidData(loc_eng_data_s_type* locEng,
                            GpsAidingData f) :
        LocMsg(), mLocEng(locEng), mType(f)
    {
        locallog();
    }
    inline virtual void proc() const {
        mLocEng->aiding_data_for_deletion = mType;
        update_aiding_data_for_deletion(*mLocEng);
    }
    inline void locallog() const {
        LOC_LOGV("aiding data msak %d", mType);
    }
    virtual void log() const {
        locallog();
    }
};

//        case LOC_ENG_MSG_ENABLE_DATA:
struct LocEngEnableData : public LocMsg {
    LocEngAdapter* mAdapter;
    const int mEnable;
    char* mAPN;
    const int mLen;
    inline LocEngEnableData(LocEngAdapter* adapter,
                            const char* name, int len, int enable) :
        LocMsg(), mAdapter(adapter),
        mEnable(enable), mAPN(NULL), mLen(len)
    {
        if (NULL != name) {
            mAPN = new char[len+1];
            memcpy((void*)mAPN, (void*)name, len);
            mAPN[len] = 0;
        }
        locallog();
    }
    inline ~LocEngEnableData() {
        if (NULL != mAPN) {
            delete[] mAPN;
        }
    }
    inline virtual void proc() const {
        mAdapter->enableData(mEnable);
        if (NULL != mAPN) {
            mAdapter->setAPN(mAPN, mLen);
        }
    }
    inline void locallog() const {
        LOC_LOGV("apn: %s\n  enable: %d",
                 (NULL == mAPN) ? "NULL" : mAPN, mEnable);
    }
    inline virtual void log() const {
        locallog();
    }
};

//        case LOC_ENG_MSG_INJECT_XTRA_DATA:
// loc_eng_xtra.cpp

//        case LOC_ENG_MSG_SET_CAPABILITIES:
struct LocEngSetCapabilities : public LocMsg {
    loc_eng_data_s_type* mLocEng;
    inline LocEngSetCapabilities(loc_eng_data_s_type* locEng) :
        LocMsg(), mLocEng(locEng)
    {
        locallog();
    }
    inline virtual void proc() const {
        if (NULL != mLocEng->set_capabilities_cb) {
            LOC_LOGV("calling set_capabilities_cb 0x%x",
                     gps_conf.CAPABILITIES);
            mLocEng->set_capabilities_cb(gps_conf.CAPABILITIES);
        } else {
            LOC_LOGV("set_capabilities_cb is NULL.\n");
        }
    }
    inline void locallog() const
    {
        LOC_LOGV("LocEngSetCapabilities");
    }
    inline virtual void log() const
    {
        locallog();
    }
};

//        case LOC_ENG_MSG_LOC_INIT:
struct LocEngInit : public LocMsg {
    loc_eng_data_s_type* mLocEng;
    inline LocEngInit(loc_eng_data_s_type* locEng) :
        LocMsg(), mLocEng(locEng)
    {
        locallog();
    }
    inline virtual void proc() const {
        loc_eng_reinit(*mLocEng);
        // set the capabilities
        mLocEng->adapter->sendMsg(new LocEngSetCapabilities(mLocEng));
    }
    inline void locallog() const
    {
        LOC_LOGV("LocEngInit");
    }
    inline virtual void log() const
    {
        locallog();
    }
};

//        case LOC_ENG_MSG_REQUEST_XTRA_SERVER:
// loc_eng_xtra.cpp

//        case LOC_ENG_MSG_ATL_OPEN_SUCCESS:
struct LocEngAtlOpenSuccess : public LocMsg {
    AgpsStateMachine* mStateMachine;
    const int mLen;
    char* mAPN;
    const AGpsBearerType mBearerType;
    inline LocEngAtlOpenSuccess(AgpsStateMachine* statemachine,
                                const char* name,
                                int len,
                                AGpsBearerType btype) :
        LocMsg(),
        mStateMachine(statemachine), mLen(len),
        mAPN(new char[len+1]), mBearerType(btype)
    {
        memcpy((void*)mAPN, (void*)name, len);
        mAPN[len] = 0;
        locallog();
    }
    inline ~LocEngAtlOpenSuccess()
    {
        delete[] mAPN;
    }
    inline virtual void proc() const {
        mStateMachine->setBearer(mBearerType);
        mStateMachine->setAPN(mAPN, mLen);
        mStateMachine->onRsrcEvent(RSRC_GRANTED);
    }
    inline void locallog() const {
        LOC_LOGV("LocEngAtlOpenSuccess agps type: %s\n  apn: %s\n"
                 "  bearer type: %s",
                 loc_get_agps_type_name(mStateMachine->getType()),
                 mAPN,
                 loc_get_agps_bear_name(mBearerType));
    }
    inline virtual void log() const {
        locallog();
    }
};

//        case LOC_ENG_MSG_ATL_CLOSED:
struct LocEngAtlClosed : public LocMsg {
    AgpsStateMachine* mStateMachine;
    inline LocEngAtlClosed(AgpsStateMachine* statemachine) :
        LocMsg(), mStateMachine(statemachine) {
        locallog();
    }
    inline virtual void proc() const {
        mStateMachine->onRsrcEvent(RSRC_RELEASED);
    }
    inline void locallog() const {
        LOC_LOGV("LocEngAtlClosed");
    }
    inline virtual void log() const {
        locallog();
    }
};

//        case LOC_ENG_MSG_ATL_OPEN_FAILED:
struct LocEngAtlOpenFailed : public LocMsg {
    AgpsStateMachine* mStateMachine;
    inline LocEngAtlOpenFailed(AgpsStateMachine* statemachine) :
        LocMsg(), mStateMachine(statemachine) {
        locallog();
    }
    inline virtual void proc() const {
        mStateMachine->onRsrcEvent(RSRC_DENIED);
    }
    inline void locallog() const {
        LOC_LOGV("LocEngAtlOpenFailed");
    }
    inline virtual void log() const {
        locallog();
    }
};

//        case LOC_ENG_MSG_ENGINE_DOWN:
LocEngDown::LocEngDown(void* locEng) :
    LocMsg(), mLocEng(locEng) {
    locallog();
}
inline void LocEngDown::proc() const {
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
    loc_eng_handle_engine_down(*locEng);
}
inline void LocEngDown::locallog() const {
    LOC_LOGV("LocEngDown");
}
inline void LocEngDown::log() const {
    locallog();
}

//        case LOC_ENG_MSG_ENGINE_UP:
LocEngUp::LocEngUp(void* locEng) :
    LocMsg(), mLocEng(locEng) {
    locallog();
}
inline void LocEngUp::proc() const {
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng;
    loc_eng_handle_engine_up(*locEng);
}
inline void LocEngUp::locallog() const {
    LOC_LOGV("LocEngUp");
}
inline void LocEngUp::log() const {
    locallog();
}

struct LocEngDataClientInit : public LocMsg {
    loc_eng_data_s_type* mLocEng;
    inline LocEngDataClientInit(loc_eng_data_s_type* locEng) :
        LocMsg(), mLocEng(locEng) {
        locallog();
    }
    virtual void proc() const {
        loc_eng_data_s_type *locEng = (loc_eng_data_s_type *)mLocEng;
        if(!locEng->adapter->initDataServiceClient()) {
            locEng->ds_nif = new DSStateMachine(servicerTypeExt,
                                               (void *)dataCallCb,
                                               locEng->adapter);
        }
    }
    void locallog() const {
        LOC_LOGV("LocEngDataClientInit\n");
    }
    virtual void log() const {
        locallog();
    }
};

struct LocEngInstallAGpsCert : public LocMsg {
    LocEngAdapter* mpAdapter;
    const size_t mNumberOfCerts;
    const uint32_t mSlotBitMask;
    DerEncodedCertificate* mpData;
    inline LocEngInstallAGpsCert(LocEngAdapter* adapter,
                              const DerEncodedCertificate* pData,
                              size_t numberOfCerts,
                              uint32_t slotBitMask) :
        LocMsg(), mpAdapter(adapter),
        mNumberOfCerts(numberOfCerts), mSlotBitMask(slotBitMask),
        mpData(new DerEncodedCertificate[mNumberOfCerts])
    {
        for (int i=0; i < mNumberOfCerts; i++) {
            mpData[i].data = new u_char[pData[i].length];
            if (mpData[i].data) {
                memcpy(mpData[i].data, (void*)pData[i].data, pData[i].length);
                mpData[i].length = pData[i].length;
            } else {
                LOC_LOGE("malloc failed for cert#%d", i);
                break;
            }
        }
        locallog();
    }
    inline ~LocEngInstallAGpsCert()
    {
        for (int i=0; i < mNumberOfCerts; i++) {
            if (mpData[i].data) {
                delete[] mpData[i].data;
            }
        }
        delete[] mpData;
    }
    inline virtual void proc() const {
        mpAdapter->installAGpsCert(mpData, mNumberOfCerts, mSlotBitMask);
    }
    inline void locallog() const {
        LOC_LOGV("LocEngInstallAGpsCert - certs=%u mask=%u",
                 mNumberOfCerts, mSlotBitMask);
    }
    inline virtual void log() const {
        locallog();
    }
};

struct LocEngUpdateRegistrationMask : public LocMsg {
    loc_eng_data_s_type* mLocEng;
    LOC_API_ADAPTER_EVENT_MASK_T mMask;
    loc_registration_mask_status mIsEnabled;
    inline LocEngUpdateRegistrationMask(loc_eng_data_s_type* locEng,
                                        LOC_API_ADAPTER_EVENT_MASK_T mask,
                                        loc_registration_mask_status isEnabled) :
        LocMsg(), mLocEng(locEng), mMask(mask), mIsEnabled(isEnabled) {
        locallog();
    }
    inline virtual void proc() const {
        loc_eng_data_s_type *locEng = (loc_eng_data_s_type *)mLocEng;
        locEng->adapter->updateRegistrationMask(mMask,
                                                mIsEnabled);
    }
    void locallog() const {
        LOC_LOGV("LocEngUpdateRegistrationMask\n");
    }
    virtual void log() const {
        locallog();
    }
};

struct LocEngGnssConstellationConfig : public LocMsg {
    LocEngAdapter* mAdapter;
    inline LocEngGnssConstellationConfig(LocEngAdapter* adapter) :
        LocMsg(), mAdapter(adapter) {
        locallog();
    }
    inline virtual void proc() const {
        if (mAdapter->gnssConstellationConfig()) {
            LOC_LOGV("Modem supports GNSS measurements\n");
            gps_conf.CAPABILITIES |= GPS_CAPABILITY_MEASUREMENTS;
        } else {
            LOC_LOGV("Modem does not support GNSS measurements\n");
        }
    }
    void locallog() const {
        LOC_LOGV("LocEngGnssConstellationConfig\n");
    }
    virtual void log() const {
        locallog();
    }
};

//        case LOC_ENG_MSG_REPORT_GNSS_MEASUREMENT:
LocEngReportGpsMeasurement::LocEngReportGpsMeasurement(void* locEng,
                                                       GpsData &gpsData) :
    LocMsg(), mLocEng(locEng), mGpsData(gpsData)
{
    locallog();
}
void LocEngReportGpsMeasurement::proc() const {
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*) mLocEng;
    if (locEng->mute_session_state != LOC_MUTE_SESS_IN_SESSION)
    {
        if (locEng->gps_measurement_cb != NULL) {
            locEng->gps_measurement_cb((GpsData*)&(mGpsData));
        }
    }
}
void LocEngReportGpsMeasurement::locallog() const {
    IF_LOC_LOGV {
        LOC_LOGV("%s:%d]: Received in GPS HAL."
                 "GNSS Measurements count: %d \n",
                 __func__, __LINE__, mGpsData.measurement_count);
        for (int i =0; i< mGpsData.measurement_count && i < GPS_MAX_SVS; i++) {
                LOC_LOGV(" GNSS measurement data in GPS HAL: \n"
                         " GPS_HAL => Measurement ID | prn | time_offset_ns | state |"
                         " received_gps_tow_ns| c_n0_dbhz | pseudorange_rate_mps |"
                         " pseudorange_rate_uncertainty_mps |"
                         " accumulated_delta_range_state | flags \n"
                         " GPS_HAL => %d | %d | %f | %d | %lld | %f | %f | %f | %d | %d \n",
                         i,
                         mGpsData.measurements[i].prn,
                         mGpsData.measurements[i].time_offset_ns,
                         mGpsData.measurements[i].state,
                         mGpsData.measurements[i].received_gps_tow_ns,
                         mGpsData.measurements[i].c_n0_dbhz,
                         mGpsData.measurements[i].pseudorange_rate_mps,
                         mGpsData.measurements[i].pseudorange_rate_uncertainty_mps,
                         mGpsData.measurements[i].accumulated_delta_range_state,
                         mGpsData.measurements[i].flags);
        }
        LOC_LOGV(" GPS_HAL => Clocks Info: type | time_ns \n"
                 " GPS_HAL => Clocks Info: %d | %lld", mGpsData.clock.type,
                 mGpsData.clock.time_ns);
    }
}
inline void LocEngReportGpsMeasurement::log() const {
    locallog();
}

/*********************************************************************
 * Initialization checking macros
 *********************************************************************/
#define STATE_CHECK(ctx, x, ret) \
    if (!(ctx))                  \
  {                              \
      /* Not intialized, abort */\
      LOC_LOGE("%s: log_eng state error: %s", __func__, x); \
      EXIT_LOG(%s, x);                                            \
      ret;                                                        \
  }
#define INIT_CHECK(ctx, ret) STATE_CHECK(ctx, "instance not initialized", ret)

uint32_t getCarrierCapabilities() {
    #define carrierMSA (uint32_t)0x2
    #define carrierMSB (uint32_t)0x1
    #define gpsConfMSA (uint32_t)0x4
    #define gpsConfMSB (uint32_t)0x2
    uint32_t capabilities = gps_conf.CAPABILITIES;
    if ((gps_conf.SUPL_MODE & carrierMSA) != carrierMSA) {
        capabilities &= ~gpsConfMSA;
    }
    if ((gps_conf.SUPL_MODE & carrierMSB) != carrierMSB) {
        capabilities &= ~gpsConfMSB;
    }

    LOC_LOGV("getCarrierCapabilities: CAPABILITIES %x, SUPL_MODE %x, carrier capabilities %x",
             gps_conf.CAPABILITIES, gps_conf.SUPL_MODE, capabilities);
    return capabilities;
}

/*===========================================================================
FUNCTION    loc_eng_init

DESCRIPTION
   Initialize the location engine, this include setting up global datas
   and registers location engien with loc api service.

DEPENDENCIES
   None

RETURN VALUE
   0: success

SIDE EFFECTS
   N/A

===========================================================================*/
int loc_eng_init(loc_eng_data_s_type &loc_eng_data, LocCallbacks* callbacks,
                 LOC_API_ADAPTER_EVENT_MASK_T event, ContextBase* context)

{
    int ret_val = 0;

    ENTRY_LOG_CALLFLOW();
    if (NULL == callbacks || 0 == event) {
        LOC_LOGE("loc_eng_init: bad parameters cb %p eMask %d", callbacks, event);
        ret_val = -1;
        EXIT_LOG(%d, ret_val);
        return ret_val;
    }

    STATE_CHECK((NULL == loc_eng_data.adapter),
                "instance already initialized", return 0);

    memset(&loc_eng_data, 0, sizeof (loc_eng_data));

    // Save callbacks
    loc_eng_data.location_cb  = callbacks->location_cb;
    loc_eng_data.sv_status_cb = callbacks->sv_status_cb;
    loc_eng_data.status_cb    = callbacks->status_cb;
    loc_eng_data.nmea_cb      = callbacks->nmea_cb;
    loc_eng_data.set_capabilities_cb = callbacks->set_capabilities_cb;
    loc_eng_data.acquire_wakelock_cb = callbacks->acquire_wakelock_cb;
    loc_eng_data.release_wakelock_cb = callbacks->release_wakelock_cb;
    loc_eng_data.request_utc_time_cb = callbacks->request_utc_time_cb;
    loc_eng_data.location_ext_parser = callbacks->location_ext_parser ?
        callbacks->location_ext_parser : noProc;
    loc_eng_data.sv_ext_parser = callbacks->sv_ext_parser ?
        callbacks->sv_ext_parser : noProc;
    loc_eng_data.intermediateFix = gps_conf.INTERMEDIATE_POS;
    // initial states taken care of by the memset above
    // loc_eng_data.engine_status -- GPS_STATUS_NONE;
    // loc_eng_data.fix_session_status -- GPS_STATUS_NONE;
    // loc_eng_data.mute_session_state -- LOC_MUTE_SESS_NONE;

    if ((event & LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT) && (gps_conf.NMEA_PROVIDER == NMEA_PROVIDER_AP))
    {
        event = event ^ LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT; // unregister for modem NMEA report
        loc_eng_data.generateNmea = true;
    }
    else
    {
        loc_eng_data.generateNmea = false;
    }

    loc_eng_data.adapter =
        new LocEngAdapter(event, &loc_eng_data, context,
                          (MsgTask::tCreate)callbacks->create_thread_cb);

    LOC_LOGD("loc_eng_init created client, id = %p\n",
             loc_eng_data.adapter);
    loc_eng_data.adapter->sendMsg(new LocEngInit(&loc_eng_data));

    EXIT_LOG(%d, ret_val);
    return ret_val;
}

static int loc_eng_reinit(loc_eng_data_s_type &loc_eng_data)
{
    ENTRY_LOG();
    int ret_val = LOC_API_ADAPTER_ERR_SUCCESS;
    LocEngAdapter* adapter = loc_eng_data.adapter;

    adapter->sendMsg(new LocEngGnssConstellationConfig(adapter));
    adapter->sendMsg(new LocEngSuplVer(adapter, gps_conf.SUPL_VER));
    adapter->sendMsg(new LocEngLppConfig(adapter, gps_conf.LPP_PROFILE));
    adapter->sendMsg(new LocEngSensorControlConfig(adapter, sap_conf.SENSOR_USAGE,
                                                   sap_conf.SENSOR_PROVIDER));
    adapter->sendMsg(new LocEngAGlonassProtocol(adapter, gps_conf.A_GLONASS_POS_PROTOCOL_SELECT));

    /* Make sure at least one of the sensor property is specified by the user in the gps.conf file. */
    if( sap_conf.GYRO_BIAS_RANDOM_WALK_VALID ||
        sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
        sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
        sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
        sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID ) {
        adapter->sendMsg(new LocEngSensorProperties(adapter,
                                                    sap_conf.GYRO_BIAS_RANDOM_WALK_VALID,
                                                    sap_conf.GYRO_BIAS_RANDOM_WALK,
                                                    sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
                                                    sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY,
                                                    sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
                                                    sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY,
                                                    sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
                                                    sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY,
                                                    sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
                                                    sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY));
    }

    adapter->sendMsg(new LocEngSensorPerfControlConfig(adapter,
                                                       sap_conf.SENSOR_CONTROL_MODE,
                                                       sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH,
                                                       sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC,
                                                       sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH,
                                                       sap_conf.SENSOR_GYRO_BATCHES_PER_SEC,
                                                       sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH,
                                                       sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH,
                                                       sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH,
                                                       sap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH,
                                                       sap_conf.SENSOR_ALGORITHM_CONFIG_MASK));

    adapter->sendMsg(new LocEngEnableData(adapter, NULL, 0, (agpsStatus ? 1:0)));

    loc_eng_xtra_version_check(loc_eng_data, gps_conf.XTRA_VERSION_CHECK);

    LOC_LOGD("loc_eng_reinit reinit() successful");
    EXIT_LOG(%d, ret_val);
    return ret_val;
}

/*===========================================================================
FUNCTION    loc_eng_cleanup

DESCRIPTION
   Cleans location engine. The location client handle will be released.

DEPENDENCIES
   None

RETURN VALUE
   None

SIDE EFFECTS
   N/A

===========================================================================*/
void loc_eng_cleanup(loc_eng_data_s_type &loc_eng_data)
{
    ENTRY_LOG_CALLFLOW();
    INIT_CHECK(loc_eng_data.adapter, return);

    // XTRA has no state, so we are fine with it.

    // we need to check and clear NI
#if 0
    // we need to check and clear ATL
    if (NULL != loc_eng_data.agnss_nif) {
        delete loc_eng_data.agnss_nif;
        loc_eng_data.agnss_nif = NULL;
    }
    if (NULL != loc_eng_data.internet_nif) {
        delete loc_eng_data.internet_nif;
        loc_eng_data.internet_nif = NULL;
    }
#endif
    if (loc_eng_data.adapter->isInSession())
    {
        LOC_LOGD("loc_eng_cleanup: fix not stopped. stop it now.");
        loc_eng_stop(loc_eng_data);
    }

#if 0 // can't afford to actually clean up, for many reason.

    LOC_LOGD("loc_eng_init: client opened. close it now.");
    delete loc_eng_data.adapter;
    loc_eng_data.adapter = NULL;

    loc_eng_dmn_conn_loc_api_server_unblock();
    loc_eng_dmn_conn_loc_api_server_join();

#endif

    EXIT_LOG(%s, VOID_RET);
}


/*===========================================================================
FUNCTION    loc_eng_start

DESCRIPTION
   Starts the tracking session

DEPENDENCIES
   None

RETURN VALUE
   0: success

SIDE EFFECTS
   N/A

===========================================================================*/
int loc_eng_start(loc_eng_data_s_type &loc_eng_data)
{
   ENTRY_LOG_CALLFLOW();
   INIT_CHECK(loc_eng_data.adapter, return -1);

   if(! loc_eng_data.adapter->getUlpProxy()->sendStartFix())
   {
       loc_eng_data.adapter->sendMsg(new LocEngStartFix(loc_eng_data.adapter));
   }

   EXIT_LOG(%d, 0);
   return 0;
}

static int loc_eng_start_handler(loc_eng_data_s_type &loc_eng_data)
{
   ENTRY_LOG();
   int ret_val = LOC_API_ADAPTER_ERR_SUCCESS;

   if (!loc_eng_data.adapter->isInSession()) {
       ret_val = loc_eng_data.adapter->startFix();

       if (ret_val == LOC_API_ADAPTER_ERR_SUCCESS ||
           ret_val == LOC_API_ADAPTER_ERR_ENGINE_DOWN ||
           ret_val == LOC_API_ADAPTER_ERR_PHONE_OFFLINE ||
           ret_val == LOC_API_ADAPTER_ERR_INTERNAL)
       {
           loc_eng_data.adapter->setInSession(TRUE);
       }
   }

   EXIT_LOG(%d, ret_val);
   return ret_val;
}

/*===========================================================================
FUNCTION    loc_eng_stop_wrapper

DESCRIPTION
   Stops the tracking session

DEPENDENCIES
   None

RETURN VALUE
   0: success

SIDE EFFECTS
   N/A

===========================================================================*/
int loc_eng_stop(loc_eng_data_s_type &loc_eng_data)
{
    ENTRY_LOG_CALLFLOW();
    INIT_CHECK(loc_eng_data.adapter, return -1);

    if(! loc_eng_data.adapter->getUlpProxy()->sendStopFix())
    {
        loc_eng_data.adapter->sendMsg(new LocEngStopFix(loc_eng_data.adapter));
    }

    EXIT_LOG(%d, 0);
    return 0;
}

static int loc_eng_stop_handler(loc_eng_data_s_type &loc_eng_data)
{
   ENTRY_LOG();
   int ret_val = LOC_API_ADAPTER_ERR_SUCCESS;

   if (loc_eng_data.adapter->isInSession()) {

       ret_val = loc_eng_data.adapter->stopFix();
       loc_eng_data.adapter->setInSession(FALSE);
   }

    EXIT_LOG(%d, ret_val);
    return ret_val;
}

/*===========================================================================
FUNCTION    loc_eng_mute_one_session

DESCRIPTION
   Mutes one session

DEPENDENCIES
   None

RETURN VALUE
   0: Success

SIDE EFFECTS
   N/A

===========================================================================*/
void loc_eng_mute_one_session(loc_eng_data_s_type &loc_eng_data)
{
    ENTRY_LOG();
    loc_eng_data.mute_session_state = LOC_MUTE_SESS_WAIT;
    EXIT_LOG(%s, VOID_RET);
}

/*===========================================================================
FUNCTION    loc_eng_set_position_mode

DESCRIPTION
   Sets the mode and fix frequency for the tracking session.

DEPENDENCIES
   None

RETURN VALUE
   0: success

SIDE EFFECTS
   N/A

===========================================================================*/
int loc_eng_set_position_mode(loc_eng_data_s_type &loc_eng_data,
                              LocPosMode &params)
{
    ENTRY_LOG_CALLFLOW();
    INIT_CHECK(loc_eng_data.adapter, return -1);

    // The position mode for AUTO/GSS/QCA1530 can only be standalone
    if (!(gps_conf.CAPABILITIES & GPS_CAPABILITY_MSB) &&
        !(gps_conf.CAPABILITIES & GPS_CAPABILITY_MSA) &&
        (params.mode != LOC_POSITION_MODE_STANDALONE)) {
        params.mode = LOC_POSITION_MODE_STANDALONE;
        LOC_LOGD("Position mode changed to standalone for target with AUTO/GSS/qca1530.");
    }

    if(! loc_eng_data.adapter->getUlpProxy()->sendFixMode(params))
    {
        LocEngAdapter* adapter = loc_eng_data.adapter;
        adapter->sendMsg(new LocEngPositionMode(adapter, params));
    }

    EXIT_LOG(%d, 0);
    return 0;
}

/*===========================================================================
FUNCTION    loc_eng_inject_time

DESCRIPTION
   This is used by Java native function to do time injection.

DEPENDENCIES
   None

RETURN VALUE
   0

SIDE EFFECTS
   N/A

===========================================================================*/
int loc_eng_inject_time(loc_eng_data_s_type &loc_eng_data, GpsUtcTime time,
                        int64_t timeReference, int uncertainty)
{
    ENTRY_LOG_CALLFLOW();
    INIT_CHECK(loc_eng_data.adapter, return -1);
    LocEngAdapter* adapter = loc_eng_data.adapter;

    adapter->sendMsg(new LocEngSetTime(adapter, time, timeReference,
                                       uncertainty));

    EXIT_LOG(%d, 0);
    return 0;
}


/*===========================================================================
FUNCTION    loc_eng_inject_location

DESCRIPTION
   This is used by Java native function to do location injection.

DEPENDENCIES
   None

RETURN VALUE
   0          : Successful
   error code : Failure

SIDE EFFECTS
   N/A
===========================================================================*/
int loc_eng_inject_location(loc_eng_data_s_type &loc_eng_data, double latitude,
                            double longitude, float accuracy)
{
    ENTRY_LOG_CALLFLOW();
    INIT_CHECK(loc_eng_data.adapter, return -1);
    LocEngAdapter* adapter = loc_eng_data.adapter;
    if(adapter->mSupportsPositionInjection)
    {
        adapter->sendMsg(new LocEngInjectLocation(adapter, latitude, longitude,
                                                  accuracy));
    }

    EXIT_LOG(%d, 0);
    return 0;
}


/*===========================================================================
FUNCTION    loc_eng_delete_aiding_data

DESCRIPTION
   This is used by Java native function to delete the aiding data. The function
   updates the global variable for the aiding data to be deleted. If the GPS
   engine is off, the aiding data will be deleted. Otherwise, the actual action
   will happen when gps engine is turned off.

DEPENDENCIES
   Assumes the aiding data type specified in GpsAidingData matches with
   LOC API specification.

RETURN VALUE
   None

SIDE EFFECTS
   N/A

===========================================================================*/
void loc_eng_delete_aiding_data(loc_eng_data_s_type &loc_eng_data, GpsAidingData f)
{
    ENTRY_LOG_CALLFLOW();
    INIT_CHECK(loc_eng_data.adapter, return);

    loc_eng_data.adapter->sendMsg(new LocEngDelAidData(&loc_eng_data, f));

    EXIT_LOG(%s, VOID_RET);
}

/*===========================================================================

FUNCTION    loc_inform_gps_state

DESCRIPTION
   Informs the GPS Provider about the GPS status

DEPENDENCIES
   None

RETURN VALUE
   None

SIDE EFFECTS
   N/A

===========================================================================*/
static void loc_inform_gps_status(loc_eng_data_s_type &loc_eng_data, GpsStatusValue status)
{
    ENTRY_LOG();

    if (loc_eng_data.status_cb)
    {
        GpsStatus gs = { sizeof(gs),status };
        CALLBACK_LOG_CALLFLOW("status_cb", %s,
                              loc_get_gps_status_name(gs.status));
        loc_eng_data.status_cb(&gs);
    }

    EXIT_LOG(%s, VOID_RET);
}

static int loc_eng_get_zpp_handler(loc_eng_data_s_type &loc_eng_data)
{
   ENTRY_LOG();
   int ret_val = LOC_API_ADAPTER_ERR_SUCCESS;
   UlpLocation location;
   LocPosTechMask tech_mask = LOC_POS_TECH_MASK_DEFAULT;
   GpsLocationExtended locationExtended;
   memset(&locationExtended, 0, sizeof (GpsLocationExtended));
   locationExtended.size = sizeof(locationExtended);

   ret_val = loc_eng_data.adapter->getZpp(location.gpsLocation, tech_mask);
  //Mark the location source as from ZPP
  location.gpsLocation.flags |= LOCATION_HAS_SOURCE_INFO;
  location.position_source = ULP_LOCATION_IS_FROM_ZPP;

  loc_eng_data.adapter->getUlpProxy()->reportPosition(location,
                                     locationExtended,
                                     NULL,
                                     LOC_SESS_SUCCESS,
                                     tech_mask);

  EXIT_LOG(%d, ret_val);
  return ret_val;
}

/*
  Callback function passed to Data Services State Machine
  This becomes part of the state machine's servicer and
  is used to send requests to the data services client
*/
static int dataCallCb(void *cb_data)
{
    LOC_LOGD("Enter dataCallCb\n");
    int ret=0;
    if(cb_data != NULL) {
        dsCbData *cbData = (dsCbData *)cb_data;
        LocEngAdapter *locAdapter = (LocEngAdapter *)cbData->mAdapter;
        if(cbData->action == GPS_REQUEST_AGPS_DATA_CONN) {
            LOC_LOGD("dataCallCb GPS_REQUEST_AGPS_DATA_CONN\n");
            ret =  locAdapter->openAndStartDataCall();
        }
        else if(cbData->action == GPS_RELEASE_AGPS_DATA_CONN) {
            LOC_LOGD("dataCallCb GPS_RELEASE_AGPS_DATA_CONN\n");
            locAdapter->stopDataCall();
        }
    }
    else {
        LOC_LOGE("NULL argument received. Failing.\n");
        ret = -1;
        goto err;
    }

err:
    LOC_LOGD("Exit dataCallCb ret = %d\n", ret);
    return ret;
}

/*===========================================================================
FUNCTION    loc_eng_agps_reinit

DESCRIPTION
   2nd half of loc_eng_agps_init(), singled out for modem restart to use.

DEPENDENCIES
   NONE

RETURN VALUE
   0

SIDE EFFECTS
   N/A

===========================================================================*/
static void loc_eng_agps_reinit(loc_eng_data_s_type &loc_eng_data)
{
    ENTRY_LOG();

    // Set server addresses which came before init
    if (loc_eng_data.supl_host_set)
    {
        loc_eng_set_server(loc_eng_data, LOC_AGPS_SUPL_SERVER,
                           loc_eng_data.supl_host_buf,
                           loc_eng_data.supl_port_buf);
    }

    if (loc_eng_data.c2k_host_set)
    {
        loc_eng_set_server(loc_eng_data, LOC_AGPS_CDMA_PDE_SERVER,
                           loc_eng_data.c2k_host_buf,
                           loc_eng_data.c2k_port_buf);
    }
    EXIT_LOG(%s, VOID_RET);
}
/*===========================================================================
FUNCTION    loc_eng_agps_init

DESCRIPTION
   Initialize the AGps interface.

DEPENDENCIES
   NONE

RETURN VALUE
   0

SIDE EFFECTS
   N/A

===========================================================================*/
void loc_eng_agps_init(loc_eng_data_s_type &loc_eng_data, AGpsExtCallbacks* callbacks)
{
    ENTRY_LOG_CALLFLOW();
    INIT_CHECK(loc_eng_data.adapter, return);
    STATE_CHECK((NULL == loc_eng_data.agps_status_cb),
                "agps instance already initialized",
                return);
    if (callbacks == NULL) {
        LOC_LOGE("loc_eng_agps_init: bad parameters cb %p", callbacks);
        EXIT_LOG(%s, VOID_RET);
        return;
    }
    LocEngAdapter* adapter = loc_eng_data.adapter;
    loc_eng_data.agps_status_cb = callbacks->status_cb;

    loc_eng_data.internet_nif = new AgpsStateMachine(servicerTypeAgps,
                                                     (void *)loc_eng_data.agps_status_cb,
                                                     AGPS_TYPE_WWAN_ANY,
                                                     false);
    loc_eng_data.wifi_nif = new AgpsStateMachine(servicerTypeAgps,
                                                 (void *)loc_eng_data.agps_status_cb,
                                                 AGPS_TYPE_WIFI,
                                                 true);

    if ((gps_conf.CAPABILITIES & GPS_CAPABILITY_MSA) ||
        (gps_conf.CAPABILITIES & GPS_CAPABILITY_MSB)) {
        loc_eng_data.agnss_nif = new AgpsStateMachine(servicerTypeAgps,
                                                      (void *)loc_eng_data.agps_status_cb,
                                                      AGPS_TYPE_SUPL,
                                                      false);

        if (adapter->mSupportsAgpsRequests) {
            if(gps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
                loc_eng_data.adapter->sendMsg(new LocEngDataClientInit(&loc_eng_data));
            }
            loc_eng_dmn_conn_loc_api_server_launch(callbacks->create_thread_cb,
                                                   NULL, NULL, &loc_eng_data);
        }
        loc_eng_agps_reinit(loc_eng_data);
    }

    EXIT_LOG(%s, VOID_RET);
}

static void deleteAidingData(loc_eng_data_s_type &logEng) {
    if (logEng.engine_status != GPS_STATUS_ENGINE_ON &&
        logEng.aiding_data_for_deletion != 0) {
        logEng.adapter->deleteAidingData(logEng.aiding_data_for_deletion);
        logEng.aiding_data_for_deletion = 0;
    }
}

static AgpsStateMachine*
getAgpsStateMachine(loc_eng_data_s_type &locEng, AGpsExtType agpsType) {
    AgpsStateMachine* stateMachine;
    switch (agpsType) {
    case AGPS_TYPE_WIFI: {
        stateMachine = locEng.wifi_nif;
        break;
    }
    case AGPS_TYPE_INVALID:
    case AGPS_TYPE_SUPL: {
        stateMachine = locEng.agnss_nif;
        break;
    }
    case AGPS_TYPE_SUPL_ES: {
        locEng.ds_nif ?
            stateMachine = locEng.ds_nif:
            stateMachine = locEng.agnss_nif;
        break;
    }
    default:
        stateMachine  = locEng.internet_nif;
    }
    return stateMachine;
}

/*===========================================================================
FUNCTION    loc_eng_agps_open

DESCRIPTION
   This function is called when on-demand data connection opening is successful.
It should inform engine about the data open result.

DEPENDENCIES
   NONE

RETURN VALUE
   0

SIDE EFFECTS
   N/A

===========================================================================*/
int loc_eng_agps_open(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType,
                     const char* apn, AGpsBearerType bearerType)
{
    ENTRY_LOG_CALLFLOW();
    INIT_CHECK(loc_eng_data.adapter && loc_eng_data.agps_status_cb,
               return -1);

    if (apn == NULL)
    {
        LOC_LOGE("APN Name NULL\n");
        return 0;
    }

    LOC_LOGD("loc_eng_agps_open APN name = [%s]", apn);

    int apn_len = smaller_of(strlen (apn), MAX_APN_LEN);
    AgpsStateMachine* sm = getAgpsStateMachine(loc_eng_data, agpsType);

    loc_eng_data.adapter->sendMsg(
        new LocEngAtlOpenSuccess(sm, apn, apn_len, bearerType));

    EXIT_LOG(%d, 0);
    return 0;
}

/*===========================================================================
FUNCTION    loc_eng_agps_closed

DESCRIPTION
   This function is called when on-demand data connection closing is done.
It should inform engine about the data close result.

DEPENDENCIES
   NONE

RETURN VALUE
   0

SIDE EFFECTS
   N/A

===========================================================================*/
int loc_eng_agps_closed(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType)
{
    ENTRY_LOG_CALLFLOW();
    INIT_CHECK(loc_eng_data.adapter && loc_eng_data.agps_status_cb,
               return -1);

    AgpsStateMachine* sm = getAgpsStateMachine(loc_eng_data, agpsType);
    loc_eng_data.adapter->sendMsg(new LocEngAtlClosed(sm));

    EXIT_LOG(%d, 0);
    return 0;
}

/*===========================================================================
FUNCTION    loc_eng_agps_open_failed

DESCRIPTION
   This function is called when on-demand data connection opening has failed.
It should inform engine about the data open result.

DEPENDENCIES
   NONE

RETURN VALUE
   0

SIDE EFFECTS
   N/A

===========================================================================*/
int loc_eng_agps_open_failed(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType)
{
    ENTRY_LOG_CALLFLOW();
    INIT_CHECK(loc_eng_data.adapter && loc_eng_data.agps_status_cb,
               return -1);

    AgpsStateMachine* sm = getAgpsStateMachine(loc_eng_data, agpsType);
    loc_eng_data.adapter->sendMsg(new LocEngAtlOpenFailed(sm));

    EXIT_LOG(%d, 0);
    return 0;
}

/*===========================================================================

FUNCTION resolve_in_addr

DESCRIPTION
   Translates a hostname to in_addr struct

DEPENDENCIES
   n/a

RETURN VALUE
   TRUE if successful

SIDE EFFECTS
   n/a

===========================================================================*/
static boolean resolve_in_addr(const char *host_addr, struct in_addr *in_addr_ptr)
{
    ENTRY_LOG();
    boolean ret_val = TRUE;

    struct hostent             *hp;
    hp = gethostbyname(host_addr);
    if (hp != NULL) /* DNS OK */
    {
        memcpy(in_addr_ptr, hp->h_addr_list[0], hp->h_length);
    }
    else
    {
        /* Try IP representation */
        if (inet_aton(host_addr, in_addr_ptr) == 0)
        {
            /* IP not valid */
            LOC_LOGE("DNS query on '%s' failed\n", host_addr);
            ret_val = FALSE;
        }
    }

    EXIT_LOG(%s, loc_logger_boolStr[ret_val!=0]);
    return ret_val;
}

/*===========================================================================
FUNCTION    loc_eng_set_server

DESCRIPTION
   This is used to set the default AGPS server. Server address is obtained
   from gps.conf.

DEPENDENCIES
   NONE

RETURN VALUE
   0

SIDE EFFECTS
   N/A

===========================================================================*/
static int loc_eng_set_server(loc_eng_data_s_type &loc_eng_data,
                              LocServerType type, const char* hostname, int port)
{
    ENTRY_LOG();
    int ret = 0;
    LocEngAdapter* adapter = loc_eng_data.adapter;

    if (LOC_AGPS_SUPL_SERVER == type) {
        char url[MAX_URL_LEN];
        unsigned int len = 0;
        const char nohost[] = "NONE";
        if (hostname == NULL ||
            strncasecmp(nohost, hostname, sizeof(nohost)) == 0) {
            url[0] = NULL;
        } else {
            len = snprintf(url, sizeof(url), "%s:%u", hostname, (unsigned) port);
        }

        if (sizeof(url) > len) {
            adapter->sendMsg(new LocEngSetServerUrl(adapter, url, len));
        }
    } else if (LOC_AGPS_CDMA_PDE_SERVER == type ||
               LOC_AGPS_CUSTOM_PDE_SERVER == type ||
               LOC_AGPS_MPC_SERVER == type) {
        struct in_addr addr;
        if (!resolve_in_addr(hostname, &addr))
        {
            LOC_LOGE("loc_eng_set_server, hostname %s cannot be resolved.\n", hostname);
            ret = -2;
        } else {
            unsigned int ip = htonl(addr.s_addr);
            adapter->sendMsg(new LocEngSetServerIpv4(adapter, ip, port, type));
        }
    } else {
        LOC_LOGE("loc_eng_set_server, type %d cannot be resolved.\n", type);
    }

    EXIT_LOG(%d, ret);
    return ret;
}

/*===========================================================================
FUNCTION    loc_eng_set_server_proxy

DESCRIPTION
   If loc_eng_set_server is called before loc_eng_init, it doesn't work. This
   proxy buffers server settings and calls loc_eng_set_server when the client is
   open.

DEPENDENCIES
   NONE

RETURN VALUE
   0

SIDE EFFECTS
   N/A

===========================================================================*/
int loc_eng_set_server_proxy(loc_eng_data_s_type &loc_eng_data,
                             LocServerType type,
                             const char* hostname, int port)
{
    ENTRY_LOG_CALLFLOW();
    int ret_val = 0;

    if (NULL != loc_eng_data.adapter)
    {
        ret_val = loc_eng_set_server(loc_eng_data, type, hostname, port);
    } else {
        LOC_LOGW("set_server called before init. save the address, type: %d, hostname: %s, port: %d",
                 (int) type, hostname, port);
        switch (type)
        {
        case LOC_AGPS_SUPL_SERVER:
            strlcpy(loc_eng_data.supl_host_buf, hostname,
                    sizeof(loc_eng_data.supl_host_buf));
            loc_eng_data.supl_port_buf = port;
            loc_eng_data.supl_host_set = 1;
            break;
        case LOC_AGPS_CDMA_PDE_SERVER:
            strlcpy(loc_eng_data.c2k_host_buf, hostname,
                    sizeof(loc_eng_data.c2k_host_buf));
            loc_eng_data.c2k_port_buf = port;
            loc_eng_data.c2k_host_set = 1;
            break;
        default:
            LOC_LOGE("loc_eng_set_server_proxy, unknown server type = %d", (int) type);
        }
    }

    EXIT_LOG(%d, ret_val);
    return ret_val;
}

/*===========================================================================
FUNCTION    loc_eng_agps_ril_update_network_availability

DESCRIPTION
   Sets data call allow vs disallow flag to modem
   This is the only member of sLocEngAGpsRilInterface implemented.

DEPENDENCIES
   None

RETURN VALUE
   0: success

SIDE EFFECTS
   N/A

===========================================================================*/
void loc_eng_agps_ril_update_network_availability(loc_eng_data_s_type &loc_eng_data,
                                                  int available, const char* apn)
{
    ENTRY_LOG_CALLFLOW();

    //This is to store the status of data availability over the network.
    //If GPS is not enabled, the INIT_CHECK will fail and the modem will
    //not be updated with the network's availability. Since the data status
    //can change before GPS is enabled the, storing the status will enable
    //us to inform the modem after GPS is enabled
    agpsStatus = available;

    INIT_CHECK(loc_eng_data.adapter, return);
    if (apn != NULL)
    {
        LOC_LOGD("loc_eng_agps_ril_update_network_availability: APN Name = [%s]\n", apn);
        int apn_len = smaller_of(strlen (apn), MAX_APN_LEN);
        LocEngAdapter* adapter = loc_eng_data.adapter;
        adapter->sendMsg(new LocEngEnableData(adapter, apn,  apn_len, available));
    }
    EXIT_LOG(%s, VOID_RET);
}

int loc_eng_agps_install_certificates(loc_eng_data_s_type &loc_eng_data,
                                      const DerEncodedCertificate* certificates,
                                      size_t numberOfCerts)
{
    ENTRY_LOG_CALLFLOW();
    int ret_val = AGPS_CERTIFICATE_OPERATION_SUCCESS;

    uint32_t slotBitMask = gps_conf.AGPS_CERT_WRITABLE_MASK;
    uint32_t slotCount = 0;
    for (uint32_t slotBitMaskCounter=slotBitMask; slotBitMaskCounter; slotCount++) {
        slotBitMaskCounter &= slotBitMaskCounter - 1;
    }
    LOC_LOGD("SlotBitMask=%u SlotCount=%u NumberOfCerts=%u",
             slotBitMask, slotCount, numberOfCerts);

    LocEngAdapter* adapter = loc_eng_data.adapter;

    if (numberOfCerts == 0) {
        LOC_LOGE("No certs to install, since numberOfCerts is zero");
        ret_val = AGPS_CERTIFICATE_OPERATION_SUCCESS;
    } else if (!adapter) {
        LOC_LOGE("adapter is null!");
        ret_val = AGPS_CERTIFICATE_ERROR_GENERIC;
    } else if (slotCount < numberOfCerts) {
        LOC_LOGE("Not enough cert slots (%u) to install %u certs!",
                 slotCount, numberOfCerts);
        ret_val = AGPS_CERTIFICATE_ERROR_TOO_MANY_CERTIFICATES;
    } else {
        for (int i=0; i < numberOfCerts; ++i)
        {
            if (certificates[i].length > AGPS_CERTIFICATE_MAX_LENGTH) {
                LOC_LOGE("cert#(%u) length of %u is too big! greater than %u",
                        certificates[i].length, AGPS_CERTIFICATE_MAX_LENGTH);
                ret_val = AGPS_CERTIFICATE_ERROR_GENERIC;
                break;
            }
        }

        if (ret_val == AGPS_CERTIFICATE_OPERATION_SUCCESS) {
            adapter->sendMsg(new LocEngInstallAGpsCert(adapter,
                                                       certificates,
                                                       numberOfCerts,
                                                       slotBitMask));
        }
    }

    EXIT_LOG(%d, ret_val);
    return ret_val;
}

void loc_eng_configuration_update (loc_eng_data_s_type &loc_eng_data,
                                   const char* config_data, int32_t length)
{
    ENTRY_LOG_CALLFLOW();

    if (config_data && length > 0) {
        loc_gps_cfg_s_type gps_conf_tmp = gps_conf;
        UTIL_UPDATE_CONF(config_data, length, gps_conf_table);
        LocEngAdapter* adapter = loc_eng_data.adapter;

        // it is possible that HAL is not init'ed at this time
        if (adapter) {
            if (gps_conf_tmp.SUPL_VER != gps_conf.SUPL_VER) {
                adapter->sendMsg(new LocEngSuplVer(adapter, gps_conf.SUPL_VER));
            }
            if (gps_conf_tmp.LPP_PROFILE != gps_conf.LPP_PROFILE) {
                adapter->sendMsg(new LocEngLppConfig(adapter, gps_conf.LPP_PROFILE));
            }
            if (gps_conf_tmp.A_GLONASS_POS_PROTOCOL_SELECT != gps_conf.A_GLONASS_POS_PROTOCOL_SELECT) {
                adapter->sendMsg(new LocEngAGlonassProtocol(adapter,
                                                            gps_conf.A_GLONASS_POS_PROTOCOL_SELECT));
            }
            if (gps_conf_tmp.SUPL_MODE != gps_conf.SUPL_MODE) {
                adapter->sendMsg(new LocEngSuplMode(adapter->getUlpProxy()));
            }
        }

        gps_conf_tmp.SUPL_VER = gps_conf.SUPL_VER;
        gps_conf_tmp.LPP_PROFILE = gps_conf.LPP_PROFILE;
        gps_conf_tmp.A_GLONASS_POS_PROTOCOL_SELECT = gps_conf.A_GLONASS_POS_PROTOCOL_SELECT;
        gps_conf_tmp.GPS_LOCK = gps_conf.GPS_LOCK;
        gps_conf = gps_conf_tmp;
    }

    EXIT_LOG(%s, VOID_RET);
}

/*===========================================================================
FUNCTION    loc_eng_report_status

DESCRIPTION
   Reports GPS engine state to Java layer.

DEPENDENCIES
   N/A

RETURN VALUE
   N/A

SIDE EFFECTS
   N/A

===========================================================================*/
static void loc_eng_report_status (loc_eng_data_s_type &loc_eng_data, GpsStatusValue status)
{
    ENTRY_LOG();
    // Switch from WAIT to MUTE, for "engine on" or "session begin" event
    if (status == GPS_STATUS_SESSION_BEGIN || status == GPS_STATUS_ENGINE_ON)
    {
        if (loc_eng_data.mute_session_state == LOC_MUTE_SESS_WAIT)
        {
            LOC_LOGD("loc_eng_report_status: mute_session_state changed from WAIT to IN SESSION");
            loc_eng_data.mute_session_state = LOC_MUTE_SESS_IN_SESSION;
        }
    }

    // Switch off MUTE session
    if (loc_eng_data.mute_session_state == LOC_MUTE_SESS_IN_SESSION &&
        (status == GPS_STATUS_SESSION_END || status == GPS_STATUS_ENGINE_OFF))
    {
        LOC_LOGD("loc_eng_report_status: mute_session_state changed from IN SESSION to NONE");
        loc_eng_data.mute_session_state = LOC_MUTE_SESS_NONE;
    }

    // Session End is not reported during Android navigating state
    boolean navigating = loc_eng_data.adapter->isInSession();
    if (status != GPS_STATUS_NONE &&
        !(status == GPS_STATUS_SESSION_END && navigating) &&
        !(status == GPS_STATUS_SESSION_BEGIN && !navigating))
    {
        if (loc_eng_data.mute_session_state != LOC_MUTE_SESS_IN_SESSION)
        {
            // Inform GpsLocationProvider about mNavigating status
            loc_inform_gps_status(loc_eng_data, status);
        }
        else {
            LOC_LOGD("loc_eng_report_status: muting the status report.");
        }
    }

    // Only keeps ENGINE ON/OFF in engine_status
    if (status == GPS_STATUS_ENGINE_ON || status == GPS_STATUS_ENGINE_OFF)
    {
        loc_eng_data.engine_status = status;
    }

    // Only keeps SESSION BEGIN/END in fix_session_status
    if (status == GPS_STATUS_SESSION_BEGIN || status == GPS_STATUS_SESSION_END)
    {
        loc_eng_data.fix_session_status = status;
    }
    EXIT_LOG(%s, VOID_RET);
}

/*===========================================================================
FUNCTION loc_eng_handle_engine_down
         loc_eng_handle_engine_up

DESCRIPTION
   Calls this function when it is detected that modem restart is happening.
   Either we detected the modem is down or received modem up event.
   This must be called from the deferred thread to avoid race condition.

DEPENDENCIES
   None

RETURN VALUE
   None

SIDE EFFECTS
   N/A

===========================================================================*/
void loc_eng_handle_engine_down(loc_eng_data_s_type &loc_eng_data)
{
    ENTRY_LOG();
    loc_eng_ni_reset_on_engine_restart(loc_eng_data);
    loc_eng_report_status(loc_eng_data, GPS_STATUS_ENGINE_OFF);
    EXIT_LOG(%s, VOID_RET);
}

void loc_eng_handle_engine_up(loc_eng_data_s_type &loc_eng_data)
{
    ENTRY_LOG();
    loc_eng_reinit(loc_eng_data);

    loc_eng_data.adapter->requestPowerVote();

    if (loc_eng_data.agps_status_cb != NULL) {
        if (loc_eng_data.agnss_nif)
            loc_eng_data.agnss_nif->dropAllSubscribers();
        if (loc_eng_data.internet_nif)
            loc_eng_data.internet_nif->dropAllSubscribers();

        loc_eng_agps_reinit(loc_eng_data);
    }

    // modem is back up.  If we crashed in the middle of navigating, we restart.
    if (loc_eng_data.adapter->isInSession()) {
        // This sets the copy in adapter to modem
        loc_eng_data.adapter->setPositionMode(NULL);
        loc_eng_data.adapter->setInSession(false);
        loc_eng_start_handler(loc_eng_data);
    }
    EXIT_LOG(%s, VOID_RET);
}

#ifdef USE_GLIB
/*===========================================================================
FUNCTION set_sched_policy

DESCRIPTION
   Local copy of this function which bypasses android set_sched_policy

DEPENDENCIES
   None

RETURN VALUE
   0

SIDE EFFECTS
   N/A

===========================================================================*/
static int set_sched_policy(int tid, SchedPolicy policy)
{
    return 0;
}
#endif /* USE_GLIB */

/*===========================================================================
FUNCTION    loc_eng_read_config

DESCRIPTION
   Initiates the reading of the gps config file stored in /etc dir

DEPENDENCIES
   None

RETURN VALUE
   0: success

SIDE EFFECTS
   N/A

===========================================================================*/
int loc_eng_read_config(void)
{
    ENTRY_LOG_CALLFLOW();
    if(configAlreadyRead == false)
    {
      // Initialize our defaults before reading of configuration file overwrites them.
      loc_default_parameters();
      // We only want to parse the conf file once. This is a good place to ensure that.
      // In fact one day the conf file should go into context.
      UTIL_READ_CONF(GPS_CONF_FILE, gps_conf_table);
      UTIL_READ_CONF(SAP_CONF_FILE, sap_conf_table);
      configAlreadyRead = true;
    } else {
      LOC_LOGV("GPS Config file has already been read\n");
    }

    EXIT_LOG(%d, 0);
    return 0;
}

/*===========================================================================
FUNCTION    loc_eng_gps_measurement_init

DESCRIPTION
   Initialize gps measurement module.

DEPENDENCIES
   N/A

RETURN VALUE
   0: success

SIDE EFFECTS
   N/A

===========================================================================*/
int loc_eng_gps_measurement_init(loc_eng_data_s_type &loc_eng_data,
                                 GpsMeasurementCallbacks* callbacks)
{
    ENTRY_LOG_CALLFLOW();

    STATE_CHECK((NULL == loc_eng_data.gps_measurement_cb),
                "gps measurement already initialized",
                return GPS_MEASUREMENT_ERROR_ALREADY_INIT);
    STATE_CHECK((callbacks != NULL),
                "callbacks can not be NULL",
                return GPS_MEASUREMENT_ERROR_GENERIC);
    STATE_CHECK(loc_eng_data.adapter,
                "GpsInterface must be initialized first",
                return GPS_MEASUREMENT_ERROR_GENERIC);

    // updated the mask
    LOC_API_ADAPTER_EVENT_MASK_T event = LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT;
    loc_eng_data.adapter->sendMsg(new LocEngUpdateRegistrationMask(
                                                        &loc_eng_data,
                                                        event,
                                                        LOC_REGISTRATION_MASK_ENABLED));
    // set up the callback
    loc_eng_data.gps_measurement_cb = callbacks->measurement_callback;
    LOC_LOGD ("%s, event masks updated successfully", __func__);

    return GPS_MEASUREMENT_OPERATION_SUCCESS;
}

/*===========================================================================
FUNCTION    loc_eng_gps_measurement_close

DESCRIPTION
   Close gps measurement module.

DEPENDENCIES
   N/A

RETURN VALUE
   N/A

SIDE EFFECTS
   N/A

===========================================================================*/
void loc_eng_gps_measurement_close(loc_eng_data_s_type &loc_eng_data)
{
    ENTRY_LOG_CALLFLOW();

    INIT_CHECK(loc_eng_data.adapter, return);

    // updated the mask
    LOC_API_ADAPTER_EVENT_MASK_T event = LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT;
    loc_eng_data.adapter->sendMsg(new LocEngUpdateRegistrationMask(
                                                          &loc_eng_data,
                                                          event,
                                                          LOC_REGISTRATION_MASK_DISABLED));
    // set up the callback
    loc_eng_data.gps_measurement_cb = NULL;
    EXIT_LOG(%d, 0);
}
