/* 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 <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

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'},
  {"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'},
};

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 */
   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.CAPABILITIES = 0x7;

   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;

      /* 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;

   /* 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 loc_eng_handle_shutdown(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);
}


LocEngShutdown::LocEngShutdown(LocEngAdapter* adapter) :
    LocMsg(), mAdapter(adapter)
{
    locallog();
}
inline void LocEngShutdown::proc() const
{
    loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mAdapter->getOwner();
    LOC_LOGD("%s:%d]: Calling loc_eng_handle_shutdown", __func__, __LINE__);
    loc_eng_handle_shutdown(*locEng);
}
inline void LocEngShutdown::locallog() const
{
    LOC_LOGV("LocEngShutdown");
}
inline void LocEngShutdown::log() const
{
    locallog();
}

//        case LOC_ENG_MSG_SET_TIME:
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();
    }
};

//        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("flags: %d\n  source: %d\n  latitude: %f\n  longitude: %f\n  "
             "altitude: %f\n  speed: %f\n  bearing: %f\n  accuracy: %f\n  "
             "timestamp: %lld\n  rawDataSize: %d\n  rawData: %p\n  Session"
             " status: %d\n Technology mask: %u",
             mLocation.gpsLocation.flags, mLocation.position_source,
             mLocation.gpsLocation.latitude, mLocation.gpsLocation.longitude,
             mLocation.gpsLocation.altitude, mLocation.gpsLocation.speed,
             mLocation.gpsLocation.bearing, mLocation.gpsLocation.accuracy,
             mLocation.gpsLocation.timestamp, mLocation.rawDataSize,
             mLocation.rawData, mStatus, mTechMask);
}
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("num sv: %d\n  ephemeris mask: %dxn  almanac mask: %x\n  "
             "used in fix mask: %x\n      sv: prn         snr       "
             "elevation      azimuth",
             mSvStatus.num_svs, mSvStatus.ephemeris_mask,
             mSvStatus.almanac_mask, mSvStatus.used_in_fix_mask);
    for (int i = 0; i < mSvStatus.num_svs && i < GPS_MAX_SVS; i++) {
        LOC_LOGV("   %d:   %d    %f    %f    %f\n  ",
                 i,
                 mSvStatus.sv_list[i].prn,
                 mSvStatus.sv_list[i].snr,
                 mSvStatus.sv_list[i].elevation,
                 mSvStatus.sv_list[i].azimuth);
    }
}
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;
    CALLBACK_LOG_CALLFLOW("nmea_cb", %d, mLen);

    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)])
{
    memset(mServers, 0, 3*(mMaxLen+1));
    strlcpy(mServers, url1, mMaxLen);
    strlcpy(&(mServers[mMaxLen+1]), url2, mMaxLen);
    strlcpy(&(mServers[(mMaxLen+1)<<1]), url3, mMaxLen);
    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 {
        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)

/*===========================================================================
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;
    loc_eng_data.shutdown_cb = callbacks->shutdown_cb;
    // 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;

    if (LOC_API_ADAPTER_ERR_SUCCESS == ret_val) {
        LOC_LOGD("loc_eng_reinit reinit() successful");

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

    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)
       {
           loc_eng_data.adapter->setInSession(TRUE);
           loc_inform_gps_status(loc_eng_data, GPS_STATUS_SESSION_BEGIN);
       }
   }

   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();
       if (ret_val == LOC_API_ADAPTER_ERR_SUCCESS)
       {
           loc_inform_gps_status(loc_eng_data, GPS_STATUS_SESSION_END);
       }

       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);

    int gnssType = getTargetGnssType(loc_get_target());

    // The position mode for GSS/QCA1530 can only be standalone
    bool is1530 = gnssType == GNSS_QCA1530;
    bool isAPQ = gnssType == GNSS_GSS;
    if ((isAPQ || is1530) && params.mode != LOC_POSITION_MODE_STANDALONE) {
        params.mode = LOC_POSITION_MODE_STANDALONE;
        LOC_LOGD("Position mode changed to standalone for target with 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);
   memset(&location, 0, sizeof location);

   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);

    int gnssType = getTargetGnssType(loc_get_target());
    bool isAPQ = (gnssType == GNSS_GSS);
    bool is1530 = (gnssType == GNSS_QCA1530);
    if (!isAPQ && !is1530) {
        loc_eng_data.agnss_nif = new AgpsStateMachine(servicerTypeAgps,
                                                      (void *)loc_eng_data.agps_status_cb,
                                                      AGPS_TYPE_SUPL,
                                                      false);

        if (adapter->mSupportsAgpsRequests) {
            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: {
        stateMachine = locEng.ds_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;

    LOC_LOGV("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);
    }

    if (NULL != loc_eng_data.adapter)
    {
        ret_val = loc_eng_set_server(loc_eng_data, type, hostname, port);
    }

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

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

    loc_eng_report_status(loc_eng_data, GPS_STATUS_ENGINE_ON);

    // 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_handle_shutdown

DESCRIPTION
   Calls the shutdown callback function in the loc interface to close
   the modem node

DEPENDENCIES
   None

RETURN VALUE
   0: success

SIDE EFFECTS
   N/A

===========================================================================*/
void loc_eng_handle_shutdown(loc_eng_data_s_type &locEng)
{
    ENTRY_LOG();
    locEng.shutdown_cb();
    EXIT_LOG(%d, 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);
}
