1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 // Note that to avoid always polluting the include paths of nanoapps, we use
18 // symlinks under the chre_nsl_internal include path to the "real" files, e.g.
19 // chre_nsl_internal/platform/shared maps to the same files that would normally
20 // be included via chre/platform/shared
21
22 #include "chre_nsl_internal/platform/shared/nanoapp_support_lib_dso.h"
23
24 #include <algorithm>
25
26 #include "chre_api/chre.h"
27 #include "chre_nsl_internal/platform/shared/debug_dump.h"
28 #include "chre_nsl_internal/util/macros.h"
29 #include "chre_nsl_internal/util/system/napp_permissions.h"
30 #ifdef CHRE_NANOAPP_USES_WIFI
31 #include "chre_nsl_internal/util/system/wifi_util.h"
32 #endif
33
34 #ifndef LOG_TAG
35 #define LOG_TAG "[NSL]"
36 #endif // LOG_TAG
37
38 /**
39 * @file
40 * The Nanoapp Support Library (NSL) that gets built with nanoapps to act as an
41 * intermediary to the reference CHRE implementation. It provides hooks so the
42 * app can be registered with the system, and also provides a layer where we can
43 * implement cross-version compatibility features as needed.
44 */
45
46 namespace {
47
48 constexpr uint32_t kNanoappPermissions = 0
49 // DO NOT USE this macro outside of specific CHQTS nanoapps. This is only used
50 // to allow testing of invalid permission declarations.
51 #ifdef CHRE_TEST_NANOAPP_PERMS
52 | CHRE_TEST_NANOAPP_PERMS
53 #else
54 #ifdef CHRE_NANOAPP_USES_AUDIO
55 | static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_AUDIO)
56 #endif
57 #ifdef CHRE_NANOAPP_USES_BLE
58 | static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_BLE)
59 #endif
60 #ifdef CHRE_NANOAPP_USES_GNSS
61 | static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_GNSS)
62 #endif
63 #ifdef CHRE_NANOAPP_USES_WIFI
64 | static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_WIFI)
65 #endif
66 #ifdef CHRE_NANOAPP_USES_WWAN
67 | static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_WWAN)
68 #endif
69 #endif // CHRE_TEST_NANOAPP_PERMS
70 ;
71
72 #if defined(CHRE_SLPI_UIMG_ENABLED) || defined(CHRE_TCM_ENABLED)
73 constexpr int kIsTcmNanoapp = 1;
74 #else
75 constexpr int kIsTcmNanoapp = 0;
76 #endif // CHRE_SLPI_UIMG_ENABLED
77
78 #if !defined(CHRE_NANOAPP_DISABLE_BACKCOMPAT) && defined(CHRE_NANOAPP_USES_GNSS)
79 // Return a v1.3+ GnssLocationEvent for the nanoapp when running on a v1.2-
80 // platform.
translateLegacyGnssLocation(const chreGnssLocationEvent & legacyEvent)81 chreGnssLocationEvent translateLegacyGnssLocation(
82 const chreGnssLocationEvent &legacyEvent) {
83 // Copy v1.2- fields over to a v1.3+ event.
84 chreGnssLocationEvent newEvent = {};
85 newEvent.timestamp = legacyEvent.timestamp;
86 newEvent.latitude_deg_e7 = legacyEvent.latitude_deg_e7;
87 newEvent.longitude_deg_e7 = legacyEvent.longitude_deg_e7;
88 newEvent.altitude = legacyEvent.altitude;
89 newEvent.speed = legacyEvent.speed;
90 newEvent.bearing = legacyEvent.bearing;
91 newEvent.accuracy = legacyEvent.accuracy;
92 newEvent.flags = legacyEvent.flags;
93
94 // Unset flags that are defined in v1.3+ but not in v1.2-.
95 newEvent.flags &= ~(CHRE_GPS_LOCATION_HAS_ALTITUDE_ACCURACY |
96 CHRE_GPS_LOCATION_HAS_SPEED_ACCURACY |
97 CHRE_GPS_LOCATION_HAS_BEARING_ACCURACY);
98 return newEvent;
99 }
100
nanoappHandleEventCompat(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)101 void nanoappHandleEventCompat(uint32_t senderInstanceId, uint16_t eventType,
102 const void *eventData) {
103 if (eventType == CHRE_EVENT_GNSS_LOCATION &&
104 chreGetApiVersion() < CHRE_API_VERSION_1_3) {
105 chreGnssLocationEvent event = translateLegacyGnssLocation(
106 *static_cast<const chreGnssLocationEvent *>(eventData));
107 nanoappHandleEvent(senderInstanceId, eventType, &event);
108 } else {
109 nanoappHandleEvent(senderInstanceId, eventType, eventData);
110 }
111 }
112 #endif
113
114 #if !defined(CHRE_NANOAPP_DISABLE_BACKCOMPAT) && \
115 defined(CHRE_NANOAPP_USES_BLE) && \
116 defined(CHRE_FIRST_SUPPORTED_API_VERSION) && \
117 CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
reverseServiceDataUuid(struct chreBleGenericFilter * filter)118 void reverseServiceDataUuid(struct chreBleGenericFilter *filter) {
119 if (filter->type != CHRE_BLE_AD_TYPE_SERVICE_DATA_WITH_UUID_16_LE ||
120 filter->len == 0) {
121 return;
122 }
123 std::swap(filter->data[0], filter->data[1]);
124 std::swap(filter->dataMask[0], filter->dataMask[1]);
125 if (filter->len == 1) {
126 filter->data[0] = 0x0;
127 filter->dataMask[0] = 0x0;
128 filter->len = 2;
129 }
130 }
131
serviceDataFilterEndianSwapRequired(const struct chreBleScanFilter * filter)132 bool serviceDataFilterEndianSwapRequired(
133 const struct chreBleScanFilter *filter) {
134 if (chreGetApiVersion() >= CHRE_API_VERSION_1_8 || filter == nullptr) {
135 return false;
136 }
137 for (size_t i = 0; i < filter->scanFilterCount; i++) {
138 if (filter->scanFilters[i].type ==
139 CHRE_BLE_AD_TYPE_SERVICE_DATA_WITH_UUID_16_LE &&
140 filter->scanFilters[i].len > 0) {
141 return true;
142 }
143 }
144 return false;
145 }
146 #endif // !defined(CHRE_NANOAPP_DISABLE_BACKCOMPAT) &&
147 // defined(CHRE_NANOAPP_USES_BLE) &&
148 // defined(CHRE_FIRST_SUPPORTED_API_VERSION) &&
149 // CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
150
151 } // anonymous namespace
152
153 //! Used to determine the given unstable ID that was provided when building this
154 //! nanoapp, if any. The symbol is placed in its own section so it can be
155 //! stripped to determine if the nanoapp changed compared to a previous version.
156 //! We also align the variable to match the minimum alignment of the surrounding
157 //! sections, since for compilers with a default size-1 alignment, there might
158 //! be a spill-over from the previous segment if not zero-padded, when we
159 //! attempt to read the string.
160 extern "C" DLL_EXPORT const char _chreNanoappUnstableId[]
161 __attribute__((section(".unstable_id"))) __attribute__((aligned(8))) =
162 NANOAPP_UNSTABLE_ID;
163
164 extern "C" DLL_EXPORT const struct chreNslNanoappInfo _chreNslDsoNanoappInfo = {
165 /* magic */ CHRE_NSL_NANOAPP_INFO_MAGIC,
166 /* structMinorVersion */ CHRE_NSL_NANOAPP_INFO_STRUCT_MINOR_VERSION,
167 /* isSystemNanoapp */ NANOAPP_IS_SYSTEM_NANOAPP,
168 /* isTcmNanoapp */ kIsTcmNanoapp,
169 /* reservedFlags */ 0,
170 /* reserved */ 0,
171 /* targetApiVersion */ CHRE_API_VERSION,
172
173 // These values are supplied by the build environment.
174 /* vendor */ NANOAPP_VENDOR_STRING,
175 /* name */ NANOAPP_NAME_STRING,
176 /* appId */ NANOAPP_ID,
177 /* appVersion */ NANOAPP_VERSION,
178 /* entryPoints */
179 {
180 /* start */ nanoappStart,
181 #if !defined(CHRE_NANOAPP_DISABLE_BACKCOMPAT) && defined(CHRE_NANOAPP_USES_GNSS)
182 /* handleEvent */ nanoappHandleEventCompat,
183 #else
184 /* handleEvent */ nanoappHandleEvent,
185 #endif
186 /* end */ nanoappEnd,
187 },
188 /* appVersionString */ _chreNanoappUnstableId,
189 /* appPermissions */ kNanoappPermissions,
190 };
191
getChreNslDsoNanoappInfo()192 const struct chreNslNanoappInfo *getChreNslDsoNanoappInfo() {
193 return &_chreNslDsoNanoappInfo;
194 }
195
196 // The code section below provides default implementations for new symbols
197 // introduced in CHRE API v1.2+ to provide binary compatibility with previous
198 // CHRE implementations. Note that we don't presently include symbols for v1.1,
199 // as the current known set of CHRE platforms that use this NSL implementation
200 // are all v1.1+.
201 // If a nanoapp knows that it is only targeting the latest platform version, it
202 // can define the CHRE_NANOAPP_DISABLE_BACKCOMPAT flag, so this indirection will
203 // be avoided at the expense of a nanoapp not being able to load at all on prior
204 // implementations.
205
206 #if !defined(CHRE_NANOAPP_DISABLE_BACKCOMPAT)
207
208 #if !defined(CHRE_FIRST_SUPPORTED_API_VERSION)
209 #error "CHRE_FIRST_SUPPORTED_API_VERSION must be defined for this platform"
210 #elif CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_1
211 #error "CHRE_FIRST_SUPPORTED_API_VERSION must be at least CHRE_API_VERSION_1_1"
212 #endif // !defined(CHRE_FIRST_SUPPORTED_API_VERSION)
213
214 #include <dlfcn.h>
215
216 namespace {
217
218 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
219 // Populate chreNanoappInfo for CHRE API pre v1.8.
populateChreNanoappInfoPre18(struct chreNanoappInfo * info)220 void populateChreNanoappInfoPre18(struct chreNanoappInfo *info) {
221 info->rpcServiceCount = 0;
222 info->rpcServices = nullptr;
223 memset(&info->reserved, 0, sizeof(info->reserved));
224 }
225 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8 */
226
227 } // namespace
228
229 /**
230 * Lazily calls dlsym to find the function pointer for a given function
231 * (provided without quotes) in another library (i.e. the CHRE platform DSO),
232 * caching and returning the result.
233 */
234 #define CHRE_NSL_LAZY_LOOKUP(functionName) \
235 ({ \
236 static bool lookupPerformed = false; \
237 static decltype(functionName) *funcPtr = nullptr; \
238 if (!lookupPerformed) { \
239 funcPtr = reinterpret_cast<decltype(funcPtr)>( \
240 dlsym(RTLD_NEXT, STRINGIFY(functionName))); \
241 lookupPerformed = true; \
242 } \
243 funcPtr; \
244 })
245
246 #ifdef CHRE_NANOAPP_USES_AUDIO
247
248 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
249 WEAK_SYMBOL
chreAudioGetSource(uint32_t handle,struct chreAudioSource * audioSource)250 bool chreAudioGetSource(uint32_t handle, struct chreAudioSource *audioSource) {
251 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreAudioGetSource);
252 return (fptr != nullptr) ? fptr(handle, audioSource) : false;
253 }
254 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
255
256 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
257 WEAK_SYMBOL
chreAudioConfigureSource(uint32_t handle,bool enable,uint64_t bufferDuration,uint64_t deliveryInterval)258 bool chreAudioConfigureSource(uint32_t handle, bool enable,
259 uint64_t bufferDuration,
260 uint64_t deliveryInterval) {
261 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreAudioConfigureSource);
262 return (fptr != nullptr)
263 ? fptr(handle, enable, bufferDuration, deliveryInterval)
264 : false;
265 }
266 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
267
268 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
269 WEAK_SYMBOL
chreAudioGetStatus(uint32_t handle,struct chreAudioSourceStatus * status)270 bool chreAudioGetStatus(uint32_t handle, struct chreAudioSourceStatus *status) {
271 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreAudioGetStatus);
272 return (fptr != nullptr) ? fptr(handle, status) : false;
273 }
274 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
275
276 #endif /* CHRE_NANOAPP_USES_AUDIO */
277
278 #ifdef CHRE_NANOAPP_USES_BLE
279
280 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
281 WEAK_SYMBOL
chreBleGetCapabilities()282 uint32_t chreBleGetCapabilities() {
283 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleGetCapabilities);
284 return (fptr != nullptr) ? fptr() : CHRE_BLE_CAPABILITIES_NONE;
285 }
286 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
287
288 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
289 WEAK_SYMBOL
chreBleGetFilterCapabilities()290 uint32_t chreBleGetFilterCapabilities() {
291 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleGetFilterCapabilities);
292 return (fptr != nullptr) ? fptr() : CHRE_BLE_FILTER_CAPABILITIES_NONE;
293 }
294 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
295
296 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_7
297 WEAK_SYMBOL
chreBleFlushAsync(const void * cookie)298 bool chreBleFlushAsync(const void *cookie) {
299 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleFlushAsync);
300 return (fptr != nullptr) ? fptr(cookie) : false;
301 }
302 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_7 */
303
304 // NOTE: The backward compatibility provided by this stub is only needed below
305 // CHRE v1.8 so we check the first API version for the platform against v1.8.
306 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
307 WEAK_SYMBOL
chreBleStartScanAsync(chreBleScanMode mode,uint32_t reportDelayMs,const struct chreBleScanFilter * filter)308 bool chreBleStartScanAsync(chreBleScanMode mode, uint32_t reportDelayMs,
309 const struct chreBleScanFilter *filter) {
310 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleStartScanAsync);
311 if (fptr == nullptr) {
312 return false;
313 } else if (!serviceDataFilterEndianSwapRequired(filter)) {
314 return fptr(mode, reportDelayMs, filter);
315 }
316 // For nanoapps compiled against v1.8+ working with earlier versions of CHRE,
317 // convert service data filters to big-endian format.
318 chreBleScanFilter convertedFilter = *filter;
319 auto genericFilters = static_cast<chreBleGenericFilter *>(
320 chreHeapAlloc(sizeof(chreBleGenericFilter) * filter->scanFilterCount));
321 if (genericFilters == nullptr) {
322 chreLog(CHRE_LOG_ERROR, "Alloc failure in chreBleStartScanAsync NSL");
323 return false;
324 }
325 memcpy(genericFilters, filter->scanFilters,
326 filter->scanFilterCount * sizeof(chreBleGenericFilter));
327 for (size_t i = 0; i < filter->scanFilterCount; i++) {
328 reverseServiceDataUuid(&genericFilters[i]);
329 }
330 convertedFilter.scanFilters = genericFilters;
331 bool success = fptr(mode, reportDelayMs, &convertedFilter);
332 chreHeapFree(const_cast<chreBleGenericFilter *>(convertedFilter.scanFilters));
333 return success;
334 }
335 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8 */
336
337 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_9
338 WEAK_SYMBOL
chreBleStartScanAsyncV1_9(chreBleScanMode mode,uint32_t reportDelayMs,const struct chreBleScanFilterV1_9 * filter,const void * cookie)339 bool chreBleStartScanAsyncV1_9(chreBleScanMode mode, uint32_t reportDelayMs,
340 const struct chreBleScanFilterV1_9 *filter,
341 const void *cookie) {
342 if (chreGetApiVersion() < CHRE_API_VERSION_1_9) {
343 return false;
344 }
345 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleStartScanAsyncV1_9);
346 if (fptr == nullptr) {
347 return false;
348 }
349 return fptr(mode, reportDelayMs, filter, cookie);
350 }
351 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_9 */
352
353 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
354 WEAK_SYMBOL
chreBleStopScanAsync()355 bool chreBleStopScanAsync() {
356 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleStopScanAsync);
357 return (fptr != nullptr) ? fptr() : false;
358 }
359 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
360
361 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_9
362 WEAK_SYMBOL
chreBleStopScanAsyncV1_9(const void * cookie)363 bool chreBleStopScanAsyncV1_9(const void *cookie) {
364 if (chreGetApiVersion() < CHRE_API_VERSION_1_9) {
365 return false;
366 }
367 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleStopScanAsyncV1_9);
368 if (fptr == nullptr) {
369 return false;
370 }
371 return fptr(cookie);
372 }
373 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_9 */
374
375 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
376 WEAK_SYMBOL
chreBleReadRssiAsync(uint16_t connectionHandle,const void * cookie)377 bool chreBleReadRssiAsync(uint16_t connectionHandle, const void *cookie) {
378 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleReadRssiAsync);
379 return (fptr != nullptr) ? fptr(connectionHandle, cookie) : false;
380 }
381 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8 */
382
383 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
384 WEAK_SYMBOL
chreBleGetScanStatus(struct chreBleScanStatus * status)385 bool chreBleGetScanStatus(struct chreBleScanStatus *status) {
386 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleGetScanStatus);
387 return (fptr != nullptr) ? fptr(status) : false;
388 }
389 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8 */
390
391 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_11
392 WEAK_SYMBOL
chreBleSocketAccept(uint64_t socketId)393 bool chreBleSocketAccept(uint64_t socketId) {
394 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleSocketAccept);
395 return (fptr != nullptr) ? fptr(socketId) : false;
396 }
397
398 WEAK_SYMBOL
chreBleSocketSend(uint64_t socketId,const void * data,uint16_t length,chreBleSocketPacketFreeFunction * freeCallback)399 int32_t chreBleSocketSend(uint64_t socketId, const void *data, uint16_t length,
400 chreBleSocketPacketFreeFunction *freeCallback) {
401 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreBleSocketSend);
402 return (fptr != nullptr) ? fptr(socketId, data, length, freeCallback)
403 : CHRE_ERROR_NOT_SUPPORTED;
404 }
405 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_11 */
406
407 #endif /* CHRE_NANOAPP_USES_BLE */
408
409 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
410 WEAK_SYMBOL
chreConfigureHostSleepStateEvents(bool enable)411 void chreConfigureHostSleepStateEvents(bool enable) {
412 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreConfigureHostSleepStateEvents);
413 if (fptr != nullptr) {
414 fptr(enable);
415 }
416 }
417 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
418
419 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
420 WEAK_SYMBOL
chreIsHostAwake(void)421 bool chreIsHostAwake(void) {
422 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreIsHostAwake);
423 return (fptr != nullptr) ? fptr() : false;
424 }
425 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
426
427 #ifdef CHRE_NANOAPP_USES_GNSS
428
429 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
430 WEAK_SYMBOL
chreGnssConfigurePassiveLocationListener(bool enable)431 bool chreGnssConfigurePassiveLocationListener(bool enable) {
432 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGnssConfigurePassiveLocationListener);
433 return (fptr != nullptr) ? fptr(enable) : false;
434 }
435 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
436
437 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_11
438 WEAK_SYMBOL
chreGnssLocationSessionStartAsyncV1_11(uint32_t minIntervalMs,uint32_t minTimeToNextFixMs,const void * cookie,enum chreGnssSource source)439 bool chreGnssLocationSessionStartAsyncV1_11(uint32_t minIntervalMs,
440 uint32_t minTimeToNextFixMs,
441 const void *cookie,
442 enum chreGnssSource source) {
443 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGnssLocationSessionStartAsyncV1_11);
444 if (fptr != nullptr) {
445 return fptr(minIntervalMs, minTimeToNextFixMs, cookie, source);
446 }
447 if (source == CHRE_GNSS_SOURCE_UNSPECIFIED ||
448 source == CHRE_GNSS_SOURCE_LOCAL) {
449 return chreGnssLocationSessionStartAsync(minIntervalMs, minTimeToNextFixMs,
450 cookie);
451 }
452 return false;
453 }
454
455 WEAK_SYMBOL
chreGnssMeasurementSessionStartAsyncV1_11(uint32_t minIntervalMs,const void * cookie,enum chreGnssSource source)456 bool chreGnssMeasurementSessionStartAsyncV1_11(uint32_t minIntervalMs,
457 const void *cookie,
458 enum chreGnssSource source) {
459 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGnssMeasurementSessionStartAsyncV1_11);
460 if (fptr != nullptr) {
461 return fptr(minIntervalMs, cookie, source);
462 }
463 if (source == CHRE_GNSS_SOURCE_UNSPECIFIED ||
464 source == CHRE_GNSS_SOURCE_LOCAL) {
465 return chreGnssMeasurementSessionStartAsync(minIntervalMs, cookie);
466 }
467 return false;
468 }
469 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_11 */
470
471 #endif /* CHRE_NANOAPP_USES_GNSS */
472
473 #ifdef CHRE_NANOAPP_USES_WIFI
474
475 // NOTE: The backward compatibility provided by this stub is only needed below
476 // CHRE v1.5 so we check the first API version for the platform against v1.5.
477 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5
478 WEAK_SYMBOL
chreWifiRequestScanAsync(const struct chreWifiScanParams * params,const void * cookie)479 bool chreWifiRequestScanAsync(const struct chreWifiScanParams *params,
480 const void *cookie) {
481 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiRequestScanAsync);
482
483 if (fptr == nullptr) {
484 // Should never happen
485 return false;
486 } else if (chreGetApiVersion() < CHRE_API_VERSION_1_5) {
487 const struct chreWifiScanParams legacyParams =
488 chre::translateToLegacyWifiScanParams(params);
489 return fptr(&legacyParams, cookie);
490 } else {
491 return fptr(params, cookie);
492 }
493 }
494 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5 */
495
496 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
497 WEAK_SYMBOL
chreWifiRequestRangingAsync(const struct chreWifiRangingParams * params,const void * cookie)498 bool chreWifiRequestRangingAsync(const struct chreWifiRangingParams *params,
499 const void *cookie) {
500 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiRequestRangingAsync);
501 return (fptr != nullptr) ? fptr(params, cookie) : false;
502 }
503 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
504
505 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
506 WEAK_SYMBOL
chreWifiNanRequestRangingAsync(const struct chreWifiNanRangingParams * params,const void * cookie)507 bool chreWifiNanRequestRangingAsync(
508 const struct chreWifiNanRangingParams *params, const void *cookie) {
509 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiNanRequestRangingAsync);
510 return (fptr != nullptr) ? fptr(params, cookie) : false;
511 }
512 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
513
514 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
515 WEAK_SYMBOL
chreWifiNanSubscribe(struct chreWifiNanSubscribeConfig * config,const void * cookie)516 bool chreWifiNanSubscribe(struct chreWifiNanSubscribeConfig *config,
517 const void *cookie) {
518 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiNanSubscribe);
519 return (fptr != nullptr) ? fptr(config, cookie) : false;
520 }
521 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
522
523 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
524 WEAK_SYMBOL
chreWifiNanSubscribeCancel(uint32_t subscriptionID)525 bool chreWifiNanSubscribeCancel(uint32_t subscriptionID) {
526 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiNanSubscribeCancel);
527 return (fptr != nullptr) ? fptr(subscriptionID) : false;
528 }
529 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
530
531 #endif /* CHRE_NANOAPP_USES_WIFI */
532
533 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5
534 WEAK_SYMBOL
chreSensorFind(uint8_t sensorType,uint8_t sensorIndex,uint32_t * handle)535 bool chreSensorFind(uint8_t sensorType, uint8_t sensorIndex, uint32_t *handle) {
536 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSensorFind);
537 if (fptr != nullptr) {
538 return fptr(sensorType, sensorIndex, handle);
539 } else if (sensorIndex == 0) {
540 return chreSensorFindDefault(sensorType, handle);
541 } else {
542 return false;
543 }
544 }
545 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5 */
546
547 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3
548 WEAK_SYMBOL
chreSensorConfigureBiasEvents(uint32_t sensorHandle,bool enable)549 bool chreSensorConfigureBiasEvents(uint32_t sensorHandle, bool enable) {
550 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSensorConfigureBiasEvents);
551 return (fptr != nullptr) ? fptr(sensorHandle, enable) : false;
552 }
553 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3 */
554
555 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3
556 WEAK_SYMBOL
chreSensorGetThreeAxisBias(uint32_t sensorHandle,struct chreSensorThreeAxisData * bias)557 bool chreSensorGetThreeAxisBias(uint32_t sensorHandle,
558 struct chreSensorThreeAxisData *bias) {
559 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSensorGetThreeAxisBias);
560 return (fptr != nullptr) ? fptr(sensorHandle, bias) : false;
561 }
562 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3 */
563
564 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3
565 WEAK_SYMBOL
chreSensorFlushAsync(uint32_t sensorHandle,const void * cookie)566 bool chreSensorFlushAsync(uint32_t sensorHandle, const void *cookie) {
567 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSensorFlushAsync);
568 return (fptr != nullptr) ? fptr(sensorHandle, cookie) : false;
569 }
570 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3 */
571
572 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_4
573 WEAK_SYMBOL
chreConfigureDebugDumpEvent(bool enable)574 void chreConfigureDebugDumpEvent(bool enable) {
575 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreConfigureDebugDumpEvent);
576 if (fptr != nullptr) {
577 fptr(enable);
578 }
579 }
580 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_4 */
581
582 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_4
583 WEAK_SYMBOL
chreDebugDumpLog(const char * formatStr,...)584 void chreDebugDumpLog(const char *formatStr, ...) {
585 auto *fptr = CHRE_NSL_LAZY_LOOKUP(platform_chreDebugDumpVaLog);
586 if (fptr != nullptr) {
587 va_list args;
588 va_start(args, formatStr);
589 fptr(formatStr, args);
590 va_end(args);
591 }
592 }
593 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_4 */
594
595 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5
596 WEAK_SYMBOL
chreSendMessageWithPermissions(void * message,size_t messageSize,uint32_t messageType,uint16_t hostEndpoint,uint32_t messagePermissions,chreMessageFreeFunction * freeCallback)597 bool chreSendMessageWithPermissions(void *message, size_t messageSize,
598 uint32_t messageType, uint16_t hostEndpoint,
599 uint32_t messagePermissions,
600 chreMessageFreeFunction *freeCallback) {
601 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSendMessageWithPermissions);
602 if (fptr != nullptr) {
603 return fptr(message, messageSize, messageType, hostEndpoint,
604 messagePermissions, freeCallback);
605 } else {
606 return chreSendMessageToHostEndpoint(message, messageSize, messageType,
607 hostEndpoint, freeCallback);
608 }
609 }
610 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5 */
611
612 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10
613 WEAK_SYMBOL
chreSendReliableMessageAsync(void * message,size_t messageSize,uint32_t messageType,uint16_t hostEndpoint,uint32_t messagePermissions,chreMessageFreeFunction * freeCallback,const void * cookie)614 bool chreSendReliableMessageAsync(void *message, size_t messageSize,
615 uint32_t messageType, uint16_t hostEndpoint,
616 uint32_t messagePermissions,
617 chreMessageFreeFunction *freeCallback,
618 const void *cookie) {
619 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSendReliableMessageAsync);
620 if (fptr != nullptr) {
621 return fptr(message, messageSize, messageType, hostEndpoint,
622 messagePermissions, freeCallback, cookie);
623 } else {
624 return false;
625 }
626 }
627 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10 */
628
629 // Begin endpoint messaging APIs
630
631 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_11
632 WEAK_SYMBOL
chreMsgGetEndpointInfo(uint64_t hubId,uint64_t endpointId,struct chreMsgEndpointInfo * info)633 bool chreMsgGetEndpointInfo(uint64_t hubId, uint64_t endpointId,
634 struct chreMsgEndpointInfo *info) {
635 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreMsgGetEndpointInfo);
636 return fptr != nullptr ? fptr(hubId, endpointId, info) : false;
637 }
638
639 WEAK_SYMBOL
chreMsgConfigureEndpointReadyEvents(uint64_t hubId,uint64_t endpointId,bool enable)640 bool chreMsgConfigureEndpointReadyEvents(uint64_t hubId, uint64_t endpointId,
641 bool enable) {
642 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreMsgConfigureEndpointReadyEvents);
643 return fptr != nullptr ? fptr(hubId, endpointId, enable) : false;
644 }
645
646 WEAK_SYMBOL
chreMsgConfigureServiceReadyEvents(uint64_t hubId,const char * serviceDescriptor,bool enable)647 bool chreMsgConfigureServiceReadyEvents(uint64_t hubId,
648 const char *serviceDescriptor,
649 bool enable) {
650 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreMsgConfigureServiceReadyEvents);
651 return fptr != nullptr ? fptr(hubId, serviceDescriptor, enable) : false;
652 }
653
654 WEAK_SYMBOL
chreMsgSessionGetInfo(uint16_t sessionId,struct chreMsgSessionInfo * info)655 bool chreMsgSessionGetInfo(uint16_t sessionId,
656 struct chreMsgSessionInfo *info) {
657 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreMsgSessionGetInfo);
658 return fptr != nullptr ? fptr(sessionId, info) : false;
659 }
660
661 WEAK_SYMBOL
chreMsgPublishServices(const struct chreMsgServiceInfo * services,size_t numServices)662 bool chreMsgPublishServices(const struct chreMsgServiceInfo *services,
663 size_t numServices) {
664 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreMsgPublishServices);
665 return fptr != nullptr ? fptr(services, numServices) : false;
666 }
667
668 WEAK_SYMBOL
chreMsgSessionOpenAsync(uint64_t hubId,uint64_t endpointId,const char * serviceDescriptor)669 bool chreMsgSessionOpenAsync(uint64_t hubId, uint64_t endpointId,
670 const char *serviceDescriptor) {
671 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreMsgSessionOpenAsync);
672 return fptr != nullptr ? fptr(hubId, endpointId, serviceDescriptor) : false;
673 }
674
675 WEAK_SYMBOL
chreMsgSessionCloseAsync(uint16_t sessionId)676 bool chreMsgSessionCloseAsync(uint16_t sessionId) {
677 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreMsgSessionCloseAsync);
678 return fptr != nullptr ? fptr(sessionId) : false;
679 }
680
681 WEAK_SYMBOL
chreMsgSend(void * message,size_t messageSize,uint32_t messageType,uint16_t sessionId,uint32_t messagePermissions,chreMessageFreeFunction * freeCallback)682 bool chreMsgSend(void *message, size_t messageSize, uint32_t messageType,
683 uint16_t sessionId, uint32_t messagePermissions,
684 chreMessageFreeFunction *freeCallback) {
685 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreMsgSend);
686 return fptr != nullptr ? fptr(message, messageSize, messageType, sessionId,
687 messagePermissions, freeCallback)
688 : false;
689 }
690 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_11 */
691
692 // End endpoint messaging APIs
693
694 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5
695 WEAK_SYMBOL
chreUserSettingGetState(uint8_t setting)696 int8_t chreUserSettingGetState(uint8_t setting) {
697 int8_t settingState = CHRE_USER_SETTING_STATE_UNKNOWN;
698 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreUserSettingGetState);
699 if (fptr != nullptr) {
700 settingState = fptr(setting);
701 }
702 return settingState;
703 }
704 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5 */
705
706 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5
707 WEAK_SYMBOL
chreUserSettingConfigureEvents(uint8_t setting,bool enable)708 void chreUserSettingConfigureEvents(uint8_t setting, bool enable) {
709 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreUserSettingConfigureEvents);
710 if (fptr != nullptr) {
711 fptr(setting, enable);
712 }
713 }
714 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5 */
715
716 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
717 WEAK_SYMBOL
chreConfigureHostEndpointNotifications(uint16_t hostEndpointId,bool enable)718 bool chreConfigureHostEndpointNotifications(uint16_t hostEndpointId,
719 bool enable) {
720 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreConfigureHostEndpointNotifications);
721 return (fptr != nullptr) ? fptr(hostEndpointId, enable) : false;
722 }
723 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
724
725 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
726 WEAK_SYMBOL
chrePublishRpcServices(struct chreNanoappRpcService * services,size_t numServices)727 bool chrePublishRpcServices(struct chreNanoappRpcService *services,
728 size_t numServices) {
729 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chrePublishRpcServices);
730 return (fptr != nullptr) ? fptr(services, numServices) : false;
731 }
732 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
733
734 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
735 WEAK_SYMBOL
chreGetHostEndpointInfo(uint16_t hostEndpointId,struct chreHostEndpointInfo * info)736 bool chreGetHostEndpointInfo(uint16_t hostEndpointId,
737 struct chreHostEndpointInfo *info) {
738 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetHostEndpointInfo);
739 return (fptr != nullptr) ? fptr(hostEndpointId, info) : false;
740 }
741 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
742
743 // NOTE: The backward compatibility provided by this stub is only needed below
744 // CHRE v1.8 so we check the first API version for the platform against v1.8.
745 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
chreGetNanoappInfoByAppId(uint64_t appId,struct chreNanoappInfo * info)746 bool chreGetNanoappInfoByAppId(uint64_t appId, struct chreNanoappInfo *info) {
747 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetNanoappInfoByAppId);
748 bool success = (fptr != nullptr) ? fptr(appId, info) : false;
749 if (success && chreGetApiVersion() < CHRE_API_VERSION_1_8) {
750 populateChreNanoappInfoPre18(info);
751 }
752 return success;
753 }
754 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8 */
755
756 // NOTE: The backward compatibility provided by this stub is only needed below
757 // CHRE v1.8 so we check the first API version for the platform against v1.8.
758 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
chreGetNanoappInfoByInstanceId(uint32_t instanceId,struct chreNanoappInfo * info)759 bool chreGetNanoappInfoByInstanceId(uint32_t instanceId,
760 struct chreNanoappInfo *info) {
761 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetNanoappInfoByInstanceId);
762 bool success = (fptr != nullptr) ? fptr(instanceId, info) : false;
763 if (success && chreGetApiVersion() < CHRE_API_VERSION_1_8) {
764 populateChreNanoappInfoPre18(info);
765 }
766 return success;
767 }
768 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8 */
769
770 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10
771 WEAK_SYMBOL
chreGetCapabilities()772 uint32_t chreGetCapabilities() {
773 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetCapabilities);
774 return (fptr != nullptr) ? fptr() : CHRE_CAPABILITIES_NONE;
775 }
776 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10 */
777
778 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10
779 WEAK_SYMBOL
chreGetMessageToHostMaxSize()780 uint32_t chreGetMessageToHostMaxSize() {
781 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetMessageToHostMaxSize);
782 return (fptr != nullptr) ? fptr() : CHRE_MESSAGE_TO_HOST_MAX_SIZE;
783 }
784 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10 */
785
786 #endif // !defined(CHRE_NANOAPP_DISABLE_BACKCOMPAT)
787