/* 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 #include #include #include #include #include #include #include #include #include /* struct sockaddr_in */ #include #include #include #include #include #include #include #ifndef USE_GLIB #include #include #endif /* USE_GLIB */ #ifdef USE_GLIB #include #include #endif /* USE_GLIB */ #include #include #include #include #include #include #include #include #include #include "log_util.h" #include "platform_lib_includes.h" #include "loc_core_log.h" #include "loc_eng_log.h" #define SUCCESS TRUE #define FAILURE FALSE #ifndef GPS_CONF_FILE #define GPS_CONF_FILE "/etc/gps.conf" //??? platform independent #endif #ifndef SAP_CONF_FILE #define SAP_CONF_FILE "/etc/sap.conf" #endif #define XTRA1_GPSONEXTRA "xtra1.gpsonextra.net" using namespace loc_core; boolean configAlreadyRead = false; unsigned int agpsStatus = 0; loc_gps_cfg_s_type gps_conf; loc_sap_cfg_s_type sap_conf; /* Parameter spec table */ static loc_param_s_type loc_parameter_table[] = { {"INTERMEDIATE_POS", &gps_conf.INTERMEDIATE_POS, NULL, 'n'}, {"ACCURACY_THRES", &gps_conf.ACCURACY_THRES, NULL, 'n'}, {"NMEA_PROVIDER", &gps_conf.NMEA_PROVIDER, NULL, 'n'}, {"SUPL_VER", &gps_conf.SUPL_VER, NULL, 'n'}, {"CAPABILITIES", &gps_conf.CAPABILITIES, NULL, 'n'}, {"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'}, {"QUIPC_ENABLED", &gps_conf.QUIPC_ENABLED, NULL, 'n'}, {"LPP_PROFILE", &gps_conf.LPP_PROFILE, NULL, 'n'}, {"A_GLONASS_POS_PROTOCOL_SELECT", &gps_conf.A_GLONASS_POS_PROTOCOL_SELECT, NULL, 'n'}, {"SENSOR_PROVIDER", &sap_conf.SENSOR_PROVIDER, NULL, 'n'}, {"XTRA_SERVER_1", &gps_conf.XTRA_SERVER_1, NULL, 's'}, {"XTRA_SERVER_2", &gps_conf.XTRA_SERVER_2, NULL, 's'}, {"XTRA_SERVER_3", &gps_conf.XTRA_SERVER_3, NULL, 's'} }; static void loc_default_parameters(void) { /* defaults */ gps_conf.INTERMEDIATE_POS = 0; gps_conf.ACCURACY_THRES = 0; gps_conf.NMEA_PROVIDER = 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; } // 2nd half of init(), singled out for // modem restart to use. static int loc_eng_reinit(loc_eng_data_s_type &loc_eng_data); static void loc_eng_agps_reinit(loc_eng_data_s_type &loc_eng_data); static int loc_eng_set_server(loc_eng_data_s_type &loc_eng_data, LocServerType type, const char *hostname, int port); // Internal functions static void loc_inform_gps_status(loc_eng_data_s_type &loc_eng_data, GpsStatusValue status); static void loc_eng_report_status(loc_eng_data_s_type &loc_eng_data, GpsStatusValue status); static void loc_eng_process_conn_request(loc_eng_data_s_type &loc_eng_data, int connHandle, AGpsType agps_type); static void loc_eng_agps_close_status(loc_eng_data_s_type &loc_eng_data, int is_succ); static void loc_eng_handle_engine_down(loc_eng_data_s_type &loc_eng_data) ; static void loc_eng_handle_engine_up(loc_eng_data_s_type &loc_eng_data) ; static int loc_eng_start_handler(loc_eng_data_s_type &loc_eng_data); static int loc_eng_stop_handler(loc_eng_data_s_type &loc_eng_data); static int loc_eng_get_zpp_handler(loc_eng_data_s_type &loc_eng_data); static void deleteAidingData(loc_eng_data_s_type &logEng); static AgpsStateMachine* getAgpsStateMachine(loc_eng_data_s_type& logEng, AGpsExtType agpsType); static int dataCallCb(void *cb_data); static void update_aiding_data_for_deletion(loc_eng_data_s_type& loc_eng_data) { if (loc_eng_data.engine_status != GPS_STATUS_ENGINE_ON && loc_eng_data.aiding_data_for_deletion != 0) { loc_eng_data.adapter->deleteAidingData(loc_eng_data.aiding_data_for_deletion); loc_eng_data.aiding_data_for_deletion = 0; } } static void* noProc(void* data) { return NULL; } /********************************************************************* * definitions of the static messages used in the file *********************************************************************/ // case LOC_ENG_MSG_REQUEST_NI: LocEngRequestNi::LocEngRequestNi(void* locEng, GpsNiNotification ¬if, 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); } // 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)]) { char * cptr = mServers; memset(mServers, 0, 3*(mMaxLen+1)); // Override modem URLs with uncommented gps.conf urls if( gps_conf.XTRA_SERVER_1[0] != '\0' ) { url1 = &gps_conf.XTRA_SERVER_1[0]; } if( gps_conf.XTRA_SERVER_2[0] != '\0' ) { url2 = &gps_conf.XTRA_SERVER_2[0]; } if( gps_conf.XTRA_SERVER_3[0] != '\0' ) { url3 = &gps_conf.XTRA_SERVER_3[0]; } // copy non xtra1.gpsonextra.net URLs into the forwarding buffer. if( NULL == strcasestr(url1, XTRA1_GPSONEXTRA) ) { strlcpy(cptr, url1, mMaxLen + 1); cptr += mMaxLen + 1; } if( NULL == strcasestr(url2, XTRA1_GPSONEXTRA) ) { strlcpy(cptr, url2, mMaxLen + 1); cptr += mMaxLen + 1; } if( NULL == strcasestr(url3, XTRA1_GPSONEXTRA) ) { strlcpy(cptr, url3, mMaxLen + 1); } locallog(); } void LocEngReportXtraServer::proc() const { loc_eng_xtra_data_s_type* locEngXtra = &(((loc_eng_data_s_type*)mLocEng)->xtra_module_data); if (locEngXtra->report_xtra_server_cb != NULL) { CALLBACK_LOG_CALLFLOW("report_xtra_server_cb", %s, mServers); locEngXtra->report_xtra_server_cb(mServers, &(mServers[mMaxLen+1]), &(mServers[(mMaxLen+1)<<1])); } else { LOC_LOGE("Callback function for request xtra is NULL"); } } inline void LocEngReportXtraServer::locallog() const { LOC_LOGV("LocEngReportXtraServers: server1: %s\n server2: %s\n" " server3: %s\n", mServers, &mServers[mMaxLen+1], &mServers[(mMaxLen+1)<<1]); } inline void LocEngReportXtraServer::log() const { locallog(); } // case LOC_ENG_MSG_REQUEST_BIT: // case LOC_ENG_MSG_RELEASE_BIT: LocEngReqRelBIT::LocEngReqRelBIT(void* locEng, AGpsExtType type, int ipv4, char* ipv6, bool isReq) : LocMsg(), mLocEng(locEng), mType(type), mIPv4Addr(ipv4), mIPv6Addr(ipv6 ? new char[16] : NULL), mIsReq(isReq) { if (NULL != ipv6) memcpy(mIPv6Addr, ipv6, 16); locallog(); } inline LocEngReqRelBIT::~LocEngReqRelBIT() { if (mIPv6Addr) { delete[] mIPv6Addr; } } void LocEngReqRelBIT::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; BITSubscriber s(getAgpsStateMachine(*locEng, mType), mIPv4Addr, mIPv6Addr); AgpsStateMachine* sm = (AgpsStateMachine*)s.mStateMachine; if (mIsReq) { sm->subscribeRsrc((Subscriber*)&s); } else { sm->unsubscribeRsrc((Subscriber*)&s); } } inline void LocEngReqRelBIT::locallog() const { LOC_LOGV("LocEngRequestBIT - ipv4: %d.%d.%d.%d, ipv6: %s", (unsigned char)mIPv4Addr, (unsigned char)(mIPv4Addr>>8), (unsigned char)(mIPv4Addr>>16), (unsigned char)(mIPv4Addr>>24), NULL != mIPv6Addr ? mIPv6Addr : ""); } inline void LocEngReqRelBIT::log() const { locallog(); } void LocEngReqRelBIT::send() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; locEng->adapter->sendMsg(this); } // case LOC_ENG_MSG_RELEASE_BIT: struct LocEngReleaseBIT : public LocMsg { const BITSubscriber mSubscriber; inline LocEngReleaseBIT(const AgpsStateMachine* stateMachine, unsigned int ipv4, char* ipv6) : LocMsg(), mSubscriber(stateMachine, ipv4, ipv6) { locallog(); } inline virtual void proc() const { AgpsStateMachine* sm = (AgpsStateMachine*)mSubscriber.mStateMachine; sm->unsubscribeRsrc((Subscriber*)&mSubscriber); } inline void locallog() const { LOC_LOGV("LocEngReleaseBIT - ipv4: %d.%d.%d.%d, ipv6: %s", (unsigned char)(mSubscriber.ID>>24), (unsigned char)(mSubscriber.ID>>16), (unsigned char)(mSubscriber.ID>>8), (unsigned char)mSubscriber.ID, NULL != mSubscriber.mIPv6Addr ? mSubscriber.mIPv6Addr : ""); } virtual void log() const { locallog(); } }; // LocEngSuplEsOpened LocEngSuplEsOpened::LocEngSuplEsOpened(void* locEng) : LocMsg(), mLocEng(locEng) { locallog(); } void LocEngSuplEsOpened::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; if (locEng->ds_nif) { AgpsStateMachine* sm = locEng->ds_nif; sm->onRsrcEvent(RSRC_GRANTED); } } void LocEngSuplEsOpened::locallog() const { LOC_LOGV("LocEngSuplEsOpened"); } void LocEngSuplEsOpened::log() const { locallog(); } // LocEngSuplEsClosed LocEngSuplEsClosed::LocEngSuplEsClosed(void* locEng) : LocMsg(), mLocEng(locEng) { locallog(); } void LocEngSuplEsClosed::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; if (locEng->ds_nif) { AgpsStateMachine* sm = locEng->ds_nif; sm->onRsrcEvent(RSRC_RELEASED); } } void LocEngSuplEsClosed::locallog() const { LOC_LOGV("LocEngSuplEsClosed"); } void LocEngSuplEsClosed::log() const { locallog(); } // case LOC_ENG_MSG_REQUEST_SUPL_ES: LocEngRequestSuplEs::LocEngRequestSuplEs(void* locEng, int id) : LocMsg(), mLocEng(locEng), mID(id) { locallog(); } void LocEngRequestSuplEs::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; if (locEng->ds_nif) { AgpsStateMachine* sm = locEng->ds_nif; DSSubscriber s(sm, mID); sm->subscribeRsrc((Subscriber*)&s); } else { 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_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); } 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(); } }; /********************************************************************* * 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)); if (NULL != callbacks->set_capabilities_cb) { callbacks->set_capabilities_cb(gps_conf.CAPABILITIES); } // 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.acquire_wakelock_cb = callbacks->acquire_wakelock_cb; loc_eng_data.release_wakelock_cb = callbacks->release_wakelock_cb; loc_eng_data.request_utc_time_cb = callbacks->request_utc_time_cb; loc_eng_data.location_ext_parser = callbacks->location_ext_parser ? callbacks->location_ext_parser : noProc; loc_eng_data.sv_ext_parser = callbacks->sv_ext_parser ? callbacks->sv_ext_parser : noProc; loc_eng_data.intermediateFix = gps_conf.INTERMEDIATE_POS; // initial states taken care of by the memset above // loc_eng_data.engine_status -- GPS_STATUS_NONE; // loc_eng_data.fix_session_status -- GPS_STATUS_NONE; // loc_eng_data.mute_session_state -- LOC_MUTE_SESS_NONE; if ((event & LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT) && (gps_conf.NMEA_PROVIDER == NMEA_PROVIDER_AP)) { event = event ^ LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT; // unregister for modem NMEA report loc_eng_data.generateNmea = true; } else { loc_eng_data.generateNmea = false; } loc_eng_data.adapter = new LocEngAdapter(event, &loc_eng_data, context, (MsgTask::tCreate)callbacks->create_thread_cb); LOC_LOGD("loc_eng_init created client, id = %p\n", loc_eng_data.adapter); loc_eng_data.adapter->sendMsg(new LocEngInit(&loc_eng_data)); EXIT_LOG(%d, ret_val); return ret_val; } static int loc_eng_reinit(loc_eng_data_s_type &loc_eng_data) { ENTRY_LOG(); int ret_val = LOC_API_ADAPTER_ERR_SUCCESS; if (LOC_API_ADAPTER_ERR_SUCCESS == ret_val) { LOC_LOGD("loc_eng_reinit reinit() successful"); LocEngAdapter* adapter = loc_eng_data.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 ¶ms) { 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 = snprintf(url, sizeof(url), "%s:%u", hostname, (unsigned) port); if (sizeof(url) > len) { adapter->sendMsg(new LocEngSetServerUrl(adapter, url, len)); } } else if (LOC_AGPS_CDMA_PDE_SERVER == type || LOC_AGPS_CUSTOM_PDE_SERVER == type || LOC_AGPS_MPC_SERVER == type) { struct in_addr addr; if (!resolve_in_addr(hostname, &addr)) { LOC_LOGE("loc_eng_set_server, hostname %s cannot be resolved.\n", hostname); ret = -2; } else { unsigned int ip = htonl(addr.s_addr); adapter->sendMsg(new LocEngSetServerIpv4(adapter, ip, port, type)); } } else { LOC_LOGE("loc_eng_set_server, type %d cannot be resolved.\n", type); } EXIT_LOG(%d, ret); return ret; } /*=========================================================================== FUNCTION loc_eng_set_server_proxy DESCRIPTION If loc_eng_set_server is called before loc_eng_init, it doesn't work. This proxy buffers server settings and calls loc_eng_set_server when the client is open. DEPENDENCIES NONE RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_set_server_proxy(loc_eng_data_s_type &loc_eng_data, LocServerType type, const char* hostname, int port) { ENTRY_LOG_CALLFLOW(); int ret_val = 0; if (NULL != loc_eng_data.adapter) { ret_val = loc_eng_set_server(loc_eng_data, type, hostname, port); } else { LOC_LOGW("set_server called before init. save the address, type: %d, hostname: %s, port: %d", (int) type, hostname, port); switch (type) { case LOC_AGPS_SUPL_SERVER: strlcpy(loc_eng_data.supl_host_buf, hostname, sizeof(loc_eng_data.supl_host_buf)); loc_eng_data.supl_port_buf = port; loc_eng_data.supl_host_set = 1; break; case LOC_AGPS_CDMA_PDE_SERVER: strlcpy(loc_eng_data.c2k_host_buf, hostname, sizeof(loc_eng_data.c2k_host_buf)); loc_eng_data.c2k_port_buf = port; loc_eng_data.c2k_host_set = 1; break; default: LOC_LOGE("loc_eng_set_server_proxy, unknown server type = %d", (int) type); } } EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_eng_agps_ril_update_network_availability DESCRIPTION Sets data call allow vs disallow flag to modem This is the only member of sLocEngAGpsRilInterface implemented. DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ void loc_eng_agps_ril_update_network_availability(loc_eng_data_s_type &loc_eng_data, int available, const char* apn) { ENTRY_LOG_CALLFLOW(); //This is to store the status of data availability over the network. //If GPS is not enabled, the INIT_CHECK will fail and the modem will //not be updated with the network's availability. Since the data status //can change before GPS is enabled the, storing the status will enable //us to inform the modem after GPS is enabled agpsStatus = available; INIT_CHECK(loc_eng_data.adapter, return); if (apn != NULL) { LOC_LOGD("loc_eng_agps_ril_update_network_availability: APN Name = [%s]\n", apn); int apn_len = smaller_of(strlen (apn), MAX_APN_LEN); LocEngAdapter* adapter = loc_eng_data.adapter; adapter->sendMsg(new LocEngEnableData(adapter, apn, apn_len, available)); } EXIT_LOG(%s, VOID_RET); } /*=========================================================================== 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); 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, loc_parameter_table); UTIL_READ_CONF(SAP_CONF_FILE, loc_parameter_table); configAlreadyRead = true; } else { LOC_LOGV("GPS Config file has already been read\n"); } EXIT_LOG(%d, 0); return 0; }