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 #endif /* CHRE_NANOAPP_USES_BLE */
392
393 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
394 WEAK_SYMBOL
chreConfigureHostSleepStateEvents(bool enable)395 void chreConfigureHostSleepStateEvents(bool enable) {
396 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreConfigureHostSleepStateEvents);
397 if (fptr != nullptr) {
398 fptr(enable);
399 }
400 }
401 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
402
403 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
404 WEAK_SYMBOL
chreIsHostAwake(void)405 bool chreIsHostAwake(void) {
406 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreIsHostAwake);
407 return (fptr != nullptr) ? fptr() : false;
408 }
409 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
410
411 #ifdef CHRE_NANOAPP_USES_GNSS
412
413 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
414 WEAK_SYMBOL
chreGnssConfigurePassiveLocationListener(bool enable)415 bool chreGnssConfigurePassiveLocationListener(bool enable) {
416 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGnssConfigurePassiveLocationListener);
417 return (fptr != nullptr) ? fptr(enable) : false;
418 }
419 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
420
421 #endif /* CHRE_NANOAPP_USES_GNSS */
422
423 #ifdef CHRE_NANOAPP_USES_WIFI
424
425 // NOTE: The backward compatibility provided by this stub is only needed below
426 // CHRE v1.5 so we check the first API version for the platform against v1.5.
427 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5
428 WEAK_SYMBOL
chreWifiRequestScanAsync(const struct chreWifiScanParams * params,const void * cookie)429 bool chreWifiRequestScanAsync(const struct chreWifiScanParams *params,
430 const void *cookie) {
431 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiRequestScanAsync);
432
433 if (fptr == nullptr) {
434 // Should never happen
435 return false;
436 } else if (chreGetApiVersion() < CHRE_API_VERSION_1_5) {
437 const struct chreWifiScanParams legacyParams =
438 chre::translateToLegacyWifiScanParams(params);
439 return fptr(&legacyParams, cookie);
440 } else {
441 return fptr(params, cookie);
442 }
443 }
444 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5 */
445
446 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2
447 WEAK_SYMBOL
chreWifiRequestRangingAsync(const struct chreWifiRangingParams * params,const void * cookie)448 bool chreWifiRequestRangingAsync(const struct chreWifiRangingParams *params,
449 const void *cookie) {
450 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiRequestRangingAsync);
451 return (fptr != nullptr) ? fptr(params, cookie) : false;
452 }
453 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_2 */
454
455 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
456 WEAK_SYMBOL
chreWifiNanRequestRangingAsync(const struct chreWifiNanRangingParams * params,const void * cookie)457 bool chreWifiNanRequestRangingAsync(
458 const struct chreWifiNanRangingParams *params, const void *cookie) {
459 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiNanRequestRangingAsync);
460 return (fptr != nullptr) ? fptr(params, cookie) : false;
461 }
462 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
463
464 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
465 WEAK_SYMBOL
chreWifiNanSubscribe(struct chreWifiNanSubscribeConfig * config,const void * cookie)466 bool chreWifiNanSubscribe(struct chreWifiNanSubscribeConfig *config,
467 const void *cookie) {
468 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiNanSubscribe);
469 return (fptr != nullptr) ? fptr(config, cookie) : false;
470 }
471 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
472
473 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
474 WEAK_SYMBOL
chreWifiNanSubscribeCancel(uint32_t subscriptionID)475 bool chreWifiNanSubscribeCancel(uint32_t subscriptionID) {
476 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreWifiNanSubscribeCancel);
477 return (fptr != nullptr) ? fptr(subscriptionID) : false;
478 }
479 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
480
481 #endif /* CHRE_NANOAPP_USES_WIFI */
482
483 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5
484 WEAK_SYMBOL
chreSensorFind(uint8_t sensorType,uint8_t sensorIndex,uint32_t * handle)485 bool chreSensorFind(uint8_t sensorType, uint8_t sensorIndex, uint32_t *handle) {
486 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSensorFind);
487 if (fptr != nullptr) {
488 return fptr(sensorType, sensorIndex, handle);
489 } else if (sensorIndex == 0) {
490 return chreSensorFindDefault(sensorType, handle);
491 } else {
492 return false;
493 }
494 }
495 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5 */
496
497 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3
498 WEAK_SYMBOL
chreSensorConfigureBiasEvents(uint32_t sensorHandle,bool enable)499 bool chreSensorConfigureBiasEvents(uint32_t sensorHandle, bool enable) {
500 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSensorConfigureBiasEvents);
501 return (fptr != nullptr) ? fptr(sensorHandle, enable) : false;
502 }
503 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3 */
504
505 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3
506 WEAK_SYMBOL
chreSensorGetThreeAxisBias(uint32_t sensorHandle,struct chreSensorThreeAxisData * bias)507 bool chreSensorGetThreeAxisBias(uint32_t sensorHandle,
508 struct chreSensorThreeAxisData *bias) {
509 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSensorGetThreeAxisBias);
510 return (fptr != nullptr) ? fptr(sensorHandle, bias) : false;
511 }
512 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3 */
513
514 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3
515 WEAK_SYMBOL
chreSensorFlushAsync(uint32_t sensorHandle,const void * cookie)516 bool chreSensorFlushAsync(uint32_t sensorHandle, const void *cookie) {
517 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSensorFlushAsync);
518 return (fptr != nullptr) ? fptr(sensorHandle, cookie) : false;
519 }
520 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_3 */
521
522 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_4
523 WEAK_SYMBOL
chreConfigureDebugDumpEvent(bool enable)524 void chreConfigureDebugDumpEvent(bool enable) {
525 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreConfigureDebugDumpEvent);
526 if (fptr != nullptr) {
527 fptr(enable);
528 }
529 }
530 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_4 */
531
532 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_4
533 WEAK_SYMBOL
chreDebugDumpLog(const char * formatStr,...)534 void chreDebugDumpLog(const char *formatStr, ...) {
535 auto *fptr = CHRE_NSL_LAZY_LOOKUP(platform_chreDebugDumpVaLog);
536 if (fptr != nullptr) {
537 va_list args;
538 va_start(args, formatStr);
539 fptr(formatStr, args);
540 va_end(args);
541 }
542 }
543 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_4 */
544
545 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5
546 WEAK_SYMBOL
chreSendMessageWithPermissions(void * message,size_t messageSize,uint32_t messageType,uint16_t hostEndpoint,uint32_t messagePermissions,chreMessageFreeFunction * freeCallback)547 bool chreSendMessageWithPermissions(void *message, size_t messageSize,
548 uint32_t messageType, uint16_t hostEndpoint,
549 uint32_t messagePermissions,
550 chreMessageFreeFunction *freeCallback) {
551 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSendMessageWithPermissions);
552 if (fptr != nullptr) {
553 return fptr(message, messageSize, messageType, hostEndpoint,
554 messagePermissions, freeCallback);
555 } else {
556 return chreSendMessageToHostEndpoint(message, messageSize, messageType,
557 hostEndpoint, freeCallback);
558 }
559 }
560 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5 */
561
562 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10
563 WEAK_SYMBOL
chreSendReliableMessageAsync(void * message,size_t messageSize,uint32_t messageType,uint16_t hostEndpoint,uint32_t messagePermissions,chreMessageFreeFunction * freeCallback,const void * cookie)564 bool chreSendReliableMessageAsync(void *message, size_t messageSize,
565 uint32_t messageType, uint16_t hostEndpoint,
566 uint32_t messagePermissions,
567 chreMessageFreeFunction *freeCallback,
568 const void *cookie) {
569 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreSendReliableMessageAsync);
570 if (fptr != nullptr) {
571 return fptr(message, messageSize, messageType, hostEndpoint,
572 messagePermissions, freeCallback, cookie);
573 } else {
574 return false;
575 }
576 }
577 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10 */
578
579 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5
580 WEAK_SYMBOL
chreUserSettingGetState(uint8_t setting)581 int8_t chreUserSettingGetState(uint8_t setting) {
582 int8_t settingState = CHRE_USER_SETTING_STATE_UNKNOWN;
583 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreUserSettingGetState);
584 if (fptr != nullptr) {
585 settingState = fptr(setting);
586 }
587 return settingState;
588 }
589 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5 */
590
591 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5
592 WEAK_SYMBOL
chreUserSettingConfigureEvents(uint8_t setting,bool enable)593 void chreUserSettingConfigureEvents(uint8_t setting, bool enable) {
594 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreUserSettingConfigureEvents);
595 if (fptr != nullptr) {
596 fptr(setting, enable);
597 }
598 }
599 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_5 */
600
601 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
602 WEAK_SYMBOL
chreConfigureHostEndpointNotifications(uint16_t hostEndpointId,bool enable)603 bool chreConfigureHostEndpointNotifications(uint16_t hostEndpointId,
604 bool enable) {
605 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreConfigureHostEndpointNotifications);
606 return (fptr != nullptr) ? fptr(hostEndpointId, enable) : false;
607 }
608 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
609
610 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
611 WEAK_SYMBOL
chrePublishRpcServices(struct chreNanoappRpcService * services,size_t numServices)612 bool chrePublishRpcServices(struct chreNanoappRpcService *services,
613 size_t numServices) {
614 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chrePublishRpcServices);
615 return (fptr != nullptr) ? fptr(services, numServices) : false;
616 }
617 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
618
619 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6
620 WEAK_SYMBOL
chreGetHostEndpointInfo(uint16_t hostEndpointId,struct chreHostEndpointInfo * info)621 bool chreGetHostEndpointInfo(uint16_t hostEndpointId,
622 struct chreHostEndpointInfo *info) {
623 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetHostEndpointInfo);
624 return (fptr != nullptr) ? fptr(hostEndpointId, info) : false;
625 }
626 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_6 */
627
628 // NOTE: The backward compatibility provided by this stub is only needed below
629 // CHRE v1.8 so we check the first API version for the platform against v1.8.
630 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
chreGetNanoappInfoByAppId(uint64_t appId,struct chreNanoappInfo * info)631 bool chreGetNanoappInfoByAppId(uint64_t appId, struct chreNanoappInfo *info) {
632 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetNanoappInfoByAppId);
633 bool success = (fptr != nullptr) ? fptr(appId, info) : false;
634 if (success && chreGetApiVersion() < CHRE_API_VERSION_1_8) {
635 populateChreNanoappInfoPre18(info);
636 }
637 return success;
638 }
639 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8 */
640
641 // NOTE: The backward compatibility provided by this stub is only needed below
642 // CHRE v1.8 so we check the first API version for the platform against v1.8.
643 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8
chreGetNanoappInfoByInstanceId(uint32_t instanceId,struct chreNanoappInfo * info)644 bool chreGetNanoappInfoByInstanceId(uint32_t instanceId,
645 struct chreNanoappInfo *info) {
646 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetNanoappInfoByInstanceId);
647 bool success = (fptr != nullptr) ? fptr(instanceId, info) : false;
648 if (success && chreGetApiVersion() < CHRE_API_VERSION_1_8) {
649 populateChreNanoappInfoPre18(info);
650 }
651 return success;
652 }
653 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_8 */
654
655 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10
656 WEAK_SYMBOL
chreGetCapabilities()657 uint32_t chreGetCapabilities() {
658 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetCapabilities);
659 return (fptr != nullptr) ? fptr() : CHRE_CAPABILITIES_NONE;
660 }
661 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10 */
662
663 #if CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10
664 WEAK_SYMBOL
chreGetMessageToHostMaxSize()665 uint32_t chreGetMessageToHostMaxSize() {
666 auto *fptr = CHRE_NSL_LAZY_LOOKUP(chreGetMessageToHostMaxSize);
667 return (fptr != nullptr) ? fptr() : CHRE_MESSAGE_TO_HOST_MAX_SIZE;
668 }
669 #endif /* CHRE_FIRST_SUPPORTED_API_VERSION < CHRE_API_VERSION_1_10 */
670
671 #endif // !defined(CHRE_NANOAPP_DISABLE_BACKCOMPAT)
672