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 <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
needsGnssTrackingInfo(LocationCallbacks & locationCallbacks)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
isGnssClient(LocationCallbacks & locationCallbacks)60 static bool isGnssClient(LocationCallbacks& locationCallbacks)
61 {
62 return (locationCallbacks.gnssNiCb != nullptr ||
63 locationCallbacks.trackingCb != nullptr ||
64 locationCallbacks.gnssMeasurementsCb != nullptr);
65 }
66
isFlpClient(LocationCallbacks & locationCallbacks)67 static bool isFlpClient(LocationCallbacks& locationCallbacks)
68 {
69 return (locationCallbacks.trackingCb != nullptr ||
70 locationCallbacks.batchingCb != nullptr);
71 }
72
isGeofenceClient(LocationCallbacks & locationCallbacks)73 static bool isGeofenceClient(LocationCallbacks& locationCallbacks)
74 {
75 return (locationCallbacks.geofenceBreachCb != nullptr ||
76 locationCallbacks.geofenceStatusCb != nullptr);
77 }
78
loadLocationInterface(const char * library,const char * name)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;
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*
createInstance(LocationCallbacks & locationCallbacks)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
destroy()187 LocationAPI::destroy()
188 {
189 delete this;
190 }
191
LocationAPI()192 LocationAPI::LocationAPI()
193 {
194 LOC_LOGD("LOCATION API CONSTRUCTOR");
195 }
196
~LocationAPI()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 size_t gnssClientCount = 0;
205 size_t flpClientCount = 0;
206 size_t geofenceClientCount = 0;
207 for (auto it2=gData.clientData.begin(); it2 != gData.clientData.end(); ++it2) {
208 if (isGnssClient(it2->second)) {
209 gnssClientCount++;
210 }
211 if (isFlpClient(it2->second)) {
212 flpClientCount++;
213 }
214 if (isGeofenceClient(it2->second)) {
215 geofenceClientCount++;
216 }
217 }
218 if (isGnssClient(it->second) && NULL != gData.gnssInterface) {
219 gData.gnssInterface->removeClient(it->first);
220 if (1 == gnssClientCount && NULL == gData.controlAPI) {
221 gData.gnssInterface->deinitialize();
222 }
223 }
224 if (isFlpClient(it->second) && NULL != gData.flpInterface) {
225 gData.flpInterface->removeClient(it->first);
226 if (1 == flpClientCount) {
227 gData.flpInterface->deinitialize();
228 }
229 }
230 if (isGeofenceClient(it->second) && NULL != gData.geofenceInterface) {
231 gData.geofenceInterface->removeClient(it->first);
232 if (1 == geofenceClientCount) {
233 gData.geofenceInterface->deinitialize();
234 }
235 }
236 gData.clientData.erase(it);
237 } else {
238 LOC_LOGE("%s:%d]: Location API client %p not found in client data",
239 __func__, __LINE__, this);
240 }
241
242 pthread_mutex_unlock(&gDataMutex);
243 }
244
245 void
updateCallbacks(LocationCallbacks & locationCallbacks)246 LocationAPI::updateCallbacks(LocationCallbacks& locationCallbacks)
247 {
248 if (nullptr == locationCallbacks.capabilitiesCb ||
249 nullptr == locationCallbacks.responseCb ||
250 nullptr == locationCallbacks.collectiveResponseCb) {
251 return;
252 }
253
254 pthread_mutex_lock(&gDataMutex);
255
256 if (isGnssClient(locationCallbacks)) {
257 if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
258 gData.gnssInterface =
259 (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface");
260 if (NULL == gData.gnssInterface) {
261 gGnssLoadFailed = true;
262 LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__);
263 } else {
264 gData.gnssInterface->initialize();
265 }
266 }
267 if (NULL != gData.gnssInterface) {
268 // either adds new Client or updates existing Client
269 gData.gnssInterface->addClient(this, locationCallbacks);
270 }
271 }
272
273 if (isFlpClient(locationCallbacks)) {
274 if (NULL == gData.flpInterface && !gFlpLoadFailed) {
275 gData.flpInterface =
276 (FlpInterface*)loadLocationInterface("libflp.so", "getFlpInterface");
277 if (NULL == gData.flpInterface) {
278 gFlpLoadFailed = true;
279 LOC_LOGW("%s:%d]: No flp interface available", __func__, __LINE__);
280 } else {
281 gData.flpInterface->initialize();
282 }
283 }
284 if (NULL != gData.flpInterface) {
285 // either adds new Client or updates existing Client
286 gData.flpInterface->addClient(this, locationCallbacks);
287 }
288 }
289
290 if (isGeofenceClient(locationCallbacks)) {
291 if (NULL == gData.geofenceInterface && !gGeofenceLoadFailed) {
292 gData.geofenceInterface =
293 (GeofenceInterface*)loadLocationInterface("libgeofence.so", "getGeofenceInterface");
294 if (NULL == gData.geofenceInterface) {
295 gGeofenceLoadFailed = true;
296 LOC_LOGW("%s:%d]: No geofence interface available", __func__, __LINE__);
297 } else {
298 gData.geofenceInterface->initialize();
299 }
300 }
301 if (NULL != gData.geofenceInterface) {
302 // either adds new Client or updates existing Client
303 gData.geofenceInterface->addClient(this, locationCallbacks);
304 }
305 }
306
307 gData.clientData[this] = locationCallbacks;
308
309 pthread_mutex_unlock(&gDataMutex);
310 }
311
312 uint32_t
startTracking(LocationOptions & locationOptions)313 LocationAPI::startTracking(LocationOptions& locationOptions)
314 {
315 uint32_t id = 0;
316 pthread_mutex_lock(&gDataMutex);
317
318 auto it = gData.clientData.find(this);
319 if (it != gData.clientData.end()) {
320 if (gData.flpInterface != NULL && locationOptions.minDistance > 0) {
321 id = gData.flpInterface->startTracking(this, locationOptions);
322 } else if (gData.gnssInterface != NULL && needsGnssTrackingInfo(it->second)) {
323 id = gData.gnssInterface->startTracking(this, locationOptions);
324 } else if (gData.flpInterface != NULL) {
325 id = gData.flpInterface->startTracking(this, locationOptions);
326 } else if (gData.gnssInterface != NULL) {
327 id = gData.gnssInterface->startTracking(this, locationOptions);
328 } else {
329 LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ",
330 __func__, __LINE__, this);
331 }
332 } else {
333 LOC_LOGE("%s:%d]: Location API client %p not found in client data",
334 __func__, __LINE__, this);
335 }
336
337 pthread_mutex_unlock(&gDataMutex);
338 return id;
339 }
340
341 void
stopTracking(uint32_t id)342 LocationAPI::stopTracking(uint32_t id)
343 {
344 pthread_mutex_lock(&gDataMutex);
345
346 auto it = gData.clientData.find(this);
347 if (it != gData.clientData.end()) {
348 // we don't know if tracking was started on flp or gnss, so we call stop on both, where
349 // stopTracking call to the incorrect interface will fail without response back to client
350 if (gData.gnssInterface != NULL) {
351 gData.gnssInterface->stopTracking(this, id);
352 }
353 if (gData.flpInterface != NULL) {
354 gData.flpInterface->stopTracking(this, id);
355 }
356 if (gData.flpInterface != NULL && gData.gnssInterface != NULL) {
357 LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ",
358 __func__, __LINE__, this);
359 }
360 } else {
361 LOC_LOGE("%s:%d]: Location API client %p not found in client data",
362 __func__, __LINE__, this);
363 }
364
365 pthread_mutex_unlock(&gDataMutex);
366 }
367
368 void
updateTrackingOptions(uint32_t id,LocationOptions & locationOptions)369 LocationAPI::updateTrackingOptions(uint32_t id, LocationOptions& locationOptions)
370 {
371 pthread_mutex_lock(&gDataMutex);
372
373 auto it = gData.clientData.find(this);
374 if (it != gData.clientData.end()) {
375 // we don't know if tracking was started on flp or gnss, so we call update on both, where
376 // updateTracking call to the incorrect interface will fail without response back to client
377 if (gData.gnssInterface != NULL) {
378 gData.gnssInterface->updateTrackingOptions(this, id, locationOptions);
379 }
380 if (gData.flpInterface != NULL) {
381 gData.flpInterface->updateTrackingOptions(this, id, locationOptions);
382 }
383 if (gData.flpInterface != NULL && gData.gnssInterface != NULL) {
384 LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ",
385 __func__, __LINE__, this);
386 }
387 } else {
388 LOC_LOGE("%s:%d]: Location API client %p not found in client data",
389 __func__, __LINE__, this);
390 }
391
392 pthread_mutex_unlock(&gDataMutex);
393 }
394
395 uint32_t
startBatching(LocationOptions & locationOptions)396 LocationAPI::startBatching(LocationOptions& locationOptions)
397 {
398 uint32_t id = 0;
399 pthread_mutex_lock(&gDataMutex);
400
401 if (gData.flpInterface != NULL) {
402 id = gData.flpInterface->startBatching(this, locationOptions);
403 } else {
404 LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
405 __func__, __LINE__, this);
406 }
407
408 pthread_mutex_unlock(&gDataMutex);
409 return id;
410 }
411
412 void
stopBatching(uint32_t id)413 LocationAPI::stopBatching(uint32_t id)
414 {
415 pthread_mutex_lock(&gDataMutex);
416
417 if (gData.flpInterface != NULL) {
418 gData.flpInterface->stopBatching(this, id);
419 } else {
420 LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
421 __func__, __LINE__, this);
422 }
423
424 pthread_mutex_unlock(&gDataMutex);
425 }
426
427 void
updateBatchingOptions(uint32_t id,LocationOptions & locationOptions)428 LocationAPI::updateBatchingOptions(uint32_t id, LocationOptions& locationOptions)
429 {
430 pthread_mutex_lock(&gDataMutex);
431
432 if (gData.flpInterface != NULL) {
433 gData.flpInterface->updateBatchingOptions(this,
434 id,
435 locationOptions);
436 } else {
437 LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
438 __func__, __LINE__, this);
439 }
440
441 pthread_mutex_unlock(&gDataMutex);
442 }
443
444 void
getBatchedLocations(uint32_t id,size_t count)445 LocationAPI::getBatchedLocations(uint32_t id, size_t count)
446 {
447 pthread_mutex_lock(&gDataMutex);
448
449 if (gData.flpInterface != NULL) {
450 gData.flpInterface->getBatchedLocations(this, id, count);
451 } else {
452 LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
453 __func__, __LINE__, this);
454 }
455
456 pthread_mutex_unlock(&gDataMutex);
457 }
458
459 uint32_t*
addGeofences(size_t count,GeofenceOption * options,GeofenceInfo * info)460 LocationAPI::addGeofences(size_t count, GeofenceOption* options, GeofenceInfo* info)
461 {
462 uint32_t* ids = NULL;
463 pthread_mutex_lock(&gDataMutex);
464
465 if (gData.geofenceInterface != NULL) {
466 ids = gData.geofenceInterface->addGeofences(this, count, options, info);
467 } else {
468 LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ",
469 __func__, __LINE__, this);
470 }
471
472 pthread_mutex_unlock(&gDataMutex);
473 return ids;
474 }
475
476 void
removeGeofences(size_t count,uint32_t * ids)477 LocationAPI::removeGeofences(size_t count, uint32_t* ids)
478 {
479 pthread_mutex_lock(&gDataMutex);
480
481 if (gData.geofenceInterface != NULL) {
482 gData.geofenceInterface->removeGeofences(this, count, ids);
483 } else {
484 LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ",
485 __func__, __LINE__, this);
486 }
487
488 pthread_mutex_unlock(&gDataMutex);
489 }
490
491 void
modifyGeofences(size_t count,uint32_t * ids,GeofenceOption * options)492 LocationAPI::modifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options)
493 {
494 pthread_mutex_lock(&gDataMutex);
495
496 if (gData.geofenceInterface != NULL) {
497 gData.geofenceInterface->modifyGeofences(this, count, ids, options);
498 } else {
499 LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ",
500 __func__, __LINE__, this);
501 }
502
503 pthread_mutex_unlock(&gDataMutex);
504 }
505
506 void
pauseGeofences(size_t count,uint32_t * ids)507 LocationAPI::pauseGeofences(size_t count, uint32_t* ids)
508 {
509 pthread_mutex_lock(&gDataMutex);
510
511 if (gData.geofenceInterface != NULL) {
512 gData.geofenceInterface->pauseGeofences(this, count, ids);
513 } else {
514 LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ",
515 __func__, __LINE__, this);
516 }
517
518 pthread_mutex_unlock(&gDataMutex);
519 }
520
521 void
resumeGeofences(size_t count,uint32_t * ids)522 LocationAPI::resumeGeofences(size_t count, uint32_t* ids)
523 {
524 pthread_mutex_lock(&gDataMutex);
525
526 if (gData.geofenceInterface != NULL) {
527 gData.geofenceInterface->resumeGeofences(this, count, ids);
528 } else {
529 LOC_LOGE("%s:%d]: No geofence interface available for Location API client %p ",
530 __func__, __LINE__, this);
531 }
532
533 pthread_mutex_unlock(&gDataMutex);
534 }
535
536 void
gnssNiResponse(uint32_t id,GnssNiResponse response)537 LocationAPI::gnssNiResponse(uint32_t id, GnssNiResponse response)
538 {
539 pthread_mutex_lock(&gDataMutex);
540
541 if (gData.gnssInterface != NULL) {
542 gData.gnssInterface->gnssNiResponse(this, id, response);
543 } else {
544 LOC_LOGE("%s:%d]: No gnss interface available for Location API client %p ",
545 __func__, __LINE__, this);
546 }
547
548 pthread_mutex_unlock(&gDataMutex);
549 }
550
551 LocationControlAPI*
createInstance(LocationControlCallbacks & locationControlCallbacks)552 LocationControlAPI::createInstance(LocationControlCallbacks& locationControlCallbacks)
553 {
554 LocationControlAPI* controlAPI = NULL;
555 pthread_mutex_lock(&gDataMutex);
556
557 if (nullptr != locationControlCallbacks.responseCb && NULL == gData.controlAPI) {
558 if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
559 gData.gnssInterface =
560 (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface");
561 if (NULL == gData.gnssInterface) {
562 gGnssLoadFailed = true;
563 LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__);
564 } else {
565 gData.gnssInterface->initialize();
566 }
567 }
568 if (NULL != gData.gnssInterface) {
569 gData.controlAPI = new LocationControlAPI();
570 gData.controlCallbacks = locationControlCallbacks;
571 gData.gnssInterface->setControlCallbacks(locationControlCallbacks);
572 controlAPI = gData.controlAPI;
573 }
574 }
575
576 pthread_mutex_unlock(&gDataMutex);
577 return controlAPI;
578 }
579
580 void
destroy()581 LocationControlAPI::destroy()
582 {
583 delete this;
584 }
585
LocationControlAPI()586 LocationControlAPI::LocationControlAPI()
587 {
588 LOC_LOGD("LOCATION CONTROL API CONSTRUCTOR");
589 }
590
~LocationControlAPI()591 LocationControlAPI::~LocationControlAPI()
592 {
593 LOC_LOGD("LOCATION CONTROL API DESTRUCTOR");
594 pthread_mutex_lock(&gDataMutex);
595
596 size_t gnssClientCount = 0;
597 for (auto it=gData.clientData.begin(); it != gData.clientData.end(); ++it) {
598 if (isGnssClient(it->second)) {
599 gnssClientCount++;
600 }
601 }
602 if (gData.gnssInterface != NULL && 0 == gnssClientCount) {
603 //@todo: we might want to call gData.gnssInterface.disable before deinitialize?
604 gData.gnssInterface->deinitialize();
605 }
606 gData.controlAPI = NULL;
607
608 pthread_mutex_unlock(&gDataMutex);
609 }
610
611 uint32_t
enable(LocationTechnologyType techType)612 LocationControlAPI::enable(LocationTechnologyType techType)
613 {
614 uint32_t id = 0;
615 pthread_mutex_lock(&gDataMutex);
616
617 if (gData.gnssInterface != NULL) {
618 id = gData.gnssInterface->enable(techType);
619 } else {
620 LOC_LOGE("%s:%d]: No gnss interface available for Location Control API client %p ",
621 __func__, __LINE__, this);
622 }
623
624 pthread_mutex_unlock(&gDataMutex);
625 return id;
626 }
627
628 void
disable(uint32_t id)629 LocationControlAPI::disable(uint32_t id)
630 {
631 pthread_mutex_lock(&gDataMutex);
632
633 if (gData.gnssInterface != NULL) {
634 gData.gnssInterface->disable(id);
635 } else {
636 LOC_LOGE("%s:%d]: No gnss interface available for Location Control API client %p ",
637 __func__, __LINE__, this);
638 }
639
640 pthread_mutex_unlock(&gDataMutex);
641 }
642
643 uint32_t*
gnssUpdateConfig(GnssConfig config)644 LocationControlAPI::gnssUpdateConfig(GnssConfig config)
645 {
646 uint32_t* ids = NULL;
647 pthread_mutex_lock(&gDataMutex);
648
649 if (gData.gnssInterface != NULL) {
650 ids = gData.gnssInterface->gnssUpdateConfig(config);
651 } else {
652 LOC_LOGE("%s:%d]: No gnss interface available for Location Control API client %p ",
653 __func__, __LINE__, this);
654 }
655
656 pthread_mutex_unlock(&gDataMutex);
657 return ids;
658 }
659
660 uint32_t
gnssDeleteAidingData(GnssAidingData & data)661 LocationControlAPI::gnssDeleteAidingData(GnssAidingData& data)
662 {
663 uint32_t id = 0;
664 pthread_mutex_lock(&gDataMutex);
665
666 if (gData.gnssInterface != NULL) {
667 id = gData.gnssInterface->gnssDeleteAidingData(data);
668 } else {
669 LOC_LOGE("%s:%d]: No gnss interface available for Location Control API client %p ",
670 __func__, __LINE__, this);
671 }
672
673 pthread_mutex_unlock(&gDataMutex);
674 return id;
675 }
676