Home | History | Annotate | Download | only in location_api
      1 /* Copyright (c) 2017, The Linux Foundation. All rights reserved.
      2  *
      3  * Redistribution and use in source and binary forms, with or without
      4  * modification, are permitted provided that the following conditions are
      5  * met:
      6  *     * Redistributions of source code must retain the above copyright
      7  *       notice, this list of conditions and the following disclaimer.
      8  *     * Redistributions in binary form must reproduce the above
      9  *       copyright notice, this list of conditions and the following
     10  *       disclaimer in the documentation and/or other materials provided
     11  *       with the distribution.
     12  *     * Neither the name of The Linux Foundation, nor the names of its
     13  *       contributors may be used to endorse or promote products derived
     14  *       from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  *
     28  */
     29 
     30 #define LOG_NDDEBUG 0
     31 #define LOG_TAG "LocSvc_GnssAPIClient"
     32 
     33 #include <log_util.h>
     34 #include <loc_cfg.h>
     35 
     36 #include "LocationUtil.h"
     37 #include "GnssAPIClient.h"
     38 
     39 namespace android {
     40 namespace hardware {
     41 namespace gnss {
     42 namespace V1_0 {
     43 namespace implementation {
     44 
     45 static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out);
     46 
     47 GnssAPIClient::GnssAPIClient(const sp<IGnssCallback>& gpsCb,
     48     const sp<IGnssNiCallback>& niCb) :
     49     LocationAPIClientBase(),
     50     mGnssCbIface(nullptr),
     51     mGnssNiCbIface(nullptr),
     52     mLocationCapabilitiesMask(0)
     53 {
     54     LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
     55 
     56     // set default LocationOptions.
     57     memset(&mLocationOptions, 0, sizeof(LocationOptions));
     58     mLocationOptions.size = sizeof(LocationOptions);
     59     mLocationOptions.minInterval = 1000;
     60     mLocationOptions.minDistance = 0;
     61     mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE;
     62 
     63     gnssUpdateCallbacks(gpsCb, niCb);
     64 }
     65 
     66 GnssAPIClient::~GnssAPIClient()
     67 {
     68     LOC_LOGD("%s]: ()", __FUNCTION__);
     69 }
     70 
     71 // for GpsInterface
     72 void GnssAPIClient::gnssUpdateCallbacks(const sp<IGnssCallback>& gpsCb,
     73     const sp<IGnssNiCallback>& niCb)
     74 {
     75     LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
     76 
     77     mGnssCbIface = gpsCb;
     78     mGnssNiCbIface = niCb;
     79 
     80     LocationCallbacks locationCallbacks;
     81     locationCallbacks.size = sizeof(LocationCallbacks);
     82 
     83     locationCallbacks.trackingCb = nullptr;
     84     if (mGnssCbIface != nullptr) {
     85         locationCallbacks.trackingCb = [this](Location location) {
     86             onTrackingCb(location);
     87         };
     88     }
     89 
     90     locationCallbacks.batchingCb = nullptr;
     91     locationCallbacks.geofenceBreachCb = nullptr;
     92     locationCallbacks.geofenceStatusCb = nullptr;
     93     locationCallbacks.gnssLocationInfoCb = nullptr;
     94 
     95     locationCallbacks.gnssNiCb = nullptr;
     96     if (mGnssNiCbIface != nullptr) {
     97         locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) {
     98             onGnssNiCb(id, gnssNiNotification);
     99         };
    100     }
    101 
    102     locationCallbacks.gnssSvCb = nullptr;
    103     if (mGnssCbIface != nullptr) {
    104         locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) {
    105             onGnssSvCb(gnssSvNotification);
    106         };
    107     }
    108 
    109     locationCallbacks.gnssNmeaCb = nullptr;
    110     if (mGnssCbIface != nullptr) {
    111         locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) {
    112             onGnssNmeaCb(gnssNmeaNotification);
    113         };
    114     }
    115 
    116     locationCallbacks.gnssMeasurementsCb = nullptr;
    117 
    118     locAPISetCallbacks(locationCallbacks);
    119 }
    120 
    121 bool GnssAPIClient::gnssStart()
    122 {
    123     LOC_LOGD("%s]: ()", __FUNCTION__);
    124     bool retVal = true;
    125     locAPIStartTracking(mLocationOptions);
    126     return retVal;
    127 }
    128 
    129 bool GnssAPIClient::gnssStop()
    130 {
    131     LOC_LOGD("%s]: ()", __FUNCTION__);
    132     bool retVal = true;
    133     locAPIStopTracking();
    134     return retVal;
    135 }
    136 
    137 void GnssAPIClient::gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)
    138 {
    139     LOC_LOGD("%s]: (%02hx)", __FUNCTION__, aidingDataFlags);
    140     GnssAidingData data;
    141     memset(&data, 0, sizeof (GnssAidingData));
    142     data.sv.svTypeMask = GNSS_AIDING_DATA_SV_TYPE_GPS |
    143         GNSS_AIDING_DATA_SV_TYPE_GLONASS |
    144         GNSS_AIDING_DATA_SV_TYPE_QZSS |
    145         GNSS_AIDING_DATA_SV_TYPE_BEIDOU |
    146         GNSS_AIDING_DATA_SV_TYPE_GALILEO;
    147 
    148     if (aidingDataFlags == IGnss::GnssAidingData::DELETE_ALL)
    149         data.deleteAll = true;
    150     else {
    151         if (aidingDataFlags & IGnss::GnssAidingData::DELETE_EPHEMERIS)
    152             data.sv.svMask |= GNSS_AIDING_DATA_SV_EPHEMERIS;
    153         if (aidingDataFlags & IGnss::GnssAidingData::DELETE_ALMANAC)
    154             data.sv.svMask |= GNSS_AIDING_DATA_SV_ALMANAC;
    155         if (aidingDataFlags & IGnss::GnssAidingData::DELETE_POSITION)
    156             data.common.mask |= GNSS_AIDING_DATA_COMMON_POSITION;
    157         if (aidingDataFlags & IGnss::GnssAidingData::DELETE_TIME)
    158             data.common.mask |= GNSS_AIDING_DATA_COMMON_TIME;
    159         if (aidingDataFlags & IGnss::GnssAidingData::DELETE_IONO)
    160             data.sv.svMask |= GNSS_AIDING_DATA_SV_IONOSPHERE;
    161         if (aidingDataFlags & IGnss::GnssAidingData::DELETE_UTC)
    162             data.common.mask |= GNSS_AIDING_DATA_COMMON_UTC;
    163         if (aidingDataFlags & IGnss::GnssAidingData::DELETE_HEALTH)
    164             data.sv.svMask |= GNSS_AIDING_DATA_SV_HEALTH;
    165         if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVDIR)
    166             data.sv.svMask |= GNSS_AIDING_DATA_SV_DIRECTION;
    167         if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVSTEER)
    168             data.sv.svMask |= GNSS_AIDING_DATA_SV_STEER;
    169         if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SADATA)
    170             data.sv.svMask |= GNSS_AIDING_DATA_SV_SA_DATA;
    171         if (aidingDataFlags & IGnss::GnssAidingData::DELETE_RTI)
    172             data.common.mask |= GNSS_AIDING_DATA_COMMON_RTI;
    173         if (aidingDataFlags & IGnss::GnssAidingData::DELETE_CELLDB_INFO)
    174             data.common.mask |= GNSS_AIDING_DATA_COMMON_CELLDB;
    175     }
    176     locAPIGnssDeleteAidingData(data);
    177 }
    178 
    179 bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode,
    180         IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs,
    181         uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs)
    182 {
    183     LOC_LOGD("%s]: (%d %d %d %d %d)", __FUNCTION__,
    184             (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters, preferredTimeMs);
    185     bool retVal = true;
    186     memset(&mLocationOptions, 0, sizeof(LocationOptions));
    187     mLocationOptions.size = sizeof(LocationOptions);
    188     mLocationOptions.minInterval = minIntervalMs;
    189     mLocationOptions.minDistance = preferredAccuracyMeters;
    190     if (mode == IGnss::GnssPositionMode::STANDALONE)
    191         mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE;
    192     else if (mode == IGnss::GnssPositionMode::MS_BASED)
    193         mLocationOptions.mode = GNSS_SUPL_MODE_MSB;
    194     else if (mode ==  IGnss::GnssPositionMode::MS_ASSISTED)
    195         mLocationOptions.mode = GNSS_SUPL_MODE_MSA;
    196     return retVal;
    197 }
    198 
    199 // for GpsNiInterface
    200 void GnssAPIClient::gnssNiRespond(int32_t notifId,
    201         IGnssNiCallback::GnssUserResponseType userResponse)
    202 {
    203     LOC_LOGD("%s]: (%d %d)", __FUNCTION__, notifId, static_cast<int>(userResponse));
    204     GnssNiResponse data = GNSS_NI_RESPONSE_IGNORE;
    205     if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT)
    206         data = GNSS_NI_RESPONSE_ACCEPT;
    207     else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY)
    208         data = GNSS_NI_RESPONSE_DENY;
    209     else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP)
    210         data = GNSS_NI_RESPONSE_NO_RESPONSE;
    211     locAPIGnssNiResponse(notifId, data);
    212 }
    213 
    214 // for GnssConfigurationInterface
    215 void GnssAPIClient::gnssConfigurationUpdate(const GnssConfig& gnssConfig)
    216 {
    217     LOC_LOGD("%s]: (%02x)", __FUNCTION__, gnssConfig.flags);
    218     locAPIGnssUpdateConfig(gnssConfig);
    219 }
    220 
    221 // callbacks
    222 void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
    223 {
    224     LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
    225     mLocationCapabilitiesMask = capabilitiesMask;
    226     if (mGnssCbIface != nullptr) {
    227         uint32_t data = 0;
    228         if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) ||
    229                 (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) ||
    230                 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) ||
    231                 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT))
    232             data |= IGnssCallback::Capabilities::SCHEDULING;
    233         if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT)
    234             data |= IGnssCallback::Capabilities::GEOFENCING;
    235         if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT)
    236             data |= IGnssCallback::Capabilities::MEASUREMENTS;
    237         if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
    238             data |= IGnssCallback::Capabilities::MSB;
    239         if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
    240             data |= IGnssCallback::Capabilities::MSA;
    241         mGnssCbIface->gnssSetCapabilitesCb(data);
    242     }
    243     if (mGnssCbIface != nullptr) {
    244         IGnssCallback::GnssSystemInfo gnssInfo;
    245         gnssInfo.yearOfHw = 2015;
    246         if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
    247             gnssInfo.yearOfHw = 2017;
    248         }
    249         LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
    250         mGnssCbIface->gnssSetSystemInfoCb(gnssInfo);
    251     }
    252 }
    253 
    254 void GnssAPIClient::onTrackingCb(Location location)
    255 {
    256     LOC_LOGD("%s]: (flags: %02x)", __FUNCTION__, location.flags);
    257     if (mGnssCbIface != nullptr) {
    258         GnssLocation gnssLocation;
    259         convertGnssLocation(location, gnssLocation);
    260         mGnssCbIface->gnssLocationCb(gnssLocation);
    261     }
    262 }
    263 
    264 void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification)
    265 {
    266     LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id);
    267 
    268     if (mGnssNiCbIface == nullptr) {
    269         LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__);
    270         return;
    271     }
    272 
    273     IGnssNiCallback::GnssNiNotification notificationGnss;
    274 
    275     notificationGnss.notificationId = id;
    276 
    277     if (gnssNiNotification.type == GNSS_NI_TYPE_VOICE)
    278         notificationGnss.niType = IGnssNiCallback::GnssNiType::VOICE;
    279     else if (gnssNiNotification.type == GNSS_NI_TYPE_SUPL)
    280         notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_SUPL;
    281     else if (gnssNiNotification.type == GNSS_NI_TYPE_CONTROL_PLANE)
    282         notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_CTRL_PLANE;
    283     // GNSS_NI_TYPE_EMERGENCY_SUPL not supported
    284 
    285     if (gnssNiNotification.options == GNSS_NI_OPTIONS_NOTIFICATION)
    286         notificationGnss.notifyFlags =
    287             static_cast<uint32_t>(IGnssNiCallback::GnssNiNotifyFlags::NEED_NOTIFY);
    288     else if (gnssNiNotification.options == GNSS_NI_OPTIONS_VERIFICATION)
    289         notificationGnss.notifyFlags =
    290             static_cast<uint32_t>(IGnssNiCallback::GnssNiNotifyFlags::NEED_VERIFY);
    291     else if (gnssNiNotification.options == GNSS_NI_OPTIONS_PRIVACY_OVERRIDE)
    292         notificationGnss.notifyFlags =
    293             static_cast<uint32_t>(IGnssNiCallback::GnssNiNotifyFlags::PRIVACY_OVERRIDE);
    294 
    295     notificationGnss.timeoutSec = gnssNiNotification.timeout;
    296 
    297     if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_ACCEPT)
    298         notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT;
    299     else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_DENY)
    300         notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY;
    301     else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_NO_RESPONSE ||
    302             gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_IGNORE)
    303         notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP;
    304 
    305     notificationGnss.requestorId = gnssNiNotification.requestor;
    306 
    307     notificationGnss.notificationMessage = gnssNiNotification.message;
    308 
    309     if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_NONE)
    310         notificationGnss.requestorIdEncoding =
    311             IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
    312     else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
    313         notificationGnss.requestorIdEncoding =
    314             IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
    315     else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
    316         notificationGnss.requestorIdEncoding =
    317             IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
    318     else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
    319         notificationGnss.requestorIdEncoding =
    320             IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
    321 
    322     if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_NONE)
    323         notificationGnss.notificationIdEncoding =
    324             IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
    325     else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
    326         notificationGnss.notificationIdEncoding =
    327             IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
    328     else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
    329         notificationGnss.notificationIdEncoding =
    330             IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
    331     else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
    332         notificationGnss.notificationIdEncoding =
    333             IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
    334 
    335     mGnssNiCbIface->niNotifyCb(notificationGnss);
    336 }
    337 
    338 void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification)
    339 {
    340     LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, gnssSvNotification.count);
    341     if (mGnssCbIface != nullptr) {
    342         IGnssCallback::GnssSvStatus svStatus;
    343         convertGnssSvStatus(gnssSvNotification, svStatus);
    344         mGnssCbIface->gnssSvStatusCb(svStatus);
    345     }
    346 }
    347 
    348 void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)
    349 {
    350     if (mGnssCbIface != nullptr) {
    351         android::hardware::hidl_string nmeaString;
    352         nmeaString.setToExternal(gnssNmeaNotification.nmea, gnssNmeaNotification.length);
    353         mGnssCbIface->gnssNmeaCb(static_cast<GnssUtcTime>(gnssNmeaNotification.timestamp),
    354                 nmeaString);
    355     }
    356 }
    357 
    358 void GnssAPIClient::onStartTrackingCb(LocationError error)
    359 {
    360     LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
    361     if (error == LOCATION_ERROR_SUCCESS && mGnssCbIface != nullptr) {
    362         mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
    363         mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
    364     }
    365 }
    366 
    367 void GnssAPIClient::onStopTrackingCb(LocationError error)
    368 {
    369     LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
    370     if (error == LOCATION_ERROR_SUCCESS && mGnssCbIface != nullptr) {
    371         mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
    372         mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
    373     }
    374 }
    375 
    376 static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out)
    377 {
    378     memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus));
    379     out.numSvs = in.count;
    380     if (out.numSvs > static_cast<uint32_t>(GnssMax::SVS_COUNT)) {
    381         LOC_LOGW("%s]: Too many satellites %zd. Clamps to %d.",
    382                 __FUNCTION__,  out.numSvs, GnssMax::SVS_COUNT);
    383         out.numSvs = static_cast<uint32_t>(GnssMax::SVS_COUNT);
    384     }
    385     for (size_t i = 0; i < out.numSvs; i++) {
    386         IGnssCallback::GnssSvInfo& info = out.gnssSvList[i];
    387         info.svid = in.gnssSvs[i].svId;
    388         convertGnssConstellationType(in.gnssSvs[i].type, info.constellation);
    389         info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
    390         info.elevationDegrees = in.gnssSvs[i].elevation;
    391         info.azimuthDegrees = in.gnssSvs[i].azimuth;
    392         info.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
    393         if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
    394             info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
    395         if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
    396             info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
    397         if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
    398             info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
    399     }
    400 }
    401 
    402 }  // namespace implementation
    403 }  // namespace V1_0
    404 }  // namespace gnss
    405 }  // namespace hardware
    406 }  // namespace android
    407