Home | History | Annotate | Download | only in location
      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 #define LOG_TAG "LocSvc_LocationAPI"
     29 
     30 #include <location_interface.h>
     31 #include <dlfcn.h>
     32 #include <platform_lib_log_util.h>
     33 #include <pthread.h>
     34 #include <map>
     35 
     36 typedef void* (getLocationInterface)();
     37 typedef std::map<LocationAPI*, LocationCallbacks> LocationClientMap;
     38 typedef struct {
     39     LocationClientMap clientData;
     40     LocationControlAPI* controlAPI;
     41     LocationControlCallbacks controlCallbacks;
     42     GnssInterface* gnssInterface;
     43     GeofenceInterface* geofenceInterface;
     44     FlpInterface* flpInterface;
     45 } LocationAPIData;
     46 static LocationAPIData gData = {};
     47 static pthread_mutex_t gDataMutex = PTHREAD_MUTEX_INITIALIZER;
     48 static bool gGnssLoadFailed = false;
     49 static bool gFlpLoadFailed = false;
     50 static bool gGeofenceLoadFailed = false;
     51 
     52 static bool needsGnssTrackingInfo(LocationCallbacks& locationCallbacks)
     53 {
     54     return (locationCallbacks.gnssLocationInfoCb != nullptr ||
     55             locationCallbacks.gnssSvCb != nullptr ||
     56             locationCallbacks.gnssNmeaCb != nullptr ||
     57             locationCallbacks.gnssMeasurementsCb != nullptr);
     58 }
     59 
     60 static bool isGnssClient(LocationCallbacks& locationCallbacks)
     61 {
     62     return (locationCallbacks.gnssNiCb != nullptr ||
     63             locationCallbacks.trackingCb != nullptr ||
     64             locationCallbacks.gnssMeasurementsCb != nullptr);
     65 }
     66 
     67 static bool isFlpClient(LocationCallbacks& locationCallbacks)
     68 {
     69     return (locationCallbacks.trackingCb != nullptr ||
     70             locationCallbacks.batchingCb != nullptr);
     71 }
     72 
     73 static bool isGeofenceClient(LocationCallbacks& locationCallbacks)
     74 {
     75     return (locationCallbacks.geofenceBreachCb != nullptr ||
     76             locationCallbacks.geofenceStatusCb != nullptr);
     77 }
     78 
     79 static void* loadLocationInterface(const char* library, const char* name) {
     80     LOC_LOGD("%s]: loading %s::%s ...", __func__, library, name);
     81     if (NULL == library || NULL == name) {
     82         return NULL;
     83     }
     84     getLocationInterface* getter = NULL;
     85     const char *error = NULL;
     86     dlerror();
     87     void *handle = dlopen(library, RTLD_NOW);
     88     if (NULL == handle || (error = dlerror()) != NULL)  {
     89         LOC_LOGW("dlopen for %s failed, error = %s", library, error);
     90     } else {
     91         getter = (getLocationInterface*)dlsym(handle, name);
     92         if ((error = dlerror()) != NULL)  {
     93             LOC_LOGW("dlsym for %s::%s failed, error = %s", library, name, error);
     94             getter = NULL;
     95         }
     96     }
     97 
     98     if (NULL == getter) {
     99         return (void*)getter;
    100     } else {
    101         return (*getter)();
    102     }
    103 }
    104 
    105 LocationAPI*
    106 LocationAPI::createInstance(LocationCallbacks& locationCallbacks)
    107 {
    108     if (nullptr == locationCallbacks.capabilitiesCb ||
    109         nullptr == locationCallbacks.responseCb ||
    110         nullptr == locationCallbacks.collectiveResponseCb) {
    111         return NULL;
    112     }
    113 
    114     LocationAPI* newLocationAPI = new LocationAPI();
    115     bool requestedCapabilities = false;
    116 
    117     pthread_mutex_lock(&gDataMutex);
    118 
    119     if (isGnssClient(locationCallbacks)) {
    120         if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
    121             gData.gnssInterface =
    122                 (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface");
    123             if (NULL == gData.gnssInterface) {
    124                 gGnssLoadFailed = true;
    125                 LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__);
    126             } else {
    127                 gData.gnssInterface->initialize();
    128             }
    129         }
    130         if (NULL != gData.gnssInterface) {
    131             gData.gnssInterface->addClient(newLocationAPI, locationCallbacks);
    132             if (!requestedCapabilities) {
    133                 gData.gnssInterface->requestCapabilities(newLocationAPI);
    134                 requestedCapabilities = true;
    135             }
    136         }
    137     }
    138 
    139     if (isFlpClient(locationCallbacks)) {
    140         if (NULL == gData.flpInterface && !gFlpLoadFailed) {
    141             gData.flpInterface =
    142                 (FlpInterface*)loadLocationInterface("libflp.so", "getFlpInterface");
    143             if (NULL == gData.flpInterface) {
    144                 gFlpLoadFailed = true;
    145                 LOC_LOGW("%s:%d]: No flp interface available", __func__, __LINE__);
    146             } else {
    147                 gData.flpInterface->initialize();
    148             }
    149         }
    150         if (NULL != gData.flpInterface) {
    151             gData.flpInterface->addClient(newLocationAPI, locationCallbacks);
    152             if (!requestedCapabilities) {
    153                 gData.flpInterface->requestCapabilities(newLocationAPI);
    154                 requestedCapabilities = true;
    155             }
    156         }
    157     }
    158 
    159     if (isGeofenceClient(locationCallbacks)) {
    160         if (NULL == gData.geofenceInterface && !gGeofenceLoadFailed) {
    161             gData.geofenceInterface =
    162                 (GeofenceInterface*)loadLocationInterface("libgeofence.so", "getGeofenceInterface");
    163             if (NULL == gData.geofenceInterface) {
    164                 gGeofenceLoadFailed = true;
    165                 LOC_LOGW("%s:%d]: No geofence interface available", __func__, __LINE__);
    166             } else {
    167                 gData.geofenceInterface->initialize();
    168             }
    169         }
    170         if (NULL != gData.geofenceInterface) {
    171             gData.geofenceInterface->addClient(newLocationAPI, locationCallbacks);
    172             if (!requestedCapabilities) {
    173                 gData.geofenceInterface->requestCapabilities(newLocationAPI);
    174                 requestedCapabilities = true;
    175             }
    176         }
    177     }
    178 
    179     gData.clientData[newLocationAPI] = locationCallbacks;
    180 
    181     pthread_mutex_unlock(&gDataMutex);
    182 
    183     return newLocationAPI;
    184 }
    185 
    186 void
    187 LocationAPI::destroy()
    188 {
    189     delete this;
    190 }
    191 
    192 LocationAPI::LocationAPI()
    193 {
    194     LOC_LOGD("LOCATION API CONSTRUCTOR");
    195 }
    196 
    197 LocationAPI::~LocationAPI()
    198 {
    199     LOC_LOGD("LOCATION API DESTRUCTOR");
    200     pthread_mutex_lock(&gDataMutex);
    201 
    202     auto it = gData.clientData.find(this);
    203     if (it != gData.clientData.end()) {
    204         if (isGnssClient(it->second) && NULL != gData.gnssInterface) {
    205             gData.gnssInterface->removeClient(it->first);
    206         }
    207         if (isFlpClient(it->second) && NULL != gData.flpInterface) {
    208             gData.flpInterface->removeClient(it->first);
    209         }
    210         if (isGeofenceClient(it->second) && NULL != gData.geofenceInterface) {
    211             gData.geofenceInterface->removeClient(it->first);
    212         }
    213         gData.clientData.erase(it);
    214     } else {
    215         LOC_LOGE("%s:%d]: Location API client %p not found in client data",
    216                  __func__, __LINE__, this);
    217     }
    218 
    219     pthread_mutex_unlock(&gDataMutex);
    220 }
    221 
    222 void
    223 LocationAPI::updateCallbacks(LocationCallbacks& locationCallbacks)
    224 {
    225     if (nullptr == locationCallbacks.capabilitiesCb ||
    226         nullptr == locationCallbacks.responseCb ||
    227         nullptr == locationCallbacks.collectiveResponseCb) {
    228         return;
    229     }
    230 
    231     pthread_mutex_lock(&gDataMutex);
    232 
    233     if (isGnssClient(locationCallbacks)) {
    234         if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
    235             gData.gnssInterface =
    236                 (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface");
    237             if (NULL == gData.gnssInterface) {
    238                 gGnssLoadFailed = true;
    239                 LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__);
    240             } else {
    241                 gData.gnssInterface->initialize();
    242             }
    243         }
    244         if (NULL != gData.gnssInterface) {
    245             // either adds new Client or updates existing Client
    246             gData.gnssInterface->addClient(this, locationCallbacks);
    247         }
    248     }
    249 
    250     if (isFlpClient(locationCallbacks)) {
    251         if (NULL == gData.flpInterface && !gFlpLoadFailed) {
    252             gData.flpInterface =
    253                 (FlpInterface*)loadLocationInterface("libflp.so", "getFlpInterface");
    254             if (NULL == gData.flpInterface) {
    255                 gFlpLoadFailed = true;
    256                 LOC_LOGW("%s:%d]: No flp interface available", __func__, __LINE__);
    257             } else {
    258                 gData.flpInterface->initialize();
    259             }
    260         }
    261         if (NULL != gData.flpInterface) {
    262             // either adds new Client or updates existing Client
    263             gData.flpInterface->addClient(this, locationCallbacks);
    264         }
    265     }
    266 
    267     if (isGeofenceClient(locationCallbacks)) {
    268         if (NULL == gData.geofenceInterface && !gGeofenceLoadFailed) {
    269             gData.geofenceInterface =
    270                 (GeofenceInterface*)loadLocationInterface("libgeofence.so", "getGeofenceInterface");
    271             if (NULL == gData.geofenceInterface) {
    272                 gGeofenceLoadFailed = true;
    273                 LOC_LOGW("%s:%d]: No geofence interface available", __func__, __LINE__);
    274             } else {
    275                 gData.geofenceInterface->initialize();
    276             }
    277         }
    278         if (NULL != gData.geofenceInterface) {
    279             // either adds new Client or updates existing Client
    280             gData.geofenceInterface->addClient(this, locationCallbacks);
    281         }
    282     }
    283 
    284     gData.clientData[this] = locationCallbacks;
    285 
    286     pthread_mutex_unlock(&gDataMutex);
    287 }
    288 
    289 uint32_t
    290 LocationAPI::startTracking(LocationOptions& locationOptions)
    291 {
    292     uint32_t id = 0;
    293     pthread_mutex_lock(&gDataMutex);
    294 
    295     auto it = gData.clientData.find(this);
    296     if (it != gData.clientData.end()) {
    297         if (gData.flpInterface != NULL && locationOptions.minDistance > 0) {
    298             id = gData.flpInterface->startTracking(this, locationOptions);
    299         } else if (gData.gnssInterface != NULL && needsGnssTrackingInfo(it->second)) {
    300             id = gData.gnssInterface->startTracking(this, locationOptions);
    301         } else if (gData.flpInterface != NULL) {
    302             id = gData.flpInterface->startTracking(this, locationOptions);
    303         } else if (gData.gnssInterface != NULL) {
    304             id = gData.gnssInterface->startTracking(this, locationOptions);
    305         } else {
    306             LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ",
    307                      __func__, __LINE__, this);
    308         }
    309     } else {
    310         LOC_LOGE("%s:%d]: Location API client %p not found in client data",
    311                  __func__, __LINE__, this);
    312     }
    313 
    314     pthread_mutex_unlock(&gDataMutex);
    315     return id;
    316 }
    317 
    318 void
    319 LocationAPI::stopTracking(uint32_t id)
    320 {
    321     pthread_mutex_lock(&gDataMutex);
    322 
    323     auto it = gData.clientData.find(this);
    324     if (it != gData.clientData.end()) {
    325         // we don't know if tracking was started on flp or gnss, so we call stop on both, where
    326         // stopTracking call to the incorrect interface will fail without response back to client
    327         if (gData.gnssInterface != NULL) {
    328             gData.gnssInterface->stopTracking(this, id);
    329         }
    330         if (gData.flpInterface != NULL) {
    331             gData.flpInterface->stopTracking(this, id);
    332         }
    333         if (gData.flpInterface == NULL && gData.gnssInterface == NULL) {
    334             LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ",
    335                      __func__, __LINE__, this);
    336         }
    337     } else {
    338         LOC_LOGE("%s:%d]: Location API client %p not found in client data",
    339                  __func__, __LINE__, this);
    340     }
    341 
    342     pthread_mutex_unlock(&gDataMutex);
    343 }
    344 
    345 void
    346 LocationAPI::updateTrackingOptions(uint32_t id, LocationOptions& locationOptions)
    347 {
    348     pthread_mutex_lock(&gDataMutex);
    349 
    350     auto it = gData.clientData.find(this);
    351     if (it != gData.clientData.end()) {
    352         // we don't know if tracking was started on flp or gnss, so we call update on both, where
    353         // updateTracking call to the incorrect interface will fail without response back to client
    354         if (gData.gnssInterface != NULL) {
    355             gData.gnssInterface->updateTrackingOptions(this, id, locationOptions);
    356         }
    357         if (gData.flpInterface != NULL) {
    358             gData.flpInterface->updateTrackingOptions(this, id, locationOptions);
    359         }
    360         if (gData.flpInterface == NULL && gData.gnssInterface == NULL) {
    361             LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ",
    362                      __func__, __LINE__, this);
    363         }
    364     } else {
    365         LOC_LOGE("%s:%d]: Location API client %p not found in client data",
    366                  __func__, __LINE__, this);
    367     }
    368 
    369     pthread_mutex_unlock(&gDataMutex);
    370 }
    371 
    372 uint32_t
    373 LocationAPI::startBatching(LocationOptions& locationOptions, BatchingOptions &batchingOptions)
    374 {
    375     uint32_t id = 0;
    376     pthread_mutex_lock(&gDataMutex);
    377 
    378     if (gData.flpInterface != NULL) {
    379         id = gData.flpInterface->startBatching(this, locationOptions, batchingOptions);
    380     } else {
    381         LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
    382                  __func__, __LINE__, this);
    383     }
    384 
    385     pthread_mutex_unlock(&gDataMutex);
    386     return id;
    387 }
    388 
    389 void
    390 LocationAPI::stopBatching(uint32_t id)
    391 {
    392     pthread_mutex_lock(&gDataMutex);
    393 
    394     if (gData.flpInterface != NULL) {
    395         gData.flpInterface->stopBatching(this, id);
    396     } else {
    397         LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
    398                  __func__, __LINE__, this);
    399     }
    400 
    401     pthread_mutex_unlock(&gDataMutex);
    402 }
    403 
    404 void
    405 LocationAPI::updateBatchingOptions(uint32_t id,
    406         LocationOptions& locationOptions, BatchingOptions& batchOptions)
    407 {
    408     pthread_mutex_lock(&gDataMutex);
    409 
    410     if (gData.flpInterface != NULL) {
    411         gData.flpInterface->updateBatchingOptions(this,
    412                                                   id,
    413                                                   locationOptions,
    414                                                   batchOptions);
    415     } else {
    416         LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
    417                  __func__, __LINE__, this);
    418     }
    419 
    420     pthread_mutex_unlock(&gDataMutex);
    421 }
    422 
    423 void
    424 LocationAPI::getBatchedLocations(uint32_t id, size_t count)
    425 {
    426     pthread_mutex_lock(&gDataMutex);
    427 
    428     if (gData.flpInterface != NULL) {
    429         gData.flpInterface->getBatchedLocations(this, id, count);
    430     } else {
    431         LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
    432                  __func__, __LINE__, this);
    433     }
    434 
    435     pthread_mutex_unlock(&gDataMutex);
    436 }
    437 
    438 uint32_t*
    439 LocationAPI::addGeofences(size_t count, GeofenceOption* options, GeofenceInfo* info)
    440 {
    441     uint32_t* ids = NULL;
    442     pthread_mutex_lock(&gDataMutex);
    443 
    444     if (gData.geofenceInterface != NULL) {
    445         ids = gData.geofenceInterface->addGeofences(this, count, options, info);
    446     } else {
    447         LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ",
    448                  __func__, __LINE__, this);
    449     }
    450 
    451     pthread_mutex_unlock(&gDataMutex);
    452     return ids;
    453 }
    454 
    455 void
    456 LocationAPI::removeGeofences(size_t count, uint32_t* ids)
    457 {
    458     pthread_mutex_lock(&gDataMutex);
    459 
    460     if (gData.geofenceInterface != NULL) {
    461         gData.geofenceInterface->removeGeofences(this, count, ids);
    462     } else {
    463         LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ",
    464                  __func__, __LINE__, this);
    465     }
    466 
    467     pthread_mutex_unlock(&gDataMutex);
    468 }
    469 
    470 void
    471 LocationAPI::modifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options)
    472 {
    473     pthread_mutex_lock(&gDataMutex);
    474 
    475     if (gData.geofenceInterface != NULL) {
    476         gData.geofenceInterface->modifyGeofences(this, count, ids, options);
    477     } else {
    478         LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ",
    479                  __func__, __LINE__, this);
    480     }
    481 
    482     pthread_mutex_unlock(&gDataMutex);
    483 }
    484 
    485 void
    486 LocationAPI::pauseGeofences(size_t count, uint32_t* ids)
    487 {
    488     pthread_mutex_lock(&gDataMutex);
    489 
    490     if (gData.geofenceInterface != NULL) {
    491         gData.geofenceInterface->pauseGeofences(this, count, ids);
    492     } else {
    493         LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ",
    494                  __func__, __LINE__, this);
    495     }
    496 
    497     pthread_mutex_unlock(&gDataMutex);
    498 }
    499 
    500 void
    501 LocationAPI::resumeGeofences(size_t count, uint32_t* ids)
    502 {
    503     pthread_mutex_lock(&gDataMutex);
    504 
    505     if (gData.geofenceInterface != NULL) {
    506         gData.geofenceInterface->resumeGeofences(this, count, ids);
    507     } else {
    508         LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ",
    509                  __func__, __LINE__, this);
    510     }
    511 
    512     pthread_mutex_unlock(&gDataMutex);
    513 }
    514 
    515 void
    516 LocationAPI::gnssNiResponse(uint32_t id, GnssNiResponse response)
    517 {
    518     pthread_mutex_lock(&gDataMutex);
    519 
    520     if (gData.gnssInterface != NULL) {
    521         gData.gnssInterface->gnssNiResponse(this, id, response);
    522     } else {
    523         LOC_LOGE("%s:%d]: No gnss interface available for Location API client %p ",
    524                  __func__, __LINE__, this);
    525     }
    526 
    527     pthread_mutex_unlock(&gDataMutex);
    528 }
    529 
    530 LocationControlAPI*
    531 LocationControlAPI::createInstance(LocationControlCallbacks& locationControlCallbacks)
    532 {
    533     LocationControlAPI* controlAPI = NULL;
    534     pthread_mutex_lock(&gDataMutex);
    535 
    536     if (nullptr != locationControlCallbacks.responseCb && NULL == gData.controlAPI) {
    537         if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
    538             gData.gnssInterface =
    539                 (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface");
    540             if (NULL == gData.gnssInterface) {
    541                 gGnssLoadFailed = true;
    542                 LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__);
    543             } else {
    544                 gData.gnssInterface->initialize();
    545             }
    546         }
    547         if (NULL != gData.gnssInterface) {
    548             gData.controlAPI = new LocationControlAPI();
    549             gData.controlCallbacks = locationControlCallbacks;
    550             gData.gnssInterface->setControlCallbacks(locationControlCallbacks);
    551             controlAPI = gData.controlAPI;
    552         }
    553     }
    554 
    555     pthread_mutex_unlock(&gDataMutex);
    556     return controlAPI;
    557 }
    558 
    559 void
    560 LocationControlAPI::destroy()
    561 {
    562     delete this;
    563 }
    564 
    565 LocationControlAPI::LocationControlAPI()
    566 {
    567     LOC_LOGD("LOCATION CONTROL API CONSTRUCTOR");
    568 }
    569 
    570 LocationControlAPI::~LocationControlAPI()
    571 {
    572     LOC_LOGD("LOCATION CONTROL API DESTRUCTOR");
    573     pthread_mutex_lock(&gDataMutex);
    574 
    575     gData.controlAPI = NULL;
    576 
    577     pthread_mutex_unlock(&gDataMutex);
    578 }
    579 
    580 uint32_t
    581 LocationControlAPI::enable(LocationTechnologyType techType)
    582 {
    583     uint32_t id = 0;
    584     pthread_mutex_lock(&gDataMutex);
    585 
    586     if (gData.gnssInterface != NULL) {
    587         id = gData.gnssInterface->enable(techType);
    588     } else {
    589         LOC_LOGE("%s:%d]: No gnss interface available for Location Control API client %p ",
    590                  __func__, __LINE__, this);
    591     }
    592 
    593     pthread_mutex_unlock(&gDataMutex);
    594     return id;
    595 }
    596 
    597 void
    598 LocationControlAPI::disable(uint32_t id)
    599 {
    600     pthread_mutex_lock(&gDataMutex);
    601 
    602     if (gData.gnssInterface != NULL) {
    603         gData.gnssInterface->disable(id);
    604     } else {
    605         LOC_LOGE("%s:%d]: No gnss interface available for Location Control API client %p ",
    606                  __func__, __LINE__, this);
    607     }
    608 
    609     pthread_mutex_unlock(&gDataMutex);
    610 }
    611 
    612 uint32_t*
    613 LocationControlAPI::gnssUpdateConfig(GnssConfig config)
    614 {
    615     uint32_t* ids = NULL;
    616     pthread_mutex_lock(&gDataMutex);
    617 
    618     if (gData.gnssInterface != NULL) {
    619         ids = gData.gnssInterface->gnssUpdateConfig(config);
    620     } else {
    621         LOC_LOGE("%s:%d]: No gnss interface available for Location Control API client %p ",
    622                  __func__, __LINE__, this);
    623     }
    624 
    625     pthread_mutex_unlock(&gDataMutex);
    626     return ids;
    627 }
    628 
    629 uint32_t
    630 LocationControlAPI::gnssDeleteAidingData(GnssAidingData& data)
    631 {
    632     uint32_t id = 0;
    633     pthread_mutex_lock(&gDataMutex);
    634 
    635     if (gData.gnssInterface != NULL) {
    636         id = gData.gnssInterface->gnssDeleteAidingData(data);
    637     } else {
    638         LOC_LOGE("%s:%d]: No gnss interface available for Location Control API client %p ",
    639                  __func__, __LINE__, this);
    640     }
    641 
    642     pthread_mutex_unlock(&gDataMutex);
    643     return id;
    644 }
    645