Merge 25Q1 (ab/BP1A.250305.020) to AOSP main Bug: 385190204 Merged-In: If22ba92978ec7e408a4c494421cec1ac2df4e03c Change-Id: Ie9ee25cc7769222deba27ed993933d11cabf86b5
diff --git a/Android.bp b/Android.bp index 78a78ca..49fe6f1 100644 --- a/Android.bp +++ b/Android.bp
@@ -56,6 +56,72 @@ ], } +filegroup { + name: "contexthub_hal_common_srcs", + srcs: [ + "host/common/file_stream.cc", + "host/common/fragmented_load_transaction.cc", + "host/common/host_protocol_host.cc", + "host/common/log.cc", + "host/hal_generic/common/context_hub_v4_impl.cc", + "host/hal_generic/common/message_hub_manager.cc", + "platform/shared/host_protocol_common.cc", + ], +} + +filegroup { + name: "contexthub_hal_client_srcs", + srcs: [ + "host/common/hal_client.cc", + "host/common/pigweed/hal_channel_output.cc", + "host/common/pigweed/hal_rpc_client.cc", + "host/common/socket_client.cc", + ], +} + +cc_defaults { + name: "contexthub_hal_defaults", + vendor: true, + srcs: [":contexthub_hal_common_srcs"], + include_dirs: [ + "system/chre/host/common/include/", + "system/chre/host/hal_generic/aidl/", + "system/chre/host/hal_generic/common/", + "system/chre/platform/shared/include/", + "system/chre/util/include/", + ], + header_libs: [ + "chre_api", + "chre_flatbuffers", + ], + shared_libs: [ + "android.frameworks.stats-V2-ndk", + "android.hardware.contexthub-V4-ndk", + "chre_atoms_log", + "chremetrics-cpp", + "libaconfig_storage_read_api_cc", + "libbase", + "libbinder_ndk", + "libcutils", + "libjsoncpp", + "liblog", + "libprotobuf-cpp-lite", + "libutils", + "server_configurable_flags", + ], + static_libs: [ + "chre_flags_c_lib", + "chre_metrics_reporter", + "event_logger", + ], + cflags: [ + "-DCHRE_IS_HOST_BUILD", + "-DCHRE_MESSAGE_TO_HOST_MAX_SIZE=4000", // Needed to import CHRE APIs + "-Wall", + "-Werror", + ], +} + cc_library_static { name: "chre_client", vendor_available: true, @@ -469,7 +535,7 @@ "util/include", ], shared_libs: [ - "android.hardware.contexthub-V3-ndk", + "android.hardware.contexthub-V4-ndk", "libcutils", "libutils", ], @@ -528,7 +594,7 @@ "util/include/", ], static_libs: [ - "android.hardware.contexthub-V3-ndk", + "android.hardware.contexthub-V4-ndk", "chre_flags_c_lib", "chre_host_common", "event_logger", @@ -537,7 +603,7 @@ ], shared_libs: [ "android.frameworks.stats-V2-ndk", - "android.hardware.contexthub-V3-ndk", + "android.hardware.contexthub-V4-ndk", "chre_atoms_log", "libaconfig_storage_read_api_cc", "libbase", @@ -715,20 +781,17 @@ "platform/shared/pw_trace/include", "util/include", ], - cflags: [ - "-DCHRE_ASSERTIONS_ENABLED=true", - "-DCHRE_BLE_SUPPORT_ENABLED=true", - "-DCHRE_FILENAME=__FILE__", - "-DCHRE_MESSAGE_TO_HOST_MAX_SIZE=4096", - "-DCHRE_MINIMUM_LOG_LEVEL=CHRE_LOG_LEVEL_DEBUG", - "-DGTEST", - ], header_libs: [ "chre_flatbuffers", ], static_libs: [ "chre_linux", "libgmock", + "pw_allocator", + "pw_containers", + ], + defaults: [ + "chre_linux_cflags", ], sanitize: { address: true, @@ -749,27 +812,55 @@ // Lib dependencies for apps and libs using PW_RPC with nanopb. cc_defaults { name: "pw_rpc_nanopb_lib_dependencies", - defaults: [ - "pw_android_common_backends", - ], static_libs: [ + "pw_assert_log", + "pw_chrono_stl", "pw_containers", + "pw_log_android", "pw_protobuf", "pw_rpc_chre", "pw_rpc_nanopb_chre", "pw_status", "pw_stream", + "pw_sync_stl", + "pw_thread_stl", "pw_varint", ], + export_static_lib_headers: [ + "pw_assert_log", + "pw_chrono_stl", + "pw_log_android", + "pw_sync_stl", + "pw_thread_stl", + ], + shared_libs: [ + "liblog", + ], } cc_library_static { name: "pw_rpc_chre", defaults: [ - "pw_android_common_backends", "pw_rpc_cflags_chre", "pw_rpc_defaults", ], + static_libs: [ + "pw_assert_log", + "pw_chrono_stl", + "pw_log_android", + "pw_sync_stl", + "pw_thread_stl", + ], + export_static_lib_headers: [ + "pw_assert_log", + "pw_chrono_stl", + "pw_log_android", + "pw_sync_stl", + "pw_thread_stl", + ], + shared_libs: [ + "liblog", + ], host_supported: true, vendor_available: true, } @@ -857,12 +948,19 @@ ], local_include_dirs: [ "platform/shared", + "platform/shared/public_platform_ble_pal", + "platform/shared/public_platform_debug_dump_manager", + "platform/shared/public_platform_gnss_pal", + "platform/shared/public_platform_wifi_pal", + "platform/shared/public_platform_wwan_pal", "test/simulation/inc", ], static_libs: [ "chre_linux", "chre_pal_linux", "libprotobuf-c-nano", + "pw_allocator", + "pw_containers", ], defaults: [ "chre_linux_cflags", @@ -882,6 +980,7 @@ "core/ble_request.cc", "core/ble_request_manager.cc", "core/ble_request_multiplexer.cc", + "core/chre_message_hub_manager.cc", "core/debug_dump_manager.cc", "core/event.cc", "core/event_loop.cc", @@ -960,6 +1059,11 @@ "platform/linux/include", "platform/shared/audio_pal/include", "platform/shared/include", + "platform/shared/public_platform_ble_pal", + "platform/shared/public_platform_debug_dump_manager", + "platform/shared/public_platform_gnss_pal", + "platform/shared/public_platform_wifi_pal", + "platform/shared/public_platform_wwan_pal", "platform/shared/sensor_pal/include", "util/include", ], @@ -974,6 +1078,7 @@ static_libs: [ "libgmock", "libgtest", + "pw_allocator", "pw_rpc_chre", ], host_supported: true, @@ -989,8 +1094,10 @@ "-DCHRE_FIRST_SUPPORTED_API_VERSION=CHRE_API_VERSION_1_1", "-DCHRE_GNSS_SUPPORT_ENABLED", "-DCHRE_LARGE_PAYLOAD_MAX_SIZE=32000", + "-DCHRE_MESSAGE_ROUTER_SUPPORT_ENABLED", "-DCHRE_MESSAGE_TO_HOST_MAX_SIZE=4096", "-DCHRE_MINIMUM_LOG_LEVEL=CHRE_LOG_LEVEL_DEBUG", + "-DCHRE_PLATFORM_ID=1", "-DCHRE_RELIABLE_MESSAGE_SUPPORT_ENABLED", "-DCHRE_SENSORS_SUPPORT_ENABLED", "-DCHRE_TEST_ASYNC_RESULT_TIMEOUT_NS=300000000",
diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c43fb9d --- /dev/null +++ b/CMakeLists.txt
@@ -0,0 +1,23 @@ +include($ENV{PW_ROOT}/pw_build/pigweed.cmake) + +add_subdirectory(chre_api) +add_subdirectory(core) +add_subdirectory(pal) +add_subdirectory(platform) +add_subdirectory(util) +add_subdirectory(variant) + +include($ENV{PW_ROOT}/pw_build/pigweed.cmake) + +if(NOT chre_third_party_flatbuffers_LIBRARY) + pw_add_error_target(chre_third_party.flatbuffers + MESSAGE + "Attempted to build chre_third_party.flatbuffers without configuring it " + "via chre_third_party_flatbuffers_LIBRARY." + ) +else() + pw_add_library(chre_third_party.flatbuffers INTERFACE + PUBLIC_DEPS + "${chre_third_party_flatbuffers_LIBRARY}" + ) +endif()
diff --git a/apps/ble_world/ble_world.cc b/apps/ble_world/ble_world.cc index 9251d87..19b1df5 100644 --- a/apps/ble_world/ble_world.cc +++ b/apps/ble_world/ble_world.cc
@@ -23,6 +23,7 @@ #define BLE_FILTER_TYPE_SERVICE_DATA 0 #define BLE_FILTER_TYPE_MANUFACTURER_DATA 1 +#define BLE_FILTER_TYPE_BROADCASTER_ADDRESS 2 /** * @file @@ -42,8 +43,9 @@ * * The BLE scanning test can also be configured by filter type. By default, the * test will filter by service data, but it can be modified to filter by - * manufacturer data by setting the BLE_FILTER_TYPE flag to - * BLE_FILTER_TYPE_MANUFACTURER_DATA. It is recommended to use an app that can + * manufacturer data or broadcaster address by setting the BLE_FILTER_TYPE flag + * to either BLE_FILTER_TYPE_MANUFACTURER_DATA or + * BLE_FILTER_TYPE_BROADCASTER_ADDRESS. It is recommended to use an app that can * create advertisers corresponding to the filters to do the tests. */ @@ -52,6 +54,7 @@ namespace { #endif // CHRE_NANOAPP_INTERNAL +using chre::ble_constants::kNumBroadcasterFilters; using chre::ble_constants::kNumManufacturerDataFilters; using chre::ble_constants::kNumScanFilters; @@ -96,6 +99,12 @@ LOGE("BLE manufacturer data filters are not supported"); return false; } +#elif BLE_FILTER_TYPE == BLE_FILTER_TYPE_BROADCASTER_ADDRESS + if ((filterCapabilities & CHRE_BLE_FILTER_CAPABILITIES_BROADCASTER_ADDRESS) == + 0) { + LOGE("BLE broadcaster address filters are not supported"); + return false; + } #else if ((filterCapabilities & CHRE_BLE_FILTER_CAPABILITIES_SERVICE_DATA) == 0) { LOGE("BLE service data filters are not supported"); @@ -111,10 +120,18 @@ chreBleGenericFilter genericFilters[kNumManufacturerDataFilters]; chre::createBleManufacturerDataFilter(kNumManufacturerDataFilters, genericFilters, filter); +#elif BLE_FILTER_TYPE == BLE_FILTER_TYPE_BROADCASTER_ADDRESS + chreBleBroadcasterAddressFilter broadcasterFilters[kNumBroadcasterFilters]; + if (!chre::createBleScanFilterForAdvertiser(filter, broadcasterFilters, + kNumBroadcasterFilters)) { + LOGE("Failed to create BLE scan filters for known beacons and advertiser"); + } #else chreBleGenericFilter genericFilters[kNumScanFilters]; - chre::createBleScanFilterForKnownBeaconsV1_9(filter, genericFilters, - kNumScanFilters); + if (!chre::createBleScanFilterForKnownBeaconsV1_9(filter, genericFilters, + kNumScanFilters)) { + LOGE("Failed to create BLE scan filters for known beacons"); + } #endif return chreBleStartScanAsyncV1_9(CHRE_BLE_SCAN_MODE_BACKGROUND, gBleBatchDurationMs, &filter, &kScanCookie); @@ -181,26 +198,27 @@ return static_cast<uint16_t>(data[0] + (data[1] << 8)); } -void parseAdData(const uint8_t *data, uint16_t size) { - for (uint16_t i = 0; i < size;) { - // First byte has the dvertisement data length. - uint16_t adDataLength = data[i]; +void parseReport(const chreBleAdvertisingReport *report) { + for (uint16_t i = 0; i < report->dataLength;) { + // First byte has the advertisement data length. + uint16_t adDataLength = report->data[i]; // Early termination with zero length advertisement. if (adDataLength == 0) break; + // Log 2 byte UUIDs for service data or manufacturer data AD types. if (adDataLength < kUuidLengthInBytes) { i += adDataLength + 1; continue; } - uint8_t adDataType = data[++i]; + uint8_t adDataType = report->data[++i]; switch (adDataType) { case kDataTypeServiceData: LOGD("Service Data UUID: %" PRIx16, - getUuidInLittleEndian(&data[i + 1])); + getUuidInLittleEndian(&report->data[i + 1])); break; case kDataTypeManufacturerData: LOGD("Manufacturer Data UUID: %" PRIx16, - getUuidInLittleEndian(&data[i + 1])); + getUuidInLittleEndian(&report->data[i + 1])); break; default: break; @@ -208,6 +226,14 @@ // Moves to next advertisement. i += adDataLength; } + LOGD("application address type 0x%" PRIx8, report->addressType); + LOGD("address=%02X:%02X:%02X:%02X:%02X:%02X", report->address[0], + report->address[1], report->address[2], report->address[3], + report->address[4], report->address[5]); + LOGD("direct address=%02X:%02X:%02X:%02X:%02X:%02X", report->directAddress[0], + report->directAddress[1], report->directAddress[2], + report->directAddress[3], report->directAddress[4], + report->directAddress[5]); } void handleAsyncResultEvent(const chreAsyncResult *result) { @@ -229,7 +255,7 @@ event->reports[i].eventTypeAndDataStatus); LOGD("Timestamp: %" PRIu64 " ms", event->reports[i].timestamp / chre::kOneMillisecondInNanoseconds); - parseAdData(event->reports[i].data, event->reports[i].dataLength); + parseReport(&event->reports[i]); } }
diff --git a/apps/message_world/message_world.cc b/apps/message_world/message_world.cc index 17c910e..b1495e7 100644 --- a/apps/message_world/message_world.cc +++ b/apps/message_world/message_world.cc
@@ -16,6 +16,7 @@ #include <cinttypes> +#include "chre/util/macros.h" #include "chre/util/nanoapp/log.h" #include "chre_api/chre.h" @@ -28,17 +29,21 @@ namespace { -constexpr uint32_t kMessageType = 1234; -uint8_t gMessageData[CHRE_MESSAGE_TO_HOST_MAX_SIZE] = {1, 2, 3, 4, 5, 6, 7, 8}; +enum MessageType { kDefault = 1, kCustomReplyMessageSize = 2 }; + +#ifdef CHRE_RELIABLE_MESSAGE_SUPPORT_ENABLED +constexpr uint32_t gMaxReplyMessageSize = CHRE_LARGE_PAYLOAD_MAX_SIZE; +#else +constexpr uint32_t gMaxReplyMessageSize = CHRE_MESSAGE_TO_HOST_MAX_SIZE; +#endif + +uint8_t gMessageData[gMaxReplyMessageSize] = {}; void messageFreeCallback(void *message, size_t messageSize) { - LOGI( - "Got message free callback for message @ %p (match? %d) size %zu (match?" - " %d)", - message, (message == gMessageData), messageSize, - (messageSize == sizeof(gMessageData))); - if (!chreSendEvent(CHRE_EVENT_FIRST_USER_VALUE, nullptr, nullptr, - chreGetInstanceId())) { + LOGI("Got message free callback for message @ %p (%s) size %zu", message, + (message == gMessageData) ? "matched" : "unmatched", messageSize); + if (!chreSendEvent(CHRE_EVENT_FIRST_USER_VALUE, /* eventData= */ nullptr, + /* freeCallback= */ nullptr, chreGetInstanceId())) { LOGE("Failed to send event"); } } @@ -47,31 +52,43 @@ bool nanoappStart() { LOGI("App started as instance %" PRIu32, chreGetInstanceId()); - + // initialize gMessageData + for (uint32_t i = 0; i < gMaxReplyMessageSize; ++i) { + gMessageData[i] = i % 10; + } bool success = chreSendMessageToHostEndpoint( - gMessageData, sizeof(gMessageData), kMessageType, + gMessageData, sizeof(gMessageData), MessageType::kDefault, CHRE_HOST_ENDPOINT_BROADCAST, messageFreeCallback); - LOGI("Sent message to host from start callback, result %d", success); + LOGI("Sent message of size %zu to host from start callback: %s", + sizeof(gMessageData), success ? "success" : "failure"); return true; } void nanoappHandleEvent(uint32_t senderInstanceId, uint16_t eventType, const void *eventData) { - if (eventType == CHRE_EVENT_MESSAGE_FROM_HOST) { - auto *msg = static_cast<const chreMessageFromHostData *>(eventData); - LOGI("Got message from host with type %" PRIu32 " size %" PRIu32 - " data @ %p hostEndpoint 0x%" PRIx16, - msg->messageType, msg->messageSize, msg->message, msg->hostEndpoint); - if (senderInstanceId != CHRE_INSTANCE_ID) { - LOGE("Message from host came from unexpected instance ID %" PRIu32, - senderInstanceId); - } - - bool success = chreSendMessageToHostEndpoint( - gMessageData, sizeof(gMessageData), kMessageType, - CHRE_HOST_ENDPOINT_BROADCAST, messageFreeCallback); - LOGI("Result of sending reply: %d", success); + if (eventType != CHRE_EVENT_MESSAGE_FROM_HOST) { + return; } + auto *msg = static_cast<const chreMessageFromHostData *>(eventData); + LOGI("Got message from host with type %" PRIu32 " size %" PRIu32 + " data @ %p hostEndpoint 0x%" PRIx16, + msg->messageType, msg->messageSize, msg->message, msg->hostEndpoint); + if (senderInstanceId != CHRE_INSTANCE_ID) { + LOGE("Message from host came from unexpected instance ID %" PRIu32, + senderInstanceId); + } + + uint32_t messageSize = gMaxReplyMessageSize; + if (msg->messageType == MessageType::kCustomReplyMessageSize) { + messageSize = + MIN(messageSize, *(static_cast<const uint32_t *>(msg->message))); + } + + bool success = chreSendMessageToHostEndpoint( + gMessageData, messageSize, MessageType::kDefault, msg->hostEndpoint, + messageFreeCallback); + LOGI("Result of sending reply (size=%" PRIu32 "): %s", messageSize, + success ? "success" : "failure"); } void nanoappEnd() {
diff --git a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/app_manager.cc b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/app_manager.cc index e99c4ea..00dd161 100644 --- a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/app_manager.cc +++ b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/app_manager.cc
@@ -114,9 +114,7 @@ HandleMatchAdvReports(adv_reports_cache_); break; case CHRE_EVENT_TIMER: - if (event_data == &ble_scan_keep_alive_timer_id) { - tracker_storage_.Refresh(tracker_filter_.GetBatchConfig()); - } + HandleTimerEvent(event_data); break; case CHRE_EVENT_HOST_AWAKE: HandleHostAwakeEvent(); @@ -213,7 +211,8 @@ } void AppManager::UpdateBleScanState() { - if (!filter_.IsEmpty() || !tracker_filter_.IsEmpty() || + if (!filter_.IsEmpty() || + (!tracker_filter_.IsEmpty() && tracker_filter_.IsActive()) || !filter_extension_.IsEmpty()) { ble_scanner_.Restart(); } else { @@ -631,12 +630,42 @@ chre::kOneMillisecondInNanoseconds; if (current_time - last_tracker_report_flush_time_nanosec_ >= flush_threshold_nanosec) { - LOGI("Flush tracker reports by host awake event."); + LOGD("Flush tracker reports by host awake event."); SendTrackerReportsToHost(tracker_storage_.GetBatchReports()); tracker_storage_.Clear(); } } +void AppManager::HandleTimerEvent(const void *event_data) { + if (event_data == &ble_scan_keep_alive_timer_id) { + tracker_storage_.Refresh(tracker_filter_.GetBatchConfig()); + } else if (event_data == + tracker_filter_.GetActiveIntervalTimer().GetTimerId()) { + // When receive the active interval timer event, set the active state for + // tracker scan filter, start the oneshot active window timer, and set the + // tracker scan filters from the BLE scanner. Then update the BLE scan state + // so that the tracker scan can start properly. The tracker scan will stop + // when receive the oneshot active window timer event. + tracker_filter_.SetActiveState(); + tracker_filter_.GetActiveWindowTimer().StartTimer(); + ble_scanner_.SetTrackerFilters(); + UpdateBleScanState(); + } else if (event_data == + tracker_filter_.GetActiveWindowTimer().GetTimerId()) { + // When receive the active window timer event, clear the active state for + // tracker scan filter, clear the tracker scan filters from the BLE scanner, + // and update the BLE scan state so that the tracker scan can stop properly. + // The tracker scan will restart when receive the next active interval timer + // event. If the tracker filter is empty, no action is needed as the tracker + // scan has completely stopped at this point. + if (!tracker_filter_.IsEmpty()) { + tracker_filter_.ClearActiveState(); + ble_scanner_.ClearTrackerFilters(); + UpdateBleScanState(); + } + } +} + void AppManager::OnTrackerStorageFullEvent() { SendTrackerStorageFullEventToHost(); } @@ -651,6 +680,12 @@ return false; } ble_scanner_.UpdateTrackerFilters(generic_filters); + // Set or clear tracker scan filter state before updating BLE scan state. + if (tracker_filter_.IsEmpty()) { + ble_scanner_.ClearTrackerFilters(); + } else { + ble_scanner_.SetTrackerFilters(); + } UpdateBleScanState(); // Send tracker reports to host before clearing the tracker storage if the // host stops the tracker filter.
diff --git a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/app_manager.h b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/app_manager.h index 2d74be8..bd324a8 100644 --- a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/app_manager.h +++ b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/app_manager.h
@@ -125,6 +125,9 @@ // Handles host awake event. void HandleHostAwakeEvent(); + // Handles timer event. + void HandleTimerEvent(const void *event_data); + // Handles tracker filter config request from the host. bool HandleExtTrackerFilterConfig( const chreHostEndpointInfo &host_info,
diff --git a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/ble_scanner.cc b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/ble_scanner.cc index 3727a17..27db465 100644 --- a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/ble_scanner.cc +++ b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/ble_scanner.cc
@@ -213,9 +213,11 @@ generic_filters.push_back(kDefaultGenericFilters[i]); } } - for (auto &tracker_filter : tracker_filters_) { - if (!ContainsFilter(generic_filters, tracker_filter)) { - generic_filters.push_back(tracker_filter); + if (is_tracker_filter_enabled_) { + for (auto &tracker_filter : tracker_filters_) { + if (!ContainsFilter(generic_filters, tracker_filter)) { + generic_filters.push_back(tracker_filter); + } } } for (auto &oem_generic_filters : generic_filters_list_) { @@ -253,7 +255,9 @@ } else { LOGE("Failed to stop BLE scan"); } - StopKeepAliveTimer(); + if (tracker_filters_.empty()) { + StopKeepAliveTimer(); + } } bool BleScanner::UpdateFilters(
diff --git a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/ble_scanner.h b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/ble_scanner.h index 7418ef1..af2f45f 100644 --- a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/ble_scanner.h +++ b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/ble_scanner.h
@@ -115,6 +115,16 @@ is_default_generic_filter_enabled_ = false; } + // Sets tracker filters. + void SetTrackerFilters() { + is_tracker_filter_enabled_ = true; + } + + // Clears tracker filters. + void ClearTrackerFilters() { + is_tracker_filter_enabled_ = false; + } + // Returns whether the filter list contains the given filter. bool ContainsFilter(const chre::DynamicVector<chreBleGenericFilter> &filters, const chreBleGenericFilter &src); @@ -146,6 +156,9 @@ // Whether default generic filter is enabled. bool is_default_generic_filter_enabled_ = false; + // Whether tracker filter is enabled. + bool is_tracker_filter_enabled_ = false; + // Current report delay for BLE batch scan uint32_t report_delay_ms_ = 0;
diff --git a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/proto/nearby_extension.proto b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/proto/nearby_extension.proto index 873388a..b0d9bd1 100644 --- a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/proto/nearby_extension.proto +++ b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/proto/nearby_extension.proto
@@ -115,6 +115,19 @@ // disables the opportunistic flush. optional uint32 opportunistic_flush_threshold_time_ms = 8 [default = 4294967295]; + + // Active interval for tracker scan filter. The tracker scan filter is + // enabled at the beginning of the active interval and disabled at the end + // of the active window. This creates a toggle effect for the tracker scan + // filter and reduces the BLE scan power consumption. If the interval and + // window are not set by host, the default values are 0, and the tracker + // scan filter is always enabled. + // The active interval must be greater than the active window so that the + // scan toggling can function properly. + optional uint32 active_interval_ms = 9 [default = 0]; + + // Active window for tracker scan filter. + optional uint32 active_window_ms = 10 [default = 0]; } message FlushTrackerReports {}
diff --git a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/timer.cc b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/timer.cc new file mode 100644 index 0000000..ee857ed --- /dev/null +++ b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/timer.cc
@@ -0,0 +1,61 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "location/lbs/contexthub/nanoapps/nearby/timer.h" + +#include <chre.h> + +#include "third_party/contexthub/chre/util/include/chre/util/nanoapp/log.h" +#include "third_party/contexthub/chre/util/include/chre/util/time.h" + +#define LOG_TAG "[NEARBY][TIMER]" + +namespace nearby { + +bool Timer::StartTimer() { + if (duration_ms_ == 0) { + LOGD("Timer is not started. Timer duration is 0."); + return false; + } + if (!is_one_shot_ && timer_id_ != CHRE_TIMER_INVALID) { + chreTimerCancel(timer_id_); + timer_id_ = CHRE_TIMER_INVALID; + } + timer_id_ = chreTimerSet(duration_ms_ * chre::kOneMillisecondInNanoseconds, + &timer_id_, /*oneShot=*/is_one_shot_); + if (timer_id_ == CHRE_TIMER_INVALID) { + LOGE("Error in configuring timer."); + return false; + } + return true; +} + +bool Timer::StopTimer() { + if (timer_id_ == CHRE_TIMER_INVALID) { + LOGD("Timer is already stopped."); + return false; + } + if (!chreTimerCancel(timer_id_)) { + LOGW( + "Error in stopping timer. For a one-shot timer, it may have just " + "fired or expired."); + return false; + } + timer_id_ = CHRE_TIMER_INVALID; + return true; +} + +} // namespace nearby
diff --git a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/timer.h b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/timer.h new file mode 100644 index 0000000..600ed9f --- /dev/null +++ b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/timer.h
@@ -0,0 +1,55 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LOCATION_LBS_CONTEXTHUB_NANOAPPS_NEARBY_TIMER_H_ +#define LOCATION_LBS_CONTEXTHUB_NANOAPPS_NEARBY_TIMER_H_ + +#include <cstdint> + +#include "chre_api/chre.h" + +namespace nearby { + +class Timer { + public: + // Constructs timer. + explicit Timer(bool is_one_shot) : is_one_shot_(is_one_shot) {} + + // Sets timer duration in milliseconds. + void SetDurationMs(uint32_t duration_ms) { + duration_ms_ = duration_ms; + } + + // Starts timer. + bool StartTimer(); + + // Stops timer. + bool StopTimer(); + + // Returns timer id. + const uint32_t *GetTimerId() { + return &timer_id_; + } + + private: + uint32_t timer_id_ = CHRE_TIMER_INVALID; + uint32_t duration_ms_ = 0; + bool is_one_shot_; +}; + +} // namespace nearby + +#endif // LOCATION_LBS_CONTEXTHUB_NANOAPPS_NEARBY_TIMER_H_
diff --git a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/tracker_filter.cc b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/tracker_filter.cc index e072b7a..3dbf1fd 100644 --- a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/tracker_filter.cc +++ b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/tracker_filter.cc
@@ -1,5 +1,6 @@ #include "location/lbs/contexthub/nanoapps/nearby/tracker_filter.h" +#include <inttypes.h> #include <cstddef> #include <cstdint> #include <cstring> @@ -51,6 +52,10 @@ } scan_filter_config_.hardware_filters = std::move(hardware_filters); scan_filter_config_.rssi_threshold = filter_config.rssi_threshold; + scan_filter_config_.active_interval_ms = filter_config.active_interval_ms; + scan_filter_config_.active_window_ms = filter_config.active_window_ms; + ConfigureActiveState(); + ConfigureScanControlTimers(); // Sets batch configuration batch_config_.sample_interval_ms = filter_config.sample_interval_ms; batch_config_.max_tracker_count = filter_config.max_tracker_count; @@ -62,6 +67,42 @@ filter_config.opportunistic_flush_threshold_time_ms; } +void TrackerFilter::ConfigureActiveState() { + if (!scan_filter_config_.hardware_filters.empty()) { + SetActiveState(); + } else { + ClearActiveState(); + } +} + +void TrackerFilter::ConfigureScanControlTimers() { + // The timer based scan is only enabled when the hardware scan filters are not + // empty and the active window and interval are valid. The active interval + // must be greater than the active window so that the timer based scan can + // function properly. + if (!scan_filter_config_.hardware_filters.empty() && + scan_filter_config_.active_window_ms > 0) { + if (scan_filter_config_.active_interval_ms <= + scan_filter_config_.active_window_ms) { + LOGE("Invalid active interval %" PRIu32 + " ms, must be greater than active window %" PRIu32 " ms.", + scan_filter_config_.active_interval_ms, + scan_filter_config_.active_window_ms); + return; + } + // Sets active interval and window timer duration. + active_interval_timer_.SetDurationMs( + scan_filter_config_.active_interval_ms); + active_window_timer_.SetDurationMs(scan_filter_config_.active_window_ms); + // Starts active interval and window timers. + if (active_interval_timer_.StartTimer()) { + active_window_timer_.StartTimer(); + } + } else if (scan_filter_config_.hardware_filters.empty()) { + active_interval_timer_.StopTimer(); + } +} + void TrackerFilter::MatchAndSave( const chre::DynamicVector<chreBleAdvertisingReport> &ble_adv_reports, TrackerStorage &tracker_storage) {
diff --git a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/tracker_filter.h b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/tracker_filter.h index ec30279..ef07856 100644 --- a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/tracker_filter.h +++ b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/tracker_filter.h
@@ -1,11 +1,14 @@ #ifndef LOCATION_LBS_CONTEXTHUB_NANOAPPS_NEARBY_TRACKER_FILTER_H_ #define LOCATION_LBS_CONTEXTHUB_NANOAPPS_NEARBY_TRACKER_FILTER_H_ +#include <stdbool.h> + #include <cstdint> #include "chre_api/chre.h" #include "location/lbs/contexthub/nanoapps/nearby/byte_array.h" #include "location/lbs/contexthub/nanoapps/nearby/proto/nearby_extension.nanopb.h" +#include "location/lbs/contexthub/nanoapps/nearby/timer.h" #include "location/lbs/contexthub/nanoapps/nearby/tracker_storage.h" #include "third_party/contexthub/chre/util/include/chre/util/dynamic_vector.h" @@ -14,6 +17,15 @@ struct TrackerScanFilterConfig { chre::DynamicVector<chreBleGenericFilter> hardware_filters; int8_t rssi_threshold = CHRE_BLE_RSSI_THRESHOLD_NONE; + // Active interval for tracker scan filter. The tracker scan filter is enabled + // at the beginning of the active interval and disabled at the end of the + // active window. This creates a toggle effect for the tracker scan filter and + // reduces the BLE scan power consumption. If the interval and window are not + // set by host, the default values are 0, and the tracker scan filter is + // always enabled. + uint32_t active_interval_ms; + // Active window for tracker scan filter. + uint32_t active_window_ms; }; class TrackerFilter { @@ -60,10 +72,47 @@ static bool EncodeTrackerReport(TrackerReport &tracker_report, ByteArray data_buf, size_t *encoded_size); + // Sets tracker scan filter active state. + void SetActiveState() { + is_active_ = true; + } + + // Clears tracker scan filter active state. + void ClearActiveState() { + is_active_ = false; + } + + // Returns whether tracker scan filter is active. + bool IsActive() { + return is_active_; + } + + Timer &GetActiveIntervalTimer() { + return active_interval_timer_; + } + + Timer &GetActiveWindowTimer() { + return active_window_timer_; + } + private: TrackerScanFilterConfig scan_filter_config_; TrackerBatchConfig batch_config_; chreHostEndpointInfo host_info_; + // whether the tracker scan filter is active. + bool is_active_ = false; + + // Configures tracker scan filter active state. + void ConfigureActiveState(); + + // Configures tracker scan filter control timers when updating scan filter and + // batch configurations. + void ConfigureScanControlTimers(); + + // Timer for tracker scan filter active interval. + Timer active_interval_timer_ = Timer(false); + // Timer for tracker scan filter active window. + Timer active_window_timer_ = Timer(true); }; } // namespace nearby
diff --git a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/tracker_storage.h b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/tracker_storage.h index 73a03b2..75eb103 100644 --- a/apps/nearby/location/lbs/contexthub/nanoapps/nearby/tracker_storage.h +++ b/apps/nearby/location/lbs/contexthub/nanoapps/nearby/tracker_storage.h
@@ -22,18 +22,18 @@ struct TrackerBatchConfig { // Minimum sampling interval to update tracker history. - uint32_t sample_interval_ms; + uint32_t sample_interval_ms = {60000}; // Maximum number of tracker reports that can be stored in storage. - uint32_t max_tracker_count; + uint32_t max_tracker_count = {30}; // Notification threshold of the number of tracker reports, which should be // equal to or smaller than max_tracker_count. - uint32_t notify_threshold_tracker_count; + uint32_t notify_threshold_tracker_count = {28}; // Maximum number of tracker histories that can be stored in tracker report. - uint32_t max_history_count; + uint32_t max_history_count = {20}; // Timeout for tracker history to be considered lost. - uint32_t lost_timeout_ms; + uint32_t lost_timeout_ms = {60000}; // Time based threshold for opportunistic flush of tracker reports. - uint32_t opportunistic_flush_threshold_time_ms; + uint32_t opportunistic_flush_threshold_time_ms = {4294967295}; }; enum class TrackerState {
diff --git a/apps/sensor_test/Makefile b/apps/sensor_test/Makefile new file mode 100644 index 0000000..d402f68 --- /dev/null +++ b/apps/sensor_test/Makefile
@@ -0,0 +1,41 @@ +# +# Sensor World Nanoapp Makefile +# + +# Environment Checks ########################################################### + +ifeq ($(CHRE_PREFIX),) +ifneq ($(ANDROID_BUILD_TOP),) +CHRE_PREFIX = $(ANDROID_BUILD_TOP)/system/chre +else +$(error "You must run 'lunch' to setup ANDROID_BUILD_TOP, or explicitly define \ + the CHRE_PREFIX environment variable to point to the CHRE root \ + directory.") +endif +endif + +# Nanoapp Configuration ######################################################## + +NANOAPP_NAME = sensor_test +NANOAPP_ID = 0x0123456789000016 +NANOAPP_VERSION = 0x00000001 + +NANOAPP_NAME_STRING = \"Sensor\ Test\" + +# Common Compiler Flags ######################################################## + +# Include paths. +COMMON_CFLAGS += -I. +COMMON_CFLAGS += -I$(CHRE_PREFIX)/util/include + +# Defines. +COMMON_CFLAGS += -DNANOAPP_MINIMUM_LOG_LEVEL=CHRE_LOG_LEVEL_DEBUG +COMMON_CFLAGS += -DCHRE_ASSERTIONS_ENABLED + +# Common Source Files ########################################################## + +COMMON_SRCS += sensor_test.cc + +# Makefile Includes ############################################################ + +include $(CHRE_PREFIX)/build/nanoapp/app.mk
diff --git a/apps/sensor_test/sensor_test.cc b/apps/sensor_test/sensor_test.cc new file mode 100644 index 0000000..0aa612e --- /dev/null +++ b/apps/sensor_test/sensor_test.cc
@@ -0,0 +1,582 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cinttypes> + +#include "chre/util/macros.h" +#include "chre/util/nanoapp/log.h" +#include "chre/util/time.h" +#include "chre_api/chre.h" + +#define LOG_TAG "[SensorTest]" + +#ifdef CHRE_NANOAPP_INTERNAL +namespace chre { +namespace { +#endif // CHRE_NANOAPP_INTERNAL + +using chre::kOneMillisecondInNanoseconds; +using chre::Milliseconds; +using chre::Seconds; + +namespace { + +//! Enable BreakIt test mode. +// In BreakIt test mode, a timer will be set periodically to randomly +// enable/disable each sensor. +constexpr bool kBreakIt = false; +constexpr Milliseconds kBreakItPeriod = Milliseconds(2000); +uint32_t gBreakItTimerHandle; + +//! Enable chreSensorFlushAsync test +// When enabled, SensorTest will set a timer to invoke +// chreSensorFlushAsync(sensors[kFlushSensorIndex].handle) +// halfway through sensors[kFlushSensorIndex].latency +// +// If CHRE_EVENT_SENSOR_FLUSH_COMPLETE is not received before +// kFlushItTimeout expires, an error message will be logged. +constexpr bool kFlushIt = true; +constexpr uint32_t kFlushCookie = 0xdeadbeef; +constexpr uint32_t kFlushSensorIndex = 0; // CHRE_SENSOR_TYPE_ACCELEROMETER +uint32_t gFlushItTimerHandle; + +constexpr Milliseconds kFlushItTimeout = Milliseconds(5000); +uint32_t gFlushItTimeoutTimerHandle; + +//! Whether to enable sensor event logging or not. +constexpr bool kEnableSensorEventLogging = true; + +//! Enable/disable all sensors by default. +// This allows disabling all sensens by default and enabling only targeted +// sensors for testing by locally overriding 'enable' field in SensorState. +// Note that enabling BreakIt test disables all sensors at init by default. +constexpr bool kEnableDefault = !kBreakIt; + +struct SensorState { + const uint8_t type; + const uint8_t sensorIndex; + uint32_t handle; + bool isInitialized; + bool enable; + uint64_t interval; // nsec + uint64_t latency; // nsec + chreSensorInfo info; +}; + +SensorState sensors[] = { + { + .type = CHRE_SENSOR_TYPE_ACCELEROMETER, + .sensorIndex = 0, + .handle = 0, + .isInitialized = false, + .enable = kEnableDefault, + .interval = Milliseconds(80).toRawNanoseconds(), + .latency = Seconds(4).toRawNanoseconds(), + .info = {}, + }, + { + .type = CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT, + .sensorIndex = 0, + .handle = 0, + .isInitialized = false, + .enable = false, // InstantMotion is triggered by Prox + .interval = CHRE_SENSOR_INTERVAL_DEFAULT, + .latency = CHRE_SENSOR_LATENCY_DEFAULT, + .info = {}, + }, + { + .type = CHRE_SENSOR_TYPE_STATIONARY_DETECT, + .sensorIndex = 0, + .handle = 0, + .isInitialized = false, + .enable = false, // StationaryDetect is triggered by Prox + .interval = CHRE_SENSOR_INTERVAL_DEFAULT, + .latency = CHRE_SENSOR_LATENCY_DEFAULT, + .info = {}, + }, + { + .type = CHRE_SENSOR_TYPE_GYROSCOPE, + .sensorIndex = 0, + .handle = 0, + .isInitialized = false, + .enable = kEnableDefault, + .interval = Milliseconds(80).toRawNanoseconds(), + .latency = Seconds(4).toRawNanoseconds(), + .info = {}, + }, + { + .type = CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD, + .sensorIndex = 0, + .handle = 0, + .isInitialized = false, + .enable = kEnableDefault, + .interval = Milliseconds(80).toRawNanoseconds(), + .latency = Seconds(4).toRawNanoseconds(), + .info = {}, + }, + { + .type = CHRE_SENSOR_TYPE_PRESSURE, + .sensorIndex = 0, + .handle = 0, + .isInitialized = false, + .enable = kEnableDefault, + .interval = Milliseconds(200).toRawNanoseconds(), + .latency = Seconds(4).toRawNanoseconds(), + .info = {}, + }, + { + .type = CHRE_SENSOR_TYPE_LIGHT, + .sensorIndex = 0, + .handle = 0, + .isInitialized = false, + .enable = kEnableDefault, + .interval = Milliseconds(200).toRawNanoseconds(), + .latency = 0, + .info = {}, + }, + { + .type = CHRE_SENSOR_TYPE_PROXIMITY, + .sensorIndex = 0, + .handle = 0, + .isInitialized = false, + .enable = kEnableDefault, + .interval = Milliseconds(200).toRawNanoseconds(), + .latency = 0, + .info = {}, + }, + { + .type = CHRE_SENSOR_TYPE_STEP_DETECT, + .sensorIndex = 0, + .handle = 0, + .isInitialized = false, + .enable = kEnableDefault, + .interval = CHRE_SENSOR_INTERVAL_DEFAULT, + .latency = CHRE_SENSOR_LATENCY_ASAP, + .info = {}, + }, + { + .type = CHRE_SENSOR_TYPE_STEP_COUNTER, + .sensorIndex = 0, + .handle = 0, + .isInitialized = false, + .enable = kEnableDefault, + .interval = CHRE_SENSOR_INTERVAL_DEFAULT, + .latency = CHRE_SENSOR_LATENCY_ASAP, + .info = {}, + }, + { + .type = CHRE_SENSOR_TYPE_ACCELEROMETER_TEMPERATURE, + .sensorIndex = 0, + .handle = 0, + .isInitialized = false, + .enable = kEnableDefault, + .interval = Seconds(2).toRawNanoseconds(), + .latency = 0, + .info = {}, + }, + { + .type = CHRE_SENSOR_TYPE_GYROSCOPE_TEMPERATURE, + .sensorIndex = 0, + .handle = 0, + .isInitialized = false, + .enable = kEnableDefault, + .interval = Seconds(2).toRawNanoseconds(), + .latency = 0, + .info = {}, + }, + { + .type = CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD_TEMPERATURE, + .sensorIndex = 0, + .handle = 0, + .isInitialized = false, + .enable = kEnableDefault, + .interval = Seconds(2).toRawNanoseconds(), + .latency = 0, + .info = {}, + }, + { + .type = CHRE_SENSOR_TYPE_UNCALIBRATED_ACCELEROMETER, + .sensorIndex = 0, + .handle = 0, + .isInitialized = false, + .enable = kEnableDefault, + .interval = Milliseconds(80).toRawNanoseconds(), + .latency = Seconds(4).toRawNanoseconds(), + .info = {}, + }, + { + .type = CHRE_SENSOR_TYPE_UNCALIBRATED_GYROSCOPE, + .sensorIndex = 0, + .handle = 0, + .isInitialized = false, + .enable = kEnableDefault, + .interval = Milliseconds(80).toRawNanoseconds(), + .latency = Seconds(4).toRawNanoseconds(), + .info = {}, + }, + { + .type = CHRE_SENSOR_TYPE_UNCALIBRATED_GEOMAGNETIC_FIELD, + .sensorIndex = 0, + .handle = 0, + .isInitialized = false, + .enable = kEnableDefault, + .interval = Milliseconds(80).toRawNanoseconds(), + .latency = Seconds(4).toRawNanoseconds(), + .info = {}, + }, +}; + +// Conditional logging macro +#define CLOGI(fmt, ...) \ + do { \ + if (kEnableSensorEventLogging) { \ + LOGI(fmt, ##__VA_ARGS__); \ + } \ + } while (0); + +// Helpers for testing InstantMotion and StationaryDetect +enum class MotionMode { + Instant, + Stationary, +}; + +// Storage to help access InstantMotion and StationaryDetect sensor handle and +// info +size_t motionSensorIndices[2]; +MotionMode motionMode = MotionMode::Instant; + +size_t getMotionSensorIndex() { + motionMode = (motionMode == MotionMode::Instant) ? MotionMode::Stationary + : MotionMode::Instant; + return motionSensorIndices[static_cast<size_t>(motionMode)]; +} + +//! Used to loop through all sensors to query sensor sampling status. +size_t statusIndex = 0; + +// Obtains 16-bit pseudo-random numbers. +uint16_t getNextLfsrState() { + // 15-bit LFSR with feedback polynomial x^15 + x^14 + 1 gives us a + // pseudo-random sequence over all 32767 possible values + static uint16_t lfsr = 0x1337; + uint16_t nextBit = ((lfsr << 14) ^ (lfsr << 13)) & 0x4000; + lfsr = nextBit | (lfsr >> 1); + + return lfsr; +} + +const char *getSensorName(uint32_t sensorHandle) { + for (size_t i = 0; i < ARRAY_SIZE(sensors); i++) { + if (sensors[i].handle == sensorHandle) { + return sensors[i].info.sensorName; + } + } + return nullptr; +} + +void handleTimerEvent(const uint32_t *ev) { + if (*ev == gFlushItTimerHandle) { + LOGI("FlushIt Timer Fired"); + if (chreSensorFlushAsync(sensors[kFlushSensorIndex].handle, + &kFlushCookie)) { + gFlushItTimeoutTimerHandle = + chreTimerSet(kFlushItTimeout.toRawNanoseconds(), + &gFlushItTimeoutTimerHandle, true /* oneShot */); + } else { + LOGE("chreSensorFlushAsync failed"); + } + + } else if (*ev == gFlushItTimeoutTimerHandle) { + LOGE("chreSensorFlushAsync Timeout"); + + } else if (*ev == gBreakItTimerHandle) { + for (size_t i = 0; i < ARRAY_SIZE(sensors); i++) { + SensorState &sensor = sensors[i]; + + bool enable = getNextLfsrState() & 0x1; + if (sensor.isInitialized && sensor.enable != enable) { + sensor.enable = enable; + + bool status; + if (!enable) { + status = chreSensorConfigureModeOnly(sensor.handle, + CHRE_SENSOR_CONFIGURE_MODE_DONE); + } else { + enum chreSensorConfigureMode mode = + sensor.info.isOneShot ? CHRE_SENSOR_CONFIGURE_MODE_ONE_SHOT + : CHRE_SENSOR_CONFIGURE_MODE_CONTINUOUS; + status = chreSensorConfigure(sensor.handle, mode, sensor.interval, + sensor.latency); + } + + LOGI("Configure [enable %d, status %d]: %s", enable, status, + sensor.info.sensorName); + } + } + + gBreakItTimerHandle = + chreTimerSet(kBreakItPeriod.toRawNanoseconds(), &gBreakItTimerHandle, + true /* oneShot */); + } +} + +void handleThreeAxisEvent(const chreSensorThreeAxisData *ev, + uint16_t eventType) { + const auto header = ev->header; + const auto *data = ev->readings; + const auto accuracy = header.accuracy; + uint64_t sampleTime = header.baseTimestamp; + uint64_t chreTime = chreGetTime(); + + float x = 0, y = 0, z = 0; + for (size_t i = 0; i < header.readingCount; i++) { + x += data[i].v[0]; + y += data[i].v[1]; + z += data[i].v[2]; + sampleTime += data[i].timestampDelta; + } + x /= header.readingCount; + y /= header.readingCount; + z /= header.readingCount; + + CLOGI("%s, %d samples: %f %f %f, accuracy: %u, t=%" PRIu64 " ms", + getSensorName(header.sensorHandle), header.readingCount, + static_cast<double>(x), static_cast<double>(y), static_cast<double>(z), + accuracy, header.baseTimestamp / kOneMillisecondInNanoseconds); + + if (eventType == CHRE_EVENT_SENSOR_UNCALIBRATED_GYROSCOPE_DATA) { + CLOGI("UncalGyro time: first %" PRIu64 " last %" PRIu64 " chre %" PRIu64 + " delta [%" PRId64 ", %" PRId64 "]ms", + header.baseTimestamp, sampleTime, chreTime, + static_cast<int64_t>(header.baseTimestamp - chreTime) / + static_cast<int64_t>(kOneMillisecondInNanoseconds), + static_cast<int64_t>(sampleTime - chreTime) / + static_cast<int64_t>(kOneMillisecondInNanoseconds)); + } +} + +void handleFloatEvent(const chreSensorFloatData *ev) { + const auto header = ev->header; + + float v = 0; + for (size_t i = 0; i < header.readingCount; i++) { + v += ev->readings[i].value; + } + v /= header.readingCount; + + CLOGI("%s, %d samples: %f, accuracy = %u, t=%" PRIu64 " ms", + getSensorName(header.sensorHandle), header.readingCount, + static_cast<double>(v), header.accuracy, + header.baseTimestamp / kOneMillisecondInNanoseconds); +} + +void handleProximityEvent(const chreSensorByteData *ev) { + const auto header = ev->header; + const auto reading = ev->readings[0]; + uint64_t sampleTime = header.baseTimestamp; + uint64_t chreTime = chreGetTime(); + + CLOGI("%s, %d samples: isNear %d, invalid %d, accuracy: %u", + getSensorName(header.sensorHandle), header.readingCount, reading.isNear, + reading.invalid, header.accuracy); + + CLOGI("Prox time: sample %" PRIu64 " chre %" PRIu64 " delta %" PRId64 "ms", + header.baseTimestamp, chreTime, + static_cast<int64_t>(sampleTime - chreTime) / 1000000); + + // Enable InstantMotion and StationaryDetect alternatively on near->far. + if (reading.isNear == 0 && !kBreakIt) { + size_t motionSensorIndex = getMotionSensorIndex(); + bool status = chreSensorConfigure( + sensors[motionSensorIndex].handle, CHRE_SENSOR_CONFIGURE_MODE_ONE_SHOT, + CHRE_SENSOR_INTERVAL_DEFAULT, CHRE_SENSOR_LATENCY_DEFAULT); + LOGI("Requested %s: %s", sensors[motionSensorIndex].info.sensorName, + status ? "success" : "failure"); + } + + // Exercise chreGetSensorSamplingStatus on one sensor on near->far. + if (sensors[statusIndex].isInitialized && reading.isNear == 0) { + struct chreSensorSamplingStatus status; + bool success = + chreGetSensorSamplingStatus(sensors[statusIndex].handle, &status); + LOGI("%s success %d: enabled %d interval %" PRIu64 " latency %" PRIu64, + sensors[statusIndex].info.sensorName, success, status.enabled, + status.interval, status.latency); + } + statusIndex = (statusIndex + 1) % ARRAY_SIZE(sensors); +} + +} // namespace + +bool nanoappStart() { + LOGI("App started on platform ID %" PRIx64, chreGetPlatformId()); + + for (size_t i = 0; i < ARRAY_SIZE(sensors); i++) { + SensorState &sensor = sensors[i]; + sensor.isInitialized = + chreSensorFind(sensor.type, sensor.sensorIndex, &sensor.handle); + LOGI("Sensor %zu initialized: %s with handle %" PRIu32, i, + sensor.isInitialized ? "true" : "false", sensor.handle); + + if (sensor.type == CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT) { + motionSensorIndices[static_cast<size_t>(MotionMode::Instant)] = i; + } else if (sensor.type == CHRE_SENSOR_TYPE_STATIONARY_DETECT) { + motionSensorIndices[static_cast<size_t>(MotionMode::Stationary)] = i; + } + + if (sensor.isInitialized) { + // Get sensor info + chreSensorInfo &info = sensor.info; + bool infoStatus = chreGetSensorInfo(sensor.handle, &info); + if (infoStatus) { + LOGI("SensorInfo: %s, Type=%" PRIu8 + " OnChange=%d OneShot=%d Passive=%d " + "minInterval=%" PRIu64 "nsec", + info.sensorName, info.sensorType, info.isOnChange, info.isOneShot, + info.supportsPassiveMode, info.minInterval); + } else { + LOGE("chreGetSensorInfo failed"); + } + + // Subscribe to sensors + if (sensor.enable) { + float odrHz = 1e9f / static_cast<float>(sensor.interval); + float latencySec = static_cast<float>(sensor.latency) / 1e9f; + bool status = chreSensorConfigure(sensor.handle, + CHRE_SENSOR_CONFIGURE_MODE_CONTINUOUS, + sensor.interval, sensor.latency); + LOGI("Requested data: odr %f Hz, latency %f sec, %s", + static_cast<double>(odrHz), static_cast<double>(latencySec), + status ? "success" : "failure"); + } + } + } + + // Set timer for BreakIt test. + if (kBreakIt) { + gBreakItTimerHandle = + chreTimerSet(kBreakItPeriod.toRawNanoseconds(), &gBreakItTimerHandle, + true /* oneShot */); + } + + if (kFlushIt) { + // Trigger a flush half way through the target sensor latency + gFlushItTimerHandle = + chreTimerSet(sensors[kFlushSensorIndex].latency / 2, + &gFlushItTimerHandle, true /* oneShot */); + } + + return true; +} + +void nanoappHandleEvent(uint32_t senderInstanceId, uint16_t eventType, + const void *eventData) { + UNUSED_VAR(senderInstanceId); + + switch (eventType) { + case CHRE_EVENT_SENSOR_ACCELEROMETER_DATA: + case CHRE_EVENT_SENSOR_UNCALIBRATED_ACCELEROMETER_DATA: + case CHRE_EVENT_SENSOR_GYROSCOPE_DATA: + case CHRE_EVENT_SENSOR_UNCALIBRATED_GYROSCOPE_DATA: + case CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_DATA: + case CHRE_EVENT_SENSOR_UNCALIBRATED_GEOMAGNETIC_FIELD_DATA: + handleThreeAxisEvent( + static_cast<const chreSensorThreeAxisData *>(eventData), eventType); + break; + + case CHRE_EVENT_SENSOR_PRESSURE_DATA: + case CHRE_EVENT_SENSOR_LIGHT_DATA: + case CHRE_EVENT_SENSOR_ACCELEROMETER_TEMPERATURE_DATA: + case CHRE_EVENT_SENSOR_GYROSCOPE_TEMPERATURE_DATA: + case CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_TEMPERATURE_DATA: + handleFloatEvent(static_cast<const chreSensorFloatData *>(eventData)); + break; + + case CHRE_EVENT_SENSOR_PROXIMITY_DATA: + handleProximityEvent(static_cast<const chreSensorByteData *>(eventData)); + break; + + case CHRE_EVENT_SENSOR_INSTANT_MOTION_DETECT_DATA: + case CHRE_EVENT_SENSOR_STATIONARY_DETECT_DATA: + case CHRE_EVENT_SENSOR_STEP_DETECT_DATA: { + const auto *ev = static_cast<const chreSensorOccurrenceData *>(eventData); + const auto header = ev->header; + + CLOGI("%s, %d samples, accuracy: %u", getSensorName(header.sensorHandle), + header.readingCount, header.accuracy); + break; + } + + case CHRE_EVENT_SENSOR_STEP_COUNTER_DATA: { + const auto *ev = static_cast<const chreSensorUint64Data *>(eventData); + const auto header = ev->header; + const uint64_t reading = ev->readings[header.readingCount - 1].value; + + CLOGI("%s, %" PRIu16 " samples: latest %" PRIu64, + getSensorName(header.sensorHandle), header.readingCount, reading); + break; + } + + case CHRE_EVENT_SENSOR_SAMPLING_CHANGE: { + const auto *ev = + static_cast<const chreSensorSamplingStatusEvent *>(eventData); + + CLOGI("Sampling Change: handle %" PRIu32 ", status: interval %" PRIu64 + " latency %" PRIu64 " enabled %d", + ev->sensorHandle, ev->status.interval, ev->status.latency, + ev->status.enabled); + break; + } + + case CHRE_EVENT_TIMER: + if (kBreakIt || kFlushIt) { + handleTimerEvent(static_cast<const uint32_t *>(eventData)); + } else { + LOGE("Timer event received with kBreakIt and kFlushIt disabled"); + } + break; + + case CHRE_EVENT_SENSOR_FLUSH_COMPLETE: { + const auto *ev = + static_cast<const chreSensorFlushCompleteEvent *>(eventData); + chreTimerCancel(gFlushItTimeoutTimerHandle); + + LOGI("Flush Complete: handle %" PRIu32 ", errorCode: %d", + ev->sensorHandle, ev->errorCode); + break; + } + + default: + LOGW("Unhandled event %d", eventType); + break; + } +} + +void nanoappEnd() { + LOGI("Stopped"); +} + +#ifdef CHRE_NANOAPP_INTERNAL +} // anonymous namespace +} // namespace chre + +#include "chre/platform/static_nanoapp_init.h" +#include "chre/util/nanoapp/app_id.h" +#include "chre/util/system/napp_permissions.h" + +CHRE_STATIC_NANOAPP_INIT(SensorWorld, chre::kSensorWorldAppId, 0, + chre::NanoappPermissions::CHRE_PERMS_NONE); +#endif // CHRE_NANOAPP_INTERNAL
diff --git a/apps/sensor_test/sensor_test.mk b/apps/sensor_test/sensor_test.mk new file mode 100644 index 0000000..6b6f44e --- /dev/null +++ b/apps/sensor_test/sensor_test.mk
@@ -0,0 +1,12 @@ +# +# Sensor World Makefile +# + +# Common Compiler Flags ######################################################## + +# Include paths. +COMMON_CFLAGS += -Iapps/sensor_test/include + +# Common Source Files ########################################################## + +COMMON_SRCS += apps/sensor_test/sensor_test.cc
diff --git a/apps/test/chqts/src/general_test/basic_audio_test.cc b/apps/test/chqts/src/general_test/basic_audio_test.cc index 8076598..6c2b7a0 100644 --- a/apps/test/chqts/src/general_test/basic_audio_test.cc +++ b/apps/test/chqts/src/general_test/basic_audio_test.cc
@@ -261,10 +261,7 @@ struct chreAudioSource source; constexpr uint32_t kRequiredAudioHandle = 0; // If the DUT supports CHRE audio, then audio handle 0 is required to be - // valid. There is the risk that the chreAudioGetSource function might - // legitimately fail however - we should replace this function when CHRE - // audio capabilities in b/185155280 are implemented. - // TODO (b/185155280): fix this query + // valid. return chreAudioGetSource(kRequiredAudioHandle, &source); } } // anonymous namespace
diff --git a/apps/test/chqts/src/general_test/basic_ble_test.cc b/apps/test/chqts/src/general_test/basic_ble_test.cc index 4d01722..e27432f 100644 --- a/apps/test/chqts/src/general_test/basic_ble_test.cc +++ b/apps/test/chqts/src/general_test/basic_ble_test.cc
@@ -15,13 +15,14 @@ */ #include <general_test/basic_ble_test.h> - #include <shared/send_message.h> #include "chre/util/nanoapp/ble.h" +#include "chre/util/nanoapp/log.h" #include "chre/util/time.h" #include "chre_api/chre.h" +#define LOG_TAG "[GeneralTest][Ble]" /* * Test to check expected functionality of the CHRE BLE APIs. */ @@ -83,8 +84,15 @@ } void BasicBleTest::handleBleAsyncResult(const chreAsyncResult *result) { - if (result == nullptr || !result->success) { + if (result == nullptr) { + sendFatalFailureToHost("Received null BLE async result"); + return; + } + if (!result->success) { + LOGE("Received unsuccessful BLE async result, error code %" PRIu8, + result->errorCode); sendFatalFailureToHost("Received unsuccessful BLE async result"); + return; } switch (result->requestType) {
diff --git a/apps/test/common/chre_api_test/rpc/chre_api_test.pwpb_options b/apps/test/common/chre_api_test/rpc/chre_api_test.pwpb_options new file mode 100644 index 0000000..6cc7b0b --- /dev/null +++ b/apps/test/common/chre_api_test/rpc/chre_api_test.pwpb_options
@@ -0,0 +1,12 @@ +chre.rpc.ChreGetSensorInfoOutput.sensorName max_size:100 +chre.rpc.ChreAudioGetSourceOutput.name max_size:40 # CHRE_AUDIO_SOURCE_NAME_MAX_SIZE +chre.rpc.ChreAudioDataEvent.samples max_size:64000 +chre.rpc.ChreAudioDataSamples.samples max_size:200 +chre.rpc.ChreBleGenericFilter.data max_size:29 # CHRE_BLE_DATA_LEN_MAX +chre.rpc.ChreBleGenericFilter.mask max_size:29 # CHRE_BLE_DATA_LEN_MAX +chre.rpc.ChreGetHostEndpointInfoOutput.endpointName max_size:51 # CHRE_MAX_ENDPOINT_NAME_LEN +chre.rpc.ChreGetHostEndpointInfoOutput.endpointTag max_size:51 # CHRE_MAX_ENDPOINT_TAG_LEN +chre.rpc.GatherEventsInput.eventTypes max_count:10 +chre.rpc.ChreBleAdvertisingReport.address max_size:6 # CHRE_BLE_ADDRESS_LEN +chre.rpc.ChreBleAdvertisingReport.directAddress max_size:6 # CHRE_BLE_ADDRESS_LEN +chre.rpc.ChreBleAdvertisingReport.data max_size:255 # extended range is [0, 255]
diff --git a/apps/test/common/chre_cross_validator_wifi/Makefile b/apps/test/common/chre_cross_validator_wifi/Makefile index 862f248..e3f53f0 100644 --- a/apps/test/common/chre_cross_validator_wifi/Makefile +++ b/apps/test/common/chre_cross_validator_wifi/Makefile
@@ -44,7 +44,7 @@ # Compiler Flags ############################################################### # Defines -COMMON_CFLAGS += -DNANOAPP_MINIMUM_LOG_LEVEL=CHRE_LOG_LEVEL_INFO +COMMON_CFLAGS += -DNANOAPP_MINIMUM_LOG_LEVEL=CHRE_LOG_LEVEL_DEBUG COMMON_CFLAGS += -DLOG_TAG=\"[ChreCrossValidatorWifi]\" COMMON_CFLAGS += -DCHRE_ASSERTIONS_ENABLED
diff --git a/apps/test/common/chre_cross_validator_wifi/inc/chre_cross_validator_wifi_manager.h b/apps/test/common/chre_cross_validator_wifi/inc/chre_cross_validator_wifi_manager.h index 0a7abc2..b8db737 100644 --- a/apps/test/common/chre_cross_validator_wifi/inc/chre_cross_validator_wifi_manager.h +++ b/apps/test/common/chre_cross_validator_wifi/inc/chre_cross_validator_wifi_manager.h
@@ -32,9 +32,7 @@ #include "chre_test_common.nanopb.h" #include "wifi_scan_result.h" -namespace chre { - -namespace cross_validator_wifi { +namespace chre::cross_validator_wifi { /** * Class to manage a CHRE cross validator wifi nanoapp. @@ -69,6 +67,10 @@ // CHRE to receive more result. uint8_t mExpectedMaxChreResultCanHandle = 100; + // Bool for tracking if we have seen the start of a scan result series. Used + // to avoid catching the tail end of a previous scan result. + bool mScanStartSeen = false; + //! Bools indicating that data collection is complete for each side bool mApDataCollectionDone = false; bool mChreDataCollectionDone = false; @@ -90,22 +92,21 @@ chre_cross_validation_wifi_StepStartCommand stepStartCommand); /** + * Sends the test result to host. + * * @param success true if the result was success. * @param errMessage The error message that should be sent to host with * failure. - * - * @return The TestResult proto message that is encoded with these fields. */ - chre_test_common_TestResult makeTestResultProtoMessage( - bool success, const char *errMessage = nullptr); + void sendTestResult(bool success, const char *errorMessage = nullptr) const; /** * @param capabilitiesFromChre The number with flags that represent the * different wifi capabilities. * @return The wifi capabilities proto message for the host. */ - chre_cross_validation_wifi_WifiCapabilities makeWifiCapabilitiesMessage( - uint32_t capabilitiesFromChre); + static chre_cross_validation_wifi_WifiCapabilities + makeWifiCapabilitiesMessage(uint32_t capabilitiesFromChre); /** * Handle a wifi scan result data message sent from AP. @@ -144,43 +145,21 @@ * @return The index of the matched scan result in the list if * found, otherwise SIZE_MAX. */ - size_t getMatchingScanResultIndex( + static size_t getMatchingScanResultIndex( const DynamicVector<WifiScanResult> &results, const WifiScanResult &queryResult); /** - * Setup WiFi scan monitoring from CHRE apis. - * - * @return true if chreWifiConfigureScanMonitorAsync() returns true - */ - bool setupWifiScanMonitoring(); - - /** * Handle wifi async result event with event data. * * @param result The data for the event. */ void handleWifiAsyncResult(const chreAsyncResult *result); - - /** - * The function to pass as the encode function pointer for the errorMessage - * field of the TestResult message. - * - * @param stream The stream to write bytes to. - * @param field The field that should be encoded. Unused by us. - * @param arg The argument that will be set to a pointer to the string to - * encode as error message. - */ - static bool encodeErrorMessage(pb_ostream_t *stream, - const pb_field_t * /*field*/, - void *const *arg); }; // The chre cross validator manager singleton. typedef chre::Singleton<Manager> ManagerSingleton; -} // namespace cross_validator_wifi - -} // namespace chre +} // namespace chre::cross_validator_wifi #endif // CHRE_CROSS_VALIDATOR_WIFI_MANAGER_H_
diff --git a/apps/test/common/chre_cross_validator_wifi/src/chre_cross_validator_wifi_manager.cc b/apps/test/common/chre_cross_validator_wifi/src/chre_cross_validator_wifi_manager.cc index 4bd78ce..a210237 100644 --- a/apps/test/common/chre_cross_validator_wifi/src/chre_cross_validator_wifi_manager.cc +++ b/apps/test/common/chre_cross_validator_wifi/src/chre_cross_validator_wifi_manager.cc
@@ -15,25 +15,15 @@ #include "chre_cross_validator_wifi_manager.h" -#include <stdio.h> -#include <algorithm> #include <cinttypes> #include <cstring> -#include "chre/util/nanoapp/assert.h" -#include "chre/util/nanoapp/callbacks.h" #include "chre/util/nanoapp/log.h" #include "chre/util/nanoapp/wifi.h" #include "chre_api/chre.h" -#include "chre_cross_validation_wifi.nanopb.h" -#include "chre_test_common.nanopb.h" #include "send_message.h" -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -namespace chre { - -namespace cross_validator_wifi { +namespace chre::cross_validator_wifi { // Fake scan monitor cookie which is not used constexpr uint32_t kScanMonitoringCookie = 0; @@ -62,31 +52,31 @@ const chreMessageFromHostData *hostData) { if (senderInstanceId != CHRE_INSTANCE_ID) { LOGE("Incorrect sender instance id: %" PRIu32, senderInstanceId); - } else { - mCrossValidatorState.hostEndpoint = hostData->hostEndpoint; - switch (hostData->messageType) { - case chre_cross_validation_wifi_MessageType_STEP_START: { - pb_istream_t stream = pb_istream_from_buffer( - static_cast<const pb_byte_t *>( - const_cast<const void *>(hostData->message)), - hostData->messageSize); - chre_cross_validation_wifi_StepStartCommand stepStartCommand; - if (!pb_decode(&stream, - chre_cross_validation_wifi_StepStartCommand_fields, - &stepStartCommand)) { - LOGE("Error decoding StepStartCommand"); - } else { - handleStepStartMessage(stepStartCommand); - } + return; + } + mCrossValidatorState.hostEndpoint = hostData->hostEndpoint; + switch (hostData->messageType) { + case chre_cross_validation_wifi_MessageType_STEP_START: { + pb_istream_t stream = pb_istream_from_buffer( + static_cast<const pb_byte_t *>( + const_cast<const void *>(hostData->message)), + hostData->messageSize); + chre_cross_validation_wifi_StepStartCommand stepStartCommand; + if (!pb_decode(&stream, + chre_cross_validation_wifi_StepStartCommand_fields, + &stepStartCommand)) { + LOGE("Error decoding StepStartCommand"); break; } - case chre_cross_validation_wifi_MessageType_SCAN_RESULT: - handleDataMessage(hostData); - break; - default: - LOGE("Unknown message type %" PRIu32 " for host message", - hostData->messageType); + handleStepStartMessage(stepStartCommand); + break; } + case chre_cross_validation_wifi_MessageType_SCAN_RESULT: + handleDataMessage(hostData); + break; + default: + LOGE("Unknown message type %" PRIu32 " for host message", + hostData->messageType); } } @@ -97,6 +87,7 @@ LOGE("Received StepStartCommand for INIT step"); break; case chre_cross_validation_wifi_Step_CAPABILITIES: { + LOGD("%s: Received Step_CAPABILITIES", __func__); chre_cross_validation_wifi_WifiCapabilities wifiCapabilities = makeWifiCapabilitiesMessage(chreWifiGetCapabilities()); test_shared::sendMessageToHost( @@ -106,24 +97,28 @@ break; } case chre_cross_validation_wifi_Step_SETUP: { - if (!chreWifiConfigureScanMonitorAsync(true /* enable */, + if (!chreWifiConfigureScanMonitorAsync(/* enable= */ true, &kScanMonitoringCookie)) { LOGE("chreWifiConfigureScanMonitorAsync() failed"); test_shared::sendTestResultWithMsgToHost( mCrossValidatorState.hostEndpoint, chre_cross_validation_wifi_MessageType_STEP_RESULT, - false /*success*/, "setupWifiScanMonitoring failed", - false /*abortOnFailure*/); - } else { - LOGD("chreWifiConfigureScanMonitorAsync() succeeded"); - if (stepStartCommand.has_chreScanCapacity) { - mExpectedMaxChreResultCanHandle = stepStartCommand.chreScanCapacity; - } + /*success=*/false, + /* errMessage= */ "setupWifiScanMonitoring failed", + /*abortOnFailure=*/false); + break; + } + LOGD("chreWifiConfigureScanMonitorAsync() succeeded"); + if (stepStartCommand.has_chreScanCapacity) { + mExpectedMaxChreResultCanHandle = stepStartCommand.chreScanCapacity; } break; } case chre_cross_validation_wifi_Step_VALIDATE: break; + default: + LOGE("Unexpected start step: %" PRIu8, + static_cast<uint8_t>(stepStartCommand.step)); } mStep = stepStartCommand.step; } @@ -137,28 +132,40 @@ uint8_t scanResultIndex = scanResult.getResultIndex(); if (scanResultIndex > scanResult.getTotalNumResults()) { LOGE("AP scan result index is greater than scan results size"); - } else { - if (!mApScanResults.push_back(scanResult)) { - LOG_OOM(); - } - if (scanResult.isLastMessage()) { - mApDataCollectionDone = true; - if (mChreDataCollectionDone) { - compareAndSendResultToHost(); - } - } + return; + } + if (!mApScanResults.push_back(scanResult)) { + LOG_OOM(); + } + LOGD("%s: AP wifi result %" PRIu8 "/%" PRIu8 " is received", __func__, + static_cast<uint8_t>(scanResultIndex + 1), + scanResult.getTotalNumResults()); + if (!scanResult.isLastMessage()) { + return; + } + mApDataCollectionDone = true; + if (mChreDataCollectionDone) { + compareAndSendResultToHost(); } } void Manager::handleWifiScanResult(const chreWifiScanEvent *event) { + if (!mScanStartSeen && event->eventIndex != 0) { + LOGW("Dropping chreWifiScanEvent because we haven't seen eventIndex=0"); + return; + } + mScanStartSeen = true; for (uint8_t i = 0; i < event->resultCount; i++) { mChreScanResults.push_back(event->results[i]); } - if (mChreScanResults.size() >= event->resultTotal) { - mChreDataCollectionDone = true; - if (mApDataCollectionDone) { - compareAndSendResultToHost(); - } + LOGD("%s: CHRE wifi result %zu/%" PRIu8 " is received", __func__, + mChreScanResults.size(), event->resultTotal); + if (mChreScanResults.size() < event->resultTotal) { + return; + } + mChreDataCollectionDone = true; + if (mApDataCollectionDone) { + compareAndSendResultToHost(); } } @@ -178,17 +185,12 @@ verifyScanResults(&testResult); if (belowMaxSizeCheck || aboveMaxSizeCheck) { - LOGE( - "AP and CHRE wifi scan result counts differ, AP = %zu, CHRE = %zu, MAX " - "= %" PRIu8, - mApScanResults.size(), mChreScanResults.size(), - mExpectedMaxChreResultCanHandle); - test_shared::sendTestResultWithMsgToHost( - mCrossValidatorState.hostEndpoint, - chre_cross_validation_wifi_MessageType_STEP_RESULT, false /*success*/, - "There is a different number of AP and CHRE scan results.", - false /*abortOnFailure*/); - + LOGE("Scan results differ: AP = %zu, CHRE = %zu, MAX = %" PRIu8, + mApScanResults.size(), mChreScanResults.size(), + mExpectedMaxChreResultCanHandle); + sendTestResult(/*success=*/false, + /* errorMessage= */ + "There is a different number of AP and CHRE scan results."); return; } @@ -200,32 +202,32 @@ void Manager::verifyScanResults(chre_test_common_TestResult *testResultOut) { bool allResultsValid = true; - for (uint8_t i = 0; i < mChreScanResults.size(); i++) { - const WifiScanResult chreScanResult = WifiScanResult(mChreScanResults[i]); + for (const chreWifiScanResult &result : mChreScanResults) { + const WifiScanResult chreWifiScanResult = WifiScanResult(result); bool isValidResult = true; - size_t index = getMatchingScanResultIndex(mApScanResults, chreScanResult); + size_t index = + getMatchingScanResultIndex(mApScanResults, chreWifiScanResult); const char *bssidStr = "<non-printable>"; char bssidBuffer[chre::kBssidStrLen]; - if (chre::parseBssidToStr(chreScanResult.getBssid(), bssidBuffer, + if (chre::parseBssidToStr(chreWifiScanResult.getBssid(), bssidBuffer, sizeof(bssidBuffer))) { bssidStr = bssidBuffer; } + // chreWifiScanResult is found if (index != SIZE_MAX) { WifiScanResult &apScanResult = mApScanResults[index]; if (apScanResult.getSeen()) { - *testResultOut = makeTestResultProtoMessage( - false, "Saw a CHRE scan result with a duplicate BSSID."); + *testResultOut = test_shared::makeTestResultProtoMessage( + /*success=*/false, "Saw a CHRE scan result with a duplicate BSSID"); isValidResult = false; - LOGE("CHRE Scan Result with bssid: %s has a dupplicate BSSID", - bssidStr); + LOGE("CHRE Scan Result with bssid: %s has a duplicate BSSID", bssidStr); } - if (!WifiScanResult::areEqual(chreScanResult, apScanResult)) { - *testResultOut = - makeTestResultProtoMessage(false, - "Fields differ between an AP and " - "CHRE scan result with same Bssid."); + if (!WifiScanResult::areEqual(chreWifiScanResult, apScanResult)) { + *testResultOut = test_shared::makeTestResultProtoMessage( + /*success=*/false, + "Fields differ between an AP and CHRE scan result with same Bssid"); isValidResult = false; LOGE( "CHRE Scan Result with bssid: %s found fields differ with " @@ -237,9 +239,9 @@ apScanResult.didSee(); } else { // Error CHRE BSSID does not match any AP - *testResultOut = makeTestResultProtoMessage( - false, - "Could not find an AP scan result with the same Bssid as a CHRE " + *testResultOut = test_shared::makeTestResultProtoMessage( + /*success=*/false, + "Could not find an AP scan result with the same Bssid in CHRE " "result"); isValidResult = false; LOGE( @@ -247,14 +249,15 @@ "with same Bssid", bssidStr); } + if (!isValidResult) { LOGE("False CHRE Scan Result with the following info:"); - logChreWifiResult(mChreScanResults[i]); + logChreWifiResult(result); allResultsValid = false; } } - for (auto &scanResult : mApScanResults) { + for (const WifiScanResult &scanResult : mApScanResults) { if (!scanResult.getSeen()) { const char *bssidStr = "<non-printable>"; char bssidBuffer[chre::kBssidStrLen]; @@ -267,16 +270,17 @@ // Since CHRE is more constrained in memory, it is expected that if we // receive over a cretin amount of AP, we will drop some of them. if (mApScanResults.size() <= mExpectedMaxChreResultCanHandle) { - *testResultOut = makeTestResultProtoMessage( - false /*success*/, + *testResultOut = test_shared::makeTestResultProtoMessage( + /*success=*/false, "Extra AP information shown in host " "when small number of AP results presenting"); allResultsValid = false; } } } + if (allResultsValid) { - *testResultOut = makeTestResultProtoMessage(true); + *testResultOut = test_shared::makeTestResultProtoMessage(true); } } @@ -291,32 +295,11 @@ return SIZE_MAX; } -bool Manager::encodeErrorMessage(pb_ostream_t *stream, - const pb_field_t * /*field*/, - void *const *arg) { - const char *str = static_cast<const char *>(const_cast<const void *>(*arg)); - size_t len = strlen(str); - return pb_encode_tag_for_field( - stream, &chre_test_common_TestResult_fields - [chre_test_common_TestResult_errorMessage_tag - 1]) && - pb_encode_string(stream, reinterpret_cast<const pb_byte_t *>(str), - len); -} - -chre_test_common_TestResult Manager::makeTestResultProtoMessage( - bool success, const char *errMessage) { - // TODO(b/154271547): Move this implementation into - // common/shared/send_message.cc::sendTestResultToHost - chre_test_common_TestResult testResult = - chre_test_common_TestResult_init_default; - testResult.has_code = true; - testResult.code = success ? chre_test_common_TestResult_Code_PASSED - : chre_test_common_TestResult_Code_FAILED; - if (!success && errMessage != nullptr) { - testResult.errorMessage = {.funcs = {.encode = encodeErrorMessage}, - .arg = const_cast<char *>(errMessage)}; - } - return testResult; +void Manager::sendTestResult(bool success, const char *errorMessage) const { + test_shared::sendTestResultWithMsgToHost( + mCrossValidatorState.hostEndpoint, + chre_cross_validation_wifi_MessageType_STEP_RESULT, success, errorMessage, + /* abortOnFailure= */ false); } chre_cross_validation_wifi_WifiCapabilities @@ -328,40 +311,26 @@ } void Manager::handleWifiAsyncResult(const chreAsyncResult *result) { - chre_test_common_TestResult testResult; - bool sendMessage = false; - if (result->requestType == CHRE_WIFI_REQUEST_TYPE_CONFIGURE_SCAN_MONITOR) { - if (mStep != chre_cross_validation_wifi_Step_SETUP) { - testResult = makeTestResultProtoMessage( - false, "Received scan monitor result event when step is not SETUP"); - sendMessage = true; - } else { - if (result->success) { - LOGD("Wifi scan monitoring setup successfully"); - testResult = makeTestResultProtoMessage(true); - sendMessage = true; - } else { - LOGE("Wifi scan monitoring setup failed async w/ error code %" PRIu8 - ".", - result->errorCode); - testResult = makeTestResultProtoMessage( - false, "Wifi scan monitoring setup failed async."); - sendMessage = true; - } - } - } else { - testResult = makeTestResultProtoMessage( - false, "Unknown chre async result type received"); - sendMessage = true; + if (result->requestType != CHRE_WIFI_REQUEST_TYPE_CONFIGURE_SCAN_MONITOR) { + sendTestResult(/*success=*/false, + /*errorMessage=*/"Unknown chre async result type received"); + return; } - if (sendMessage) { - test_shared::sendMessageToHost( - mCrossValidatorState.hostEndpoint, &testResult, - chre_test_common_TestResult_fields, - chre_cross_validation_wifi_MessageType_STEP_RESULT); + if (mStep != chre_cross_validation_wifi_Step_SETUP) { + sendTestResult( + /*success=*/false, + /*errorMessage=*/"Received scan monitor result but step is not SETUP"); + return; + } + if (result->success) { + LOGI("Wifi scan monitoring setup successfully"); + sendTestResult(/*success=*/true); + } else { + LOGE("Wifi scan monitoring setup failed async w/ error code %" PRIu8, + result->errorCode); + sendTestResult(/*success=*/false, + /*errorMessage=*/"Wifi scan monitoring setup failed async"); } } -} // namespace cross_validator_wifi - -} // namespace chre +} // namespace chre::cross_validator_wifi
diff --git a/apps/test/common/chre_settings_test/src/chre_settings_test_manager.cc b/apps/test/common/chre_settings_test/src/chre_settings_test_manager.cc index 85502cc..8ffb6ee 100644 --- a/apps/test/common/chre_settings_test/src/chre_settings_test_manager.cc +++ b/apps/test/common/chre_settings_test/src/chre_settings_test_manager.cc
@@ -431,7 +431,7 @@ // Retry on CHRE_ERROR_BUSY after a short delay mWifiRequestRetries++; - uint64_t delay = kOneSecondInNanoseconds; + uint64_t delay = kOneSecondInNanoseconds * 2; gRangingRequestRetryTimerHandle = chreTimerSet( delay, &kRangingRequestRetryTimerCookie, /*oneShot=*/true); LOGW(
diff --git a/apps/test/common/shared/inc/send_message.h b/apps/test/common/shared/inc/send_message.h index d79387d..cd41e34 100644 --- a/apps/test/common/shared/inc/send_message.h +++ b/apps/test/common/shared/inc/send_message.h
@@ -20,10 +20,16 @@ #include <pb_encode.h> #include <cinttypes> +#include "chre/util/system/napp_permissions.h" +#include "chre_test_common.nanopb.h" + namespace chre { namespace test_shared { +chre_test_common_TestResult makeTestResultProtoMessage( + bool success, const char *errMessage = nullptr); + /** * Same as sendTestResultWithMsgToHost, but doesn't accept an error message and * uses the free callback specified in chre/util/nanoapp/callbacks.h @@ -55,7 +61,7 @@ void sendEmptyMessageToHost(uint16_t hostEndpointId, uint32_t messageType); /** - * Sends a message to the host. + * Sends a message to the host with default NanoappPermissions (CHRE_PERMS_NONE) * * @param hostEndpointId The endpoint Id of the host to send the message to. * @param message The proto message struct pointer. @@ -65,6 +71,21 @@ void sendMessageToHost(uint16_t hostEndpointId, const void *message, const pb_field_t *fields, uint32_t messageType); +/** + * Sends a message to the host with the provided NanoappPermissions. + * + * @param hostEndpointId The endpoint Id of the host to send the message to. + * @param message The proto message struct pointer. + * @param fields The fields descriptor of the proto message to encode. + * @param messageType The message type of the message. + @param perms The NanoappPermissions associated with the message. + */ +void sendMessageToHostWithPermissions(uint16_t hostEndpointId, + const void *message, + const pb_field_t *fields, + uint32_t messageType, + chre::NanoappPermissions perms); + } // namespace test_shared } // namespace chre
diff --git a/apps/test/common/shared/src/send_message.cc b/apps/test/common/shared/src/send_message.cc index 9f600fc..949f7fd 100644 --- a/apps/test/common/shared/src/send_message.cc +++ b/apps/test/common/shared/src/send_message.cc
@@ -17,19 +17,17 @@ #include "send_message.h" #include <pb_encode.h> -#include <cinttypes> #include "chre/util/nanoapp/callbacks.h" #include "chre/util/nanoapp/log.h" +#include "chre/util/system/napp_permissions.h" #include "chre_api/chre.h" -#include "chre_test_common.nanopb.h" #ifndef LOG_TAG #define LOG_TAG "[TestShared]" #endif -namespace chre { -namespace test_shared { +namespace chre::test_shared { namespace { bool encodeErrorMessage(pb_ostream_t *stream, const pb_field_t * /*field*/, @@ -45,6 +43,21 @@ } // namespace +chre_test_common_TestResult makeTestResultProtoMessage(bool success, + const char *errMessage) { + chre_test_common_TestResult testResult = + chre_test_common_TestResult_init_default; + testResult.has_code = true; + testResult.code = success ? chre_test_common_TestResult_Code_PASSED + : chre_test_common_TestResult_Code_FAILED; + if (!success && errMessage != nullptr) { + testResult.errorMessage = {.funcs = {.encode = encodeErrorMessage}, + .arg = const_cast<char *>(errMessage)}; + LOGE("%s", errMessage); + } + return testResult; +} + void sendTestResultWithMsgToHost(uint16_t hostEndpointId, uint32_t messageType, bool success, const char *errMessage, bool abortOnFailure) { @@ -55,15 +68,8 @@ success = false; } - chre_test_common_TestResult result = chre_test_common_TestResult_init_default; - result.has_code = true; - result.code = success ? chre_test_common_TestResult_Code_PASSED - : chre_test_common_TestResult_Code_FAILED; - if (!success && errMessage != nullptr) { - result.errorMessage = {.funcs = {.encode = encodeErrorMessage}, - .arg = const_cast<char *>(errMessage)}; - LOGE("%s", errMessage); - } + chre_test_common_TestResult result = + makeTestResultProtoMessage(success, errMessage); sendMessageToHost(hostEndpointId, &result, chre_test_common_TestResult_fields, messageType); @@ -95,6 +101,15 @@ void sendMessageToHost(uint16_t hostEndpointId, const void *message, const pb_field_t *fields, uint32_t messageType) { + sendMessageToHostWithPermissions(hostEndpointId, message, fields, messageType, + chre::NanoappPermissions::CHRE_PERMS_NONE); +} + +void sendMessageToHostWithPermissions(uint16_t hostEndpointId, + const void *message, + const pb_field_t *fields, + uint32_t messageType, + chre::NanoappPermissions perms) { size_t size; if (!pb_get_encoded_size(&size, fields, message)) { LOGE("Failed to get message size"); @@ -107,15 +122,13 @@ if (!pb_encode(&stream, fields, message)) { LOGE("Failed to encode message error %s", PB_GET_ERROR(&stream)); chreHeapFree(bytes); - } else if (!chreSendMessageToHostEndpoint(bytes, size, messageType, - hostEndpointId, - heapFreeMessageCallback)) { + } else if (!chreSendMessageWithPermissions( + bytes, size, messageType, hostEndpointId, + static_cast<uint32_t>(perms), heapFreeMessageCallback)) { LOGE("Failed to send message to host"); } } } } -} // namespace test_shared - -} // namespace chre +} // namespace chre::test_shared
diff --git a/apps/wifi_world/wifi_world.cc b/apps/wifi_world/wifi_world.cc index b0f2eb0..92767c6 100644 --- a/apps/wifi_world/wifi_world.cc +++ b/apps/wifi_world/wifi_world.cc
@@ -208,8 +208,6 @@ if (result->cookie != &kOnDemandScanCookie) { LOGE("On-demand scan cookie mismatch"); } - - requestDelayedWifiScan(); } else if (result->requestType == CHRE_WIFI_REQUEST_TYPE_RANGING) { uint64_t timeSinceRequest = chreGetTime() - gLastRangingTimeNs; if (result->success) { @@ -277,9 +275,10 @@ * @param event a pointer to the details of the WiFi scan event. */ void handleWifiScanEvent(const chreWifiScanEvent *event) { - LOGI("Received Wifi scan event of type %" PRIu8 " with %" PRIu8 - " results at %" PRIu64 "ns", - event->scanType, event->resultCount, event->referenceTime); + LOGI("Received Wifi scan event of type %" PRIu8 " index %" PRIu8 + " with %" PRIu8 "/%" PRIu8 " results completed at %" PRIu64 "ns", + event->scanType, event->eventIndex, event->resultCount, + event->resultTotal, event->referenceTime); if (gPendingOnDemandScan) { uint64_t timeSinceRequest = chreGetTime() - gLastRequestTimeNs; @@ -349,6 +348,8 @@ } else { LOGE("Received invalid timer handle"); } + + requestDelayedWifiScan(); } } // namespace
diff --git a/build/common.mk b/build/common.mk index 8de6ed4..7a3a490 100644 --- a/build/common.mk +++ b/build/common.mk
@@ -47,8 +47,8 @@ include $(CHRE_PREFIX)/build/clean.mk include $(CHRE_PREFIX)/build/tools_config.mk -# Flag config -include $(CHRE_PREFIX)/build/embedded_flags.mk +# Flag config (currently disabled) +# include $(CHRE_PREFIX)/build/embedded_flags.mk # NanoPB Source Generation include $(CHRE_PREFIX)/build/nanopb.mk
diff --git a/build/nanopb.mk b/build/nanopb.mk index 75d77af..57a287e 100644 --- a/build/nanopb.mk +++ b/build/nanopb.mk
@@ -204,13 +204,15 @@ $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ --out-dir=$(PW_RPC_GEN_PATH)/py/pw_rpc/internal \ --compile-dir=$(dir $<) --sources $(PW_RPC_GENERATOR_PROTO) \ - --language python + --language python \ + --no-experimental-editions $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) \ --plugin-path=$(PIGWEED_DIR)/pw_protobuf/py/pw_protobuf/plugin.py \ --compile-dir=$(dir $<) --sources $(PW_RPC_GENERATOR_PROTO) \ - --language pwpb + --language pwpb \ + --no-experimental-editions # Generated PW RPC Files ####################################################### @@ -266,7 +268,7 @@ # Pigweed RPC sources COMMON_SRCS += $(PIGWEED_DIR)/pw_assert_log/assert_log.cc -COMMON_SRCS += $(PIGWEED_DIR)/pw_containers/intrusive_list.cc +COMMON_SRCS += $(PIGWEED_DIR)/pw_containers/intrusive_item.cc COMMON_SRCS += $(PIGWEED_DIR)/pw_protobuf/decoder.cc COMMON_SRCS += $(PIGWEED_DIR)/pw_protobuf/encoder.cc COMMON_SRCS += $(PIGWEED_DIR)/pw_protobuf/stream_decoder.cc @@ -326,26 +328,31 @@ $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ --plugin-path=$(NANOPB_PROTOC) \ --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language nanopb \ + --no-experimental-editions \ --sources $< $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ --plugin-path=$(PIGWEED_DIR)/pw_protobuf/py/pw_protobuf/plugin.py \ --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language pwpb \ + --no-experimental-editions \ --sources $< $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_nanopb.py \ --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language nanopb_rpc \ + --no-experimental-editions \ --sources $< $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_raw.py \ --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language raw_rpc \ + --no-experimental-editions \ --sources $< $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_pwpb.py \ --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language pwpb_rpc \ + --no-experimental-editions \ --sources $< $(PW_RPC_GEN_PATH)/%.pb.c \ @@ -359,26 +366,31 @@ $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ --plugin-path=$(NANOPB_PROTOC) \ --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language nanopb \ + --no-experimental-editions \ --sources $< $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ --plugin-path=$(PIGWEED_DIR)/pw_protobuf/py/pw_protobuf/plugin.py \ --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language pwpb \ + --no-experimental-editions \ --sources $< $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_nanopb.py \ --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language nanopb_rpc \ + --no-experimental-editions \ --sources $< $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_raw.py \ --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language raw_rpc \ + --no-experimental-editions \ --sources $< $(V)$(PW_RPC_GENERATOR_CMD) $(PW_RPC_PROTO_GENERATOR) \ --plugin-path=$(PIGWEED_DIR)/pw_rpc/py/pw_rpc/plugin_pwpb.py \ --out-dir=$(PW_RPC_GEN_PATH)/$(dir $<) --compile-dir=$(dir $<) --language pwpb_rpc \ + --no-experimental-editions \ --sources $< endif # ifneq ($(PW_RPC_SRCS),)
diff --git a/build/sys_support/qcom/chre.scons b/build/sys_support/qcom/chre.scons deleted file mode 100644 index f911d59..0000000 --- a/build/sys_support/qcom/chre.scons +++ /dev/null
@@ -1,382 +0,0 @@ -# Copyright (C) 2019 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -#=============================================================================== -# -# CHRE builder scons -# -# GENERAL DESCRIPTION -# Build script used to build the CHRE library for use on SLPI -# -#------------------------------------------------------------------------------- - -Import('env') -import os - -#------------------------------------------------------------------------------- -# Configure optional features -#------------------------------------------------------------------------------- - -# There are two options to configure the optional features that CHRE bundles in: -# 1. Set the flags below to True/False depending on which features are desired -# 2. Set the command-line flag -f USES_CHRE_BUILD_FLAGS to ignore the defaults -# and control the features by presence of -f USES_CHRE_WIFI, etc. in the -# command line flags -USE_CHRE_AUDIO = False # not currently supported -if 'USES_CHRE_BUILD_FLAGS' not in env: - # Option 1 - USE_CHRE_GNSS = True - USE_CHRE_WIFI = True - USE_CHRE_WWAN = True -else: - # Option 2 - USE_CHRE_GNSS = 'USES_CHRE_GNSS' in env - USE_CHRE_WIFI = 'USES_CHRE_WIFI' in env - USE_CHRE_WWAN = 'USES_CHRE_WWAN' in env - -#------------------------------------------------------------------------------- -# Configure testing nanoapps -#------------------------------------------------------------------------------- - -# CHRE provides several nanoapps that can be used to verify that APIs are -# working as expected. To use these nanoapps, set 1 or more of the following -# flags to True and recompile CHRE. Once restarted, CHRE will load the enabled -# nanoapps -LOAD_GNSS_WORLD = False -LOAD_SENSOR_WORLD = False -LOAD_WIFI_WORLD = False -LOAD_WWAN_WORLD = False - -TESTING_NANOAPPS_ENABLED = False -if LOAD_GNSS_WORLD or LOAD_SENSOR_WORLD or LOAD_WIFI_WORLD or LOAD_WWAN_WORLD: - TESTING_NANOAPPS_ENABLED = True - -#------------------------------------------------------------------------------- -# Setup source and tooling paths -#------------------------------------------------------------------------------- -SRCPATH = "${BUILD_ROOT}/chre/chre/src" -LIBNAME = 'libchre_slpi_skel' -env.VariantDir('${BUILDPATH}', SRCPATH, duplicate=0) -LIB_ROOT = "${BUILD_ROOT}/chre/chre" - -target_so = '${BUILDPATH}/'+LIBNAME+'.so' -hexagon_root = env.get('HEXAGON_ROOT') -hexgaon_rtos_release = env.get('HEXAGON_RTOS_RELEASE') -hexagon_version = env.get('Q6VERSION') -HEXAGON_LIB_PATH = "{0}/{1}/Tools/target/hexagon/lib/{2}/G0/pic".format(hexagon_root, - hexgaon_rtos_release,hexagon_version) - -#------------------------------------------------------------------------------- -# Setup various env flags -#------------------------------------------------------------------------------- -env.Replace(ASM_DFLAGS = '-D__V_DYNAMIC__') -env.Replace(CC_DFLAGS = '-D__V_DYNAMIC__') -env.Replace(HEXAGONCC_OPT = ' -Os ') -env.Replace(CFLAGS = ' -G0') - -env.Replace(HEXAGONCC_WARN = '-Wall -Wno-cast-align -Wpointer-arith -Wno-missing-braces' \ - ' -Wno-strict-aliasing -Wstrict-prototypes -Wnested-externs -Werror') -env.Replace(HEXAGON_UNDEF = ' ') -env.Replace(HEXAGON_LANIND = '-fno-exceptions -fno-strict-aliasing -fno-zero-initialized-in-bss' \ - ' -fdata-sections -fno-signed-char -fdiagnostics-show-option ') -env.Append(SHCXXFLAGS = ' -std=c++11 ') -env.Append(SHLINKFLAGS = '-G0 --wrap=malloc --wrap=calloc --wrap=free --wrap=realloc --wrap=memalign' \ - ' --wrap=__stack_chk_fail -call_shared ') - -env['SKEL_DEP'] = '' -if USE_CHRE_GNSS: - env['SKEL_DEP'] += ' ${BUILD_ROOT}/chre/chre_drv_loc/build/${BUILDPATH}/chre_drv_loc.so ' - env.Depends(target_so,'${BUILD_ROOT}/chre/chre_drv_loc/build/${BUILDPATH}/chre_drv_loc.so') - -if USE_CHRE_WIFI: - env['SKEL_DEP'] += ' ${BUILD_ROOT}/chre/chre_drv_wifi/build/${BUILDPATH}/chre_drv_wifi.so ' \ - ' ${BUILD_ROOT}/chre/lowi_client/build/${BUILDPATH}/lowi_client.so ' - env.Depends(target_so,'${BUILD_ROOT}/chre/chre_drv_wifi/build/${BUILDPATH}/chre_drv_wifi.so') - env.Depends(target_so,'${BUILD_ROOT}/chre/lowi_client/build/${BUILDPATH}/lowi_client.so') - -if USE_CHRE_WWAN: - env['SKEL_DEP'] += ' ${BUILD_ROOT}/chre/chre_drv_modem/build/${BUILDPATH}/chre_drv_modem.so ' - env.Depends(target_so,'${BUILD_ROOT}/chre/chre_drv_modem/build/${BUILDPATH}/chre_drv_modem.so') - -env.Replace(QDSP6OBJS1= '${QDSP6_RELEASE_DIR}/Tools/target/hexagon/lib/${Q6VERSION}/G0/pic/initS.o') -env.Replace(QDSP6OBJS3= ['${QDSP6_RELEASE_DIR}/Tools/target/hexagon/lib/${Q6VERSION}/G0/pic/libgcc.a', - '${QDSP6_RELEASE_DIR}/Tools/target/hexagon/lib/${Q6VERSION}/G0/pic/libstdc++.a', - '${QDSP6_RELEASE_DIR}/Tools/target/hexagon/lib/${Q6VERSION}/G0/pic/libc++.a']) -env.Replace(QDSP6OBJS4= '${QDSP6_RELEASE_DIR}/Tools/target/hexagon/lib/${Q6VERSION}/G0/pic/finiS.o') - -env['SHLINKGRP'] = ' -shared -fPIC -Bsymbolic --start-group $QDSP6OBJS1 $QDSP6OBJS3 $SOURCES.posix' \ - ' $QDSP6OBJS4 $SKEL_DEP --end-group ${HEXAGONLD_MAP_CMD} ${TARGET.posix}.map' - -# Tells SCons to link various shared libraries against the CHRE library (drivers, various Hexagon libraries). -env.Replace(SHLINKCOM="${TEMPFILE('$SHLINK $SHLINKFLAGS $HEXAGON_OUTPUT_CMD $TARGET.posix $SHLINKGRP')}") - -#------------------------------------------------------------------------------- -# Ensure required libraries are available to the CHRE source code -#------------------------------------------------------------------------------- -core_public_apis = [ - 'KERNEL', - 'SERVICES', - 'DEBUGTOOLS', - 'ADSPPM', - 'POWER', - 'MPROC', - 'SYSTEMDRIVERS', - 'DEBUGTRACE', - 'DAL', - 'DIAG', - 'BUSES', -] - -platform_public_apis = [ - 'PLATFORM_LIBS', - 'MOD_TABLE', - 'QAIC', - 'STDDEF', - 'REMOTE', - 'HAPSDK', - 'DLW', - 'PLS', - 'UTILS', - 'ADSP_MMAP', - 'A1STD', - 'RTLD', -] - -qmimsgs_public_apis = [ - 'COMMON', - 'SNS_CLIENT_API', -] - -chre_priv_api = [ - "${BUILD_ROOT}/chre/chre/src/system/chre/chre_api/include", - "${BUILD_ROOT}/chre/chre/src/system/chre/chre_api/include/chre_api", - "${BUILD_ROOT}/chre/chre/src/system/chre/core/include", - "${BUILD_ROOT}/chre/chre/src/system/chre/external/flatbuffers/include", - "${BUILD_ROOT}/chre/chre/src/system/chre/pal/include", - "${BUILD_ROOT}/chre/chre/src/system/chre/platform/include", - "${BUILD_ROOT}/chre/chre/src/system/chre/platform/shared/include", - "${BUILD_ROOT}/chre/chre/src/system/chre/platform/slpi", - "${BUILD_ROOT}/chre/chre/src/system/chre/platform/slpi/include", - "${BUILD_ROOT}/chre/chre/src/system/chre/platform/slpi/see/include", - "${BUILD_ROOT}/chre/chre/src/system/chre/util/include", - "${BUILD_ROOT}/core/api/kernel/libstd/stringl", - "${BUILD_ROOT}/qmimsgs/common/api", - "${BUILD_ROOT}/ssc_api/pb", - "${BUILD_ROOT}/ssc/framework/cm/inc", - "${BUILD_ROOT}/ssc/inc", - "${BUILD_ROOT}/ssc/inc/internal", - "${BUILD_ROOT}/ssc/inc/utils/nanopb", -] - -if TESTING_NANOAPPS_ENABLED: - chre_priv_api.append("${BUILD_ROOT}/chre/chre/src/system/chre/apps/include") - -env.PublishPrivateApi('CHRE', chre_priv_api) - -env.RequirePublicApi(core_public_apis, area='core') -env.RequirePublicApi(platform_public_apis, area='platform') -env.RequirePublicApi(qmimsgs_public_apis, area='qmimsgs') -env.RequirePublicApi(['SNS_API_INCLUDES'], area='ssc_api') -env.RequirePrivateApi('CHRE') - -#------------------------------------------------------------------------------- -# Define various preprocessor definitions needed to compile CHRE -#------------------------------------------------------------------------------- - -oem_ver = os.environ.get('SCONS_OEM_BUILD_VER') -if oem_ver is not None: - oem_ver = str(oem_ver).strip().strip('"') -else: - oem_ver = 'undefined' - -CHRE_DEFINES = [ - 'CHRE_SLPI_DEFAULT_BUILD', - 'CHRE_MINIMUM_LOG_LEVEL=CHRE_LOG_LEVEL_DEBUG', - 'NANOAPP_MINIMUM_LOG_LEVEL=CHRE_LOG_LEVEL_DEBUG', - 'CHRE_ASSERTIONS_DISABLED', - 'CHRE_NANOAPP_INTERNAL', - 'CHRE_VERSION_STRING=\\\"' + oem_ver + '\\\"', - 'CHRE_PATCH_VERSION=1', - 'CHRE_FILENAME=__FILE__', - 'CHRE_PLATFORM_ID=0x476f6f676c000005', - 'CHRE_SEE_NUM_TEMP_SENSORS=1', - 'FLATBUFFERS_CHRE', - 'SSC_TARGET_HEXAGON', - 'CHRE_SLPI_SEE', - 'PB_FIELD_16BIT', - 'CHRE_MESSAGE_TO_HOST_MAX_SIZE=4000', - 'QDSP6', - 'CHRE_USE_FARF_LOGGING', -] - -if USE_CHRE_GNSS: - CHRE_DEFINES.append('CHRE_GNSS_SUPPORT_ENABLED') -if USE_CHRE_WIFI: - CHRE_DEFINES.append('CHRE_WIFI_SUPPORT_ENABLED') -if USE_CHRE_WWAN: - CHRE_DEFINES.append('CHRE_WWAN_SUPPORT_ENABLED') - -if TESTING_NANOAPPS_ENABLED: - CHRE_DEFINES.append('CHRE_INCLUDE_DEFAULT_STATIC_NANOAPPS') -if LOAD_GNSS_WORLD: - CHRE_DEFINES.append('CHRE_LOAD_GNSS_WORLD') -if LOAD_SENSOR_WORLD: - CHRE_DEFINES.append('CHRE_LOAD_SENSOR_WORLD') -if LOAD_WIFI_WORLD: - CHRE_DEFINES.append('CHRE_LOAD_WIFI_WORLD') -if LOAD_WWAN_WORLD: - CHRE_DEFINES.append('CHRE_LOAD_WWAN_WORLD') - -env.Append(CPPDEFINES = CHRE_DEFINES) - -#------------------------------------------------------------------------------- -# Setup source files to be built -#------------------------------------------------------------------------------- - -# Define path to the IDL file used to communicate with the host via FastRPC -libchre_slpi_skel_idl = "${BUILDPATH}/system/chre/host/msm/daemon/idl/chre_slpi.idl" - -# Compile chre_slpi.h from chre_slpi.idl, This is a prereq for the libchre_slpi_skel.so -prereq = env.HeaderBuilder("${BUILDPATH}/chre_slpi.h", libchre_slpi_skel_idl) - -chre_cc_src = [ - # QMI interfaces - "${BUILD_ROOT}/qmimsgs/common/src/common_v01.c", - "${BUILD_ROOT}/qmimsgs/sns_client_api/src/sns_client_api_v01.c", - - # Qualcomm protobufs needed by CHRE code - "${BUILD_ROOT}/ssc_api/build/${BUILDPATH}/pb/sns_amd.pb.c", - "${BUILD_ROOT}/ssc_api/build/${BUILDPATH}/pb/sns_client.pb.c", - "${BUILD_ROOT}/ssc_api/build/${BUILDPATH}/pb/sns_suid.pb.c", - "${BUILD_ROOT}/ssc_api/build/${BUILDPATH}/pb/sns_cal.pb.c", - "${BUILD_ROOT}/ssc_api/build/${BUILDPATH}/pb/sns_physical_sensor_test.pb.c", - "${BUILD_ROOT}/ssc_api/build/${BUILDPATH}/pb/sns_proximity.pb.c", - "${BUILD_ROOT}/ssc_api/build/${BUILDPATH}/pb/sns_remote_proc_state.pb.c", - "${BUILD_ROOT}/ssc_api/build/${BUILDPATH}/pb/sns_resampler.pb.c", - "${BUILD_ROOT}/ssc_api/build/${BUILDPATH}/pb/sns_std.pb.c", - "${BUILD_ROOT}/ssc_api/build/${BUILDPATH}/pb/sns_std_sensor.pb.c", - "${BUILD_ROOT}/ssc_api/build/${BUILDPATH}/pb/sns_std_type.pb.c", - - # Core CHRE framework code - "${BUILDPATH}/system/chre/core/debug_dump_manager.cc", - "${BUILDPATH}/system/chre/core/event.cc", - "${BUILDPATH}/system/chre/core/event_loop.cc", - "${BUILDPATH}/system/chre/core/event_loop_manager.cc", - "${BUILDPATH}/system/chre/core/event_ref_queue.cc", - "${BUILDPATH}/system/chre/core/host_comms_manager.cc", - "${BUILDPATH}/system/chre/core/init.cc", - "${BUILDPATH}/system/chre/core/nanoapp.cc", - "${BUILDPATH}/system/chre/core/sensor_request.cc", - "${BUILDPATH}/system/chre/core/sensor_request_manager.cc", - "${BUILDPATH}/system/chre/core/sensor_request_multiplexer.cc", - "${BUILDPATH}/system/chre/core/sensor.cc", - "${BUILDPATH}/system/chre/core/sensor_type.cc", - "${BUILDPATH}/system/chre/core/sensor_type_helpers.cc", - "${BUILDPATH}/system/chre/core/static_nanoapps.cc", - "${BUILDPATH}/system/chre/core/timer_pool.cc", - - # CHRE platform-specific implementation - "${BUILDPATH}/system/chre/platform/shared/chre_api_audio.cc", - "${BUILDPATH}/system/chre/platform/shared/chre_api_core.cc", - "${BUILDPATH}/system/chre/platform/shared/chre_api_gnss.cc", - "${BUILDPATH}/system/chre/platform/shared/chre_api_re.cc", - "${BUILDPATH}/system/chre/platform/shared/chre_api_sensor.cc", - "${BUILDPATH}/system/chre/platform/shared/chre_api_version.cc", - "${BUILDPATH}/system/chre/platform/shared/chre_api_wifi.cc", - "${BUILDPATH}/system/chre/platform/shared/chre_api_wwan.cc", - "${BUILDPATH}/system/chre/platform/shared/host_protocol_chre.cc", - "${BUILDPATH}/system/chre/platform/shared/host_protocol_common.cc", - "${BUILDPATH}/system/chre/platform/shared/memory_manager.cc", - "${BUILDPATH}/system/chre/platform/shared/nanoapp_load_manager.cc", - "${BUILDPATH}/system/chre/platform/shared/nanoapp/nanoapp_dso_util.cc", - "${BUILDPATH}/system/chre/platform/shared/pal_system_api.cc", - "${BUILDPATH}/system/chre/platform/shared/platform_debug_dump_manager.cc", - "${BUILDPATH}/system/chre/platform/shared/system_time.cc", - "${BUILDPATH}/system/chre/platform/slpi/chre_api_re.cc", - "${BUILDPATH}/system/chre/platform/slpi/host_link.cc", - "${BUILDPATH}/system/chre/platform/slpi/init.cc", - "${BUILDPATH}/system/chre/platform/slpi/memory.cc", - "${BUILDPATH}/system/chre/platform/slpi/memory_manager.cc", - "${BUILDPATH}/system/chre/platform/slpi/platform_nanoapp.cc", - "${BUILDPATH}/system/chre/platform/slpi/platform_pal.cc", - "${BUILDPATH}/system/chre/platform/slpi/platform_sensor_type_helpers.cc", - "${BUILDPATH}/system/chre/platform/slpi/system_time.cc", - "${BUILDPATH}/system/chre/platform/slpi/system_time_util.cc", - "${BUILDPATH}/system/chre/platform/slpi/system_timer.cc", - "${BUILDPATH}/system/chre/platform/slpi/see/island_vote_client.cc", - "${BUILDPATH}/system/chre/platform/slpi/see/platform_sensor.cc", - "${BUILDPATH}/system/chre/platform/slpi/see/platform_sensor_manager.cc", - "${BUILDPATH}/system/chre/platform/slpi/see/power_control_manager.cc", - "${BUILDPATH}/system/chre/platform/slpi/see/see_helper.cc", - "${BUILDPATH}/system/chre/platform/slpi/see/see_cal_helper.cc", - "${BUILDPATH}/system/chre/platform/slpi/see/sns_qmi_client.c", - - # Common utilities - "${BUILDPATH}/system/chre/util/system/debug_dump.cc", - "${BUILDPATH}/system/chre/util/buffer_base.cc", - "${BUILDPATH}/system/chre/util/dynamic_vector_base.cc", - "${BUILDPATH}/system/chre/util/hash.cc", - "${BUILDPATH}/system/chre/util/nanoapp/audio.cc", - "${BUILDPATH}/system/chre/util/nanoapp/ble.cc", - "${BUILDPATH}/system/chre/util/nanoapp/callbacks.cc", - "${BUILDPATH}/system/chre/util/nanoapp/debug.cc", - "${BUILDPATH}/system/chre/util/nanoapp/wifi.cc", -] - -if USE_CHRE_AUDIO: - chre_cc_src.extend([ - "${BUILDPATH}/system/chre/core/audio_request_manager.cc", - "${BUILDPATH}/system/chre/platform/slpi/platform_audio.cc", - ]) - -if USE_CHRE_GNSS: - chre_cc_src.extend([ - "${BUILDPATH}/system/chre/core/gnss_manager.cc", - "${BUILDPATH}/system/chre/platform/shared/platform_gnss.cc", - ]) - -if USE_CHRE_WIFI: - chre_cc_src.extend([ - "${BUILDPATH}/system/chre/core/wifi_request_manager.cc", - "${BUILDPATH}/system/chre/core/wifi_scan_request.cc", - "${BUILDPATH}/system/chre/platform/shared/platform_wifi.cc", - ]) - -if USE_CHRE_WWAN: - chre_cc_src.extend([ - "${BUILDPATH}/system/chre/core/wwan_request_manager.cc", - "${BUILDPATH}/system/chre/platform/shared/platform_wwan.cc", - ]) - -if LOAD_GNSS_WORLD: - chre_cc_src.append("${BUILDPATH}/system/chre/apps/gnss_world/gnss_world.cc") -if LOAD_SENSOR_WORLD: - chre_cc_src.append("${BUILDPATH}/system/chre/apps/sensor_world/sensor_world.cc") -if LOAD_WIFI_WORLD: - chre_cc_src.append("${BUILDPATH}/system/chre/apps/wifi_world/wifi_world.cc") -if LOAD_WWAN_WORLD: - chre_cc_src.append("${BUILDPATH}/system/chre/apps/wwan_world/wwan_world.cc") - -#------------------------------------------------------------------------------- -# Add CHRE as a shared library that should be built -#------------------------------------------------------------------------------- - -target = env.AddMySharedLibrary(['ADSP_SHARED_LIBS'], '${BUILDPATH}/'+LIBNAME, chre_cc_src, libchre_slpi_skel_idl) -env.Requires(target, prereq) - -# Clean / pack rules -CLEAN_LIST=[] -CLEAN_LIST.extend(env.FindFiles(['*'], LIB_ROOT + '/inc')) -CLEAN_LIST.extend(env.FindFiles(['*'], LIB_ROOT + '/src')) -env.CleanPack(['ADSP_SHARED_LIBS'], CLEAN_LIST)
diff --git a/build/variant/aosp_riscv55e03_tinysys.mk b/build/variant/aosp_riscv55e03_tinysys.mk index 616ca54..aacd366 100644 --- a/build/variant/aosp_riscv55e03_tinysys.mk +++ b/build/variant/aosp_riscv55e03_tinysys.mk
@@ -1,89 +1,10 @@ # -# Google Reference CHRE Implementation for MTK riscv (v55e03) Tinysys +# Google Reference CHRE Implementation for MTK riscv (55e03) Tinysys # -include $(CHRE_PREFIX)/build/clean_build_template_args.mk +RISCV_TARGET_NAME = aosp_riscv55e03_tinysys +RISCV_TARGET_PLATFORM_ID = 0x476f6f676c003000 +RISCV_TOOLCHAIN_TYPE = MRV55E03 +RISCV_CPU_TYPE = MRV55E03 -TARGET_NAME = aosp_riscv55e03_tinysys -ifneq ($(filter $(TARGET_NAME)% all, $(MAKECMDGOALS)),) - -ifneq ($(IS_NANOAPP_BUILD),) - # Inline functions of ctype.h for nanoapps - COMMON_CFLAGS += -DUSE_CHARSET_ASCII -else - # only enforce RISCV_TINYSYS_PREFIX when building CHRE - ifeq ($(RISCV_TINYSYS_PREFIX),) - $(error "The tinysys code directory needs to be exported as the RISCV_TINYSYS_PREFIX \ - environment variable") - endif -endif - -TARGET_CFLAGS = $(TINYSYS_CFLAGS) -TARGET_VARIANT_SRCS = $(TINYSYS_SRCS) -TARGET_BIN_LDFLAGS = $(AOSP_RISCV_TINYSYS_BIN_LDFLAGS) -TARGET_SO_EARLY_LIBS = $(AOSP_RISCV_TINYSYS_EARLY_LIBS) -TARGET_SO_LATE_LIBS = $(AOSP_RISCV_TINYSYS_LATE_LIBS) -TARGET_PLATFORM_ID = 0x476f6f676c003000 - -# Macros ####################################################################### -TINYSYS_CFLAGS += $(FLATBUFFERS_CFLAGS) -TINYSYS_CFLAGS += $(MBEDTLS_CFLAGS) - -TINYSYS_CFLAGS += -DCFG_DRAM_HEAP_SUPPORT -TINYSYS_CFLAGS += -DCHRE_LOADER_ARCH=EM_RISCV -TINYSYS_CFLAGS += -DCHRE_NANOAPP_LOAD_ALIGNMENT=4096 - -TINYSYS_CFLAGS += -D__riscv -TINYSYS_CFLAGS += -DMRV55 -TINYSYS_CFLAGS += -D_LIBCPP_HAS_NO_LONG_LONG - -TINYSYS_CFLAGS += --target=riscv32-unknown-elf -TINYSYS_CFLAGS += -march=rv32imafcv -TINYSYS_CFLAGS += -mcpu=MRV55E03 - -# Word size for this architecture -TARGET_CFLAGS += -DCHRE_32_BIT_WORD_SIZE - -# chre platform -TARGET_CFLAGS += -DCHRE_FIRST_SUPPORTED_API_VERSION=CHRE_API_VERSION_1_7 -TARGET_CFLAGS += -DCHRE_MESSAGE_TO_HOST_MAX_SIZE=4096 -TARGET_CFLAGS += -DCHRE_USE_BUFFERED_LOGGING -# enable static allocation in freertos -TINYSYS_CFLAGS += -DCFG_STATIC_ALLOCATE - -# Compiling flags ############################################################## - -# -fpic and -shared are only needed for dynamic linking -ifeq ($(IS_ARCHIVE_ONLY_BUILD),) -TARGET_SO_LDFLAGS += -shared -TARGET_CFLAGS += -fpic - -# Enable compiler-rt dependencies -LLVM_RTLIB=$(RISCV_TOOLCHAIN_PATH)/lib/clang/9.0.1/libpic/riscv32/MRV55E03 -TARGET_SO_LDFLAGS += -L$(LLVM_RTLIB) -TARGET_SO_LDFLAGS += -lclang_rt.builtins-riscv32 -endif - -ifneq ($(IS_NANOAPP_BUILD),) -# Used to expose libc headers to nanoapps that aren't supported on the given platform -TARGET_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/include/chre/platform/shared/libc - -TARGET_VARIANT_SRCS += $(DSO_SUPPORT_LIB_SRCS) -TARGET_CFLAGS += $(DSO_SUPPORT_LIB_CFLAGS) - -ifeq ($(CHRE_TCM_ENABLED),true) -TARGET_CFLAGS += -DCHRE_TCM_ENABLED -# Flags: -# Signed = 0x00000001 -# TCM-capable = 0x00000004 -TARGET_NANOAPP_FLAGS = 0x00000005 -endif -endif - -# Other makefiles ############################################################## - -include $(CHRE_PREFIX)/platform/shared/mbedtls/mbedtls.mk -include $(CHRE_PREFIX)/build/arch/riscv.mk -include $(CHRE_PREFIX)/build/build_template.mk -endif - +include $(CHRE_PREFIX)/build/variant/aosp_riscv_tinysys_common.mk \ No newline at end of file
diff --git a/build/variant/aosp_riscv55e300_tinysys.mk b/build/variant/aosp_riscv55e300_tinysys.mk index f8ffbf3..0c8c890 100644 --- a/build/variant/aosp_riscv55e300_tinysys.mk +++ b/build/variant/aosp_riscv55e300_tinysys.mk
@@ -1,90 +1,10 @@ # -# Google Reference CHRE Implementation for MTK riscv (v55e300) Tinysys +# Google Reference CHRE Implementation for MTK riscv (55e300) Tinysys # -include $(CHRE_PREFIX)/build/clean_build_template_args.mk +RISCV_TARGET_NAME = aosp_riscv55e300_tinysys +RISCV_TARGET_PLATFORM_ID = 0x476f6f676c003001 +RISCV_TOOLCHAIN_TYPE = MRV55E300 +RISCV_CPU_TYPE = MRV55E300 -TARGET_NAME = aosp_riscv55e300_tinysys -ifneq ($(filter $(TARGET_NAME)% all, $(MAKECMDGOALS)),) - -ifneq ($(IS_NANOAPP_BUILD),) - # Inline functions of ctype.h for nanoapps - COMMON_CFLAGS += -DUSE_CHARSET_ASCII -else - # only enforce RISCV_TINYSYS_PREFIX when building CHRE - ifeq ($(RISCV_TINYSYS_PREFIX),) - $(error "The tinysys code directory needs to be exported as the RISCV_TINYSYS_PREFIX \ - environment variable") - endif -endif - -TARGET_CFLAGS = $(TINYSYS_CFLAGS) -TARGET_VARIANT_SRCS = $(TINYSYS_SRCS) -TARGET_BIN_LDFLAGS = $(AOSP_RISCV_TINYSYS_BIN_LDFLAGS) -TARGET_SO_EARLY_LIBS = $(AOSP_RISCV_TINYSYS_EARLY_LIBS) -TARGET_SO_LATE_LIBS = $(AOSP_RISCV_TINYSYS_LATE_LIBS) -TARGET_PLATFORM_ID = 0x476f6f676c003001 - -# Macros ####################################################################### - -TINYSYS_CFLAGS += $(FLATBUFFERS_CFLAGS) -TINYSYS_CFLAGS += $(MBEDTLS_CFLAGS) - -TINYSYS_CFLAGS += -DCFG_DRAM_HEAP_SUPPORT -TINYSYS_CFLAGS += -DCHRE_LOADER_ARCH=EM_RISCV -TINYSYS_CFLAGS += -DCHRE_NANOAPP_LOAD_ALIGNMENT=4096 - -TINYSYS_CFLAGS += -D__riscv -TINYSYS_CFLAGS += -DMRV55 -TINYSYS_CFLAGS += -D_LIBCPP_HAS_NO_LONG_LONG - -TINYSYS_CFLAGS += --target=riscv32-unknown-elf -TINYSYS_CFLAGS += -march=rv32imafcv -TINYSYS_CFLAGS += -mcpu=MRV55E300 - -# Word size for this architecture -TARGET_CFLAGS += -DCHRE_32_BIT_WORD_SIZE - -# chre platform -TARGET_CFLAGS += -DCHRE_FIRST_SUPPORTED_API_VERSION=CHRE_API_VERSION_1_7 -# TODO(b/254121302): Needs to confirm with MTK about the max message size below -TARGET_CFLAGS += -DCHRE_MESSAGE_TO_HOST_MAX_SIZE=4096 -TARGET_CFLAGS += -DCHRE_USE_BUFFERED_LOGGING -# TODO(b/256870101): create mutex on heap for now -TARGET_CFLAGS += -DCHRE_CREATE_MUTEX_ON_HEAP - -# Compiling flags ############################################################## - -# -fpic and -shared are only needed for dynamic linking -ifeq ($(IS_ARCHIVE_ONLY_BUILD),) -TARGET_SO_LDFLAGS += -shared -TARGET_CFLAGS += -fpic - -# Enable compiler-rt dependencies -LLVM_RTLIB=$(RISCV_TOOLCHAIN_PATH)/lib/clang/12.0.0/libpic/riscv32/MRV55E300 -TARGET_SO_LDFLAGS += -L$(LLVM_RTLIB) -TARGET_SO_LDFLAGS += -lclang_rt.builtins-riscv32 -endif - -ifneq ($(IS_NANOAPP_BUILD),) -# Used to expose libc headers to nanoapps that aren't supported on the given platform -TARGET_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/include/chre/platform/shared/libc - -TARGET_VARIANT_SRCS += $(DSO_SUPPORT_LIB_SRCS) -TARGET_CFLAGS += $(DSO_SUPPORT_LIB_CFLAGS) - -ifeq ($(CHRE_TCM_ENABLED),true) -TARGET_CFLAGS += -DCHRE_TCM_ENABLED -# Flags: -# Signed = 0x00000001 -# TCM-capable = 0x00000004 -TARGET_NANOAPP_FLAGS = 0x00000005 -endif -endif - -# Other makefiles ############################################################## - -include $(CHRE_PREFIX)/platform/shared/mbedtls/mbedtls.mk -include $(CHRE_PREFIX)/build/arch/riscv.mk -include $(CHRE_PREFIX)/build/build_template.mk -endif +include $(CHRE_PREFIX)/build/variant/aosp_riscv_tinysys_common.mk \ No newline at end of file
diff --git a/build/variant/aosp_riscv_tinysys_common.mk b/build/variant/aosp_riscv_tinysys_common.mk new file mode 100644 index 0000000..136f2a4 --- /dev/null +++ b/build/variant/aosp_riscv_tinysys_common.mk
@@ -0,0 +1,92 @@ +# +# Google Reference CHRE Implementation for common MTK riscv Tinysys platforms. +# + +# Having a clean start +include $(CHRE_PREFIX)/build/clean_build_template_args.mk + +TARGET_NAME = $(RISCV_TARGET_NAME) +TARGET_PLATFORM_ID = $(RISCV_TARGET_PLATFORM_ID) + +ifneq ($(filter $(TARGET_NAME)% all, $(MAKECMDGOALS)),) + TARGET_CFLAGS = $(TINYSYS_CFLAGS) + TARGET_VARIANT_SRCS = $(TINYSYS_SRCS) + TARGET_BIN_LDFLAGS = $(AOSP_RISCV_TINYSYS_BIN_LDFLAGS) + TARGET_SO_EARLY_LIBS = $(AOSP_RISCV_TINYSYS_EARLY_LIBS) + TARGET_SO_LATE_LIBS = $(AOSP_RISCV_TINYSYS_LATE_LIBS) + + ifneq ($(IS_NANOAPP_BUILD),) + # Inline functions of ctype.h for nanoapps + COMMON_CFLAGS += -DUSE_CHARSET_ASCII + + # Used to expose libc headers to nanoapps that aren't supported on the given platform + TARGET_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/include/chre/platform/shared/libc + + TARGET_VARIANT_SRCS += $(DSO_SUPPORT_LIB_SRCS) + TARGET_CFLAGS += $(DSO_SUPPORT_LIB_CFLAGS) + + ifeq ($(CHRE_TCM_ENABLED),true) + TARGET_CFLAGS += -DCHRE_TCM_ENABLED + # Flags: + # Signed = 0x00000001 + # TCM-capable = 0x00000004 + TARGET_NANOAPP_FLAGS = 0x00000005 + endif + else + # only enforce RISCV_TINYSYS_PREFIX when building CHRE + ifeq ($(RISCV_TINYSYS_PREFIX),) + $(error "The tinysys code directory needs to be exported as the RISCV_TINYSYS_PREFIX \ + environment variable") + endif + endif + + # Macros ####################################################################### + + TINYSYS_CFLAGS += -DCFG_DRAM_HEAP_SUPPORT + TINYSYS_CFLAGS += -DCHRE_LOADER_ARCH=EM_RISCV + TINYSYS_CFLAGS += -DCHRE_NANOAPP_LOAD_ALIGNMENT=4096 + + TINYSYS_CFLAGS += -DCFG_TASK_MULTINOTIFY_SUPPORT + TINYSYS_CFLAGS += -mllvm -enable-printf-opt=false + + TINYSYS_CFLAGS += -D__riscv + TINYSYS_CFLAGS += -DMRV55 + TINYSYS_CFLAGS += -D_LIBCPP_HAS_NO_LONG_LONG + + # Word size for this architecture + TARGET_CFLAGS += -DCHRE_32_BIT_WORD_SIZE + + # CHRE platform + TARGET_CFLAGS += -DCHRE_FIRST_SUPPORTED_API_VERSION=CHRE_API_VERSION_1_7 + TARGET_CFLAGS += -DCHRE_MESSAGE_TO_HOST_MAX_SIZE=4096 + TARGET_CFLAGS += -DCHRE_USE_BUFFERED_LOGGING + + # Enable static allocation in freertos + TINYSYS_CFLAGS += -DCFG_STATIC_ALLOCATE + TINYSYS_CFLAGS += -DconfigSUPPORT_STATIC_ALLOCATION=1 + + # Compiling flags ############################################################## + + TINYSYS_CFLAGS += $(FLATBUFFERS_CFLAGS) + TINYSYS_CFLAGS += $(MBEDTLS_CFLAGS) + TINYSYS_CFLAGS += -mcpu=$(RISCV_CPU_TYPE) + TINYSYS_CFLAGS += --target=riscv32-unknown-elf + TINYSYS_CFLAGS += -march=rv32imafcv + + # -fpic and -shared are only needed for dynamic linking + ifeq ($(IS_ARCHIVE_ONLY_BUILD),) + TARGET_SO_LDFLAGS += -shared + TARGET_CFLAGS += -fpic + + # Enable compiler-rt dependencies + LLVM_RTLIB=$(RISCV_TOOLCHAIN_PATH)/lib/clang/12.0.0/libpic/riscv32/$(RISCV_TOOLCHAIN_TYPE) + TARGET_SO_LDFLAGS += -L$(LLVM_RTLIB) + TARGET_SO_LDFLAGS += -lclang_rt.builtins-riscv32 + endif + + # Other makefiles ############################################################## + + include $(CHRE_PREFIX)/platform/shared/mbedtls/mbedtls.mk + include $(CHRE_PREFIX)/build/arch/riscv.mk + include $(CHRE_PREFIX)/build/build_template.mk +endif \ No newline at end of file
diff --git a/chpp/clients/gnss.c b/chpp/clients/gnss.c index d084b2c..18b0e94 100644 --- a/chpp/clients/gnss.c +++ b/chpp/clients/gnss.c
@@ -192,7 +192,8 @@ switch (rxHeader->command) { case CHPP_GNSS_OPEN: { chppClientProcessOpenResponse(&gnssClientContext->client, buf, len); - if (gnssClientContext->requestStateResyncPending) { + if (rxHeader->error == CHPP_APP_ERROR_NONE && + gnssClientContext->requestStateResyncPending) { gCallbacks->requestStateResync(); gnssClientContext->requestStateResyncPending = false; } @@ -326,18 +327,13 @@ chppClientCloseOpenRequests(&gnssClientContext->client, &kGnssClientConfig, false /* clearOnly */); - if (gnssClientContext->client.openState != CHPP_OPEN_STATE_OPENED && - !gnssClientContext->client.pseudoOpen) { - CHPP_LOGW("GNSS client reset but wasn't open"); - } else { - CHPP_LOGD("GNSS client reopening from state=%" PRIu8, - gnssClientContext->client.openState); - gnssClientContext->requestStateResyncPending = true; - chppClientSendOpenRequest(&gGnssClientContext.client, - &gGnssClientContext.outReqStates[CHPP_GNSS_OPEN], - CHPP_GNSS_OPEN, - /*blocking=*/false); - } + CHPP_LOGD("GNSS client reopening from state=%" PRIu8, + gnssClientContext->client.openState); + gnssClientContext->requestStateResyncPending = true; + chppClientSendOpenRequest(&gGnssClientContext.client, + &gGnssClientContext.outReqStates[CHPP_GNSS_OPEN], + CHPP_GNSS_OPEN, + /*blocking=*/false); } /**
diff --git a/chpp/clients/wifi.c b/chpp/clients/wifi.c index 2f2b19b..87f28a3 100644 --- a/chpp/clients/wifi.c +++ b/chpp/clients/wifi.c
@@ -213,7 +213,9 @@ switch (rxHeader->command) { case CHPP_WIFI_OPEN: { chppClientProcessOpenResponse(&wifiClientContext->client, buf, len); - chppWiFiRecoverScanMonitor(wifiClientContext); + if (rxHeader->error == CHPP_APP_ERROR_NONE) { + chppWiFiRecoverScanMonitor(wifiClientContext); + } break; } @@ -376,17 +378,12 @@ false /* clearOnly */); chppCheckWifiScanEventNotificationReset(); - if (wifiClientContext->client.openState != CHPP_OPEN_STATE_OPENED && - !wifiClientContext->client.pseudoOpen) { - CHPP_LOGW("WiFi client reset but wasn't open"); - } else { - CHPP_LOGI("WiFi client reopening from state=%" PRIu8, - wifiClientContext->client.openState); - chppClientSendOpenRequest(&wifiClientContext->client, - &wifiClientContext->outReqStates[CHPP_WIFI_OPEN], - CHPP_WIFI_OPEN, - /*blocking=*/false); - } + CHPP_LOGI("WiFi client reopening from state=%" PRIu8, + wifiClientContext->client.openState); + chppClientSendOpenRequest(&wifiClientContext->client, + &wifiClientContext->outReqStates[CHPP_WIFI_OPEN], + CHPP_WIFI_OPEN, + /*blocking=*/false); } /** @@ -491,9 +488,10 @@ if (len < sizeof(struct ChppWifiConfigureScanMonitorAsyncResponse)) { // Short response length indicates an error - gCallbacks->scanMonitorStatusChangeCallback( - false, chppAppShortResponseErrorHandler(buf, len, "ScanMonitor")); - + uint8_t error = chppAppShortResponseErrorHandler(buf, len, "ScanMonitor"); + if (!gWifiClientContext.scanMonitorSilenceCallback) { + gCallbacks->scanMonitorStatusChangeCallback(false, error); + } } else { struct ChppWifiConfigureScanMonitorAsyncResponseParameters *result = &((struct ChppWifiConfigureScanMonitorAsyncResponse *)buf)->params; @@ -643,7 +641,7 @@ CHPP_WIFI_MAX_TIMESYNC_AGE_NS); uint64_t currentTime = chppGetCurrentTimeNs(); if (correctedTime > currentTime) { - CHPP_LOGD("WiFi scan time overcorrected %" PRIu64 " current %" PRIu64, + CHPP_LOGW("WiFi scan time overcorrected %" PRIu64 " current %" PRIu64, correctedTime / CHPP_NSEC_PER_MSEC, currentTime / CHPP_NSEC_PER_MSEC); correctedTime = currentTime; @@ -691,6 +689,13 @@ results[i].timestamp - (uint64_t)chppTimesyncGetOffset(gWifiClientContext.client.appContext, CHPP_WIFI_MAX_TIMESYNC_AGE_NS); + uint64_t currentTime = chppGetCurrentTimeNs(); + if (correctedTime > currentTime) { + CHPP_LOGW("WiFi ranging time overcorrected %" PRIu64 " current %" PRIu64, + correctedTime / CHPP_NSEC_PER_MSEC, + currentTime / CHPP_NSEC_PER_MSEC); + correctedTime = currentTime; + } CHPP_LOGD("WiFi ranging result time corrected from %" PRIu64 "to %" PRIu64, results[i].timestamp / CHPP_NSEC_PER_MSEC, correctedTime / CHPP_NSEC_PER_MSEC); @@ -946,10 +951,7 @@ CHPP_LOG_OOM(); } else { request->header.command = CHPP_WIFI_CONFIGURE_SCAN_MONITOR_ASYNC; - request->params.enable = enable; - request->params.cookie = - &gWifiClientContext - .outReqStates[CHPP_WIFI_CONFIGURE_SCAN_MONITOR_ASYNC]; + request->enable = enable; result = chppClientSendTimestampedRequestOrFail( &gWifiClientContext.client,
diff --git a/chpp/clients/wwan.c b/chpp/clients/wwan.c index 1ac8aa3..396a100 100644 --- a/chpp/clients/wwan.c +++ b/chpp/clients/wwan.c
@@ -247,17 +247,12 @@ chppClientCloseOpenRequests(&wwanClientContext->client, &kWwanClientConfig, false /* clearOnly */); - if (wwanClientContext->client.openState != CHPP_OPEN_STATE_OPENED && - !wwanClientContext->client.pseudoOpen) { - CHPP_LOGW("WWAN client reset but wasn't open"); - } else { - CHPP_LOGI("WWAN client reopening from state=%" PRIu8, - wwanClientContext->client.openState); - chppClientSendOpenRequest(&wwanClientContext->client, - &wwanClientContext->outReqStates[CHPP_WWAN_OPEN], - CHPP_WWAN_OPEN, - /*blocking=*/false); - } + CHPP_LOGI("WWAN client reopening from state=%" PRIu8, + wwanClientContext->client.openState); + chppClientSendOpenRequest(&wwanClientContext->client, + &wwanClientContext->outReqStates[CHPP_WWAN_OPEN], + CHPP_WWAN_OPEN, + /*blocking=*/false); } /**
diff --git a/chpp/include/chpp/common/wifi.h b/chpp/include/chpp/common/wifi.h index c1a6d2b..239a08b 100644 --- a/chpp/include/chpp/common/wifi.h +++ b/chpp/include/chpp/common/wifi.h
@@ -37,16 +37,9 @@ * Data structures used by the Configure Scan Monitor request. */ CHPP_PACKED_START -struct ChppWifiConfigureScanMonitorAsyncRequestParameters { - bool enable; - const void *cookie; -} CHPP_PACKED_ATTR; -CHPP_PACKED_END - -CHPP_PACKED_START struct ChppWifiConfigureScanMonitorAsyncRequest { struct ChppAppHeader header; - struct ChppWifiConfigureScanMonitorAsyncRequestParameters params; + bool enable; } CHPP_PACKED_ATTR; CHPP_PACKED_END
diff --git a/chpp/include/chpp/transport.h b/chpp/include/chpp/transport.h index f25b321..32d8cfe 100644 --- a/chpp/include/chpp/transport.h +++ b/chpp/include/chpp/transport.h
@@ -38,20 +38,11 @@ ***********************************************/ /** - * CHPP Transport layer reset timeout in ns. The transport layer will attempt - * another reset if the previous reset is not acked in time. - */ -#ifndef CHPP_TRANSPORT_RESET_TIMEOUT_NS -#define CHPP_TRANSPORT_RESET_TIMEOUT_NS \ - (UINT64_C(1500) * CHPP_NSEC_PER_MSEC) // 1500 ms -#endif - -/** * CHPP Transport layer timeout for tx packets. */ #ifndef CHPP_TRANSPORT_TX_TIMEOUT_NS #define CHPP_TRANSPORT_TX_TIMEOUT_NS \ - (UINT64_C(100) * CHPP_NSEC_PER_MSEC) // 100 ms + (UINT64_C(500) * CHPP_NSEC_PER_MSEC) // 500 ms #endif /** @@ -71,6 +62,15 @@ #endif /** + * CHPP Transport layer reset timeout in ns. The transport layer will attempt + * another reset if the previous reset is not acked in time. + */ +#ifndef CHPP_TRANSPORT_RESET_TIMEOUT_NS +#define CHPP_TRANSPORT_RESET_TIMEOUT_NS \ + (UINT64_C(1) * CHPP_TRANSPORT_TX_TIMEOUT_NS * (CHPP_TRANSPORT_MAX_RETX + 1)) +#endif + +/** * CHPP Transport layer maximum reset attempts. Current functional values are 1 * or higher (setting to 0 currently functions identically to 1). */
diff --git a/chpp/platform/linux/include/chpp/platform/platform_log.h b/chpp/platform/linux/include/chpp/platform/platform_log.h index 5fdcda7..604e421 100644 --- a/chpp/platform/linux/include/chpp/platform/platform_log.h +++ b/chpp/platform/linux/include/chpp/platform/platform_log.h
@@ -37,13 +37,16 @@ // TODO: Should use PRIu8 etc. from inttypes.h instead of %d, etc. (add -Wall // and -Werror to cflags to catch these) -#define CHPP_LINUX_LOG(level, color, fmt, ...) \ - { \ - char name[16]; \ - uint64_t ms = chppGetCurrentTimeNs() / 1000000; \ - pthread_getname_np(pthread_self(), name, 16); \ - printf("\e[" color "m[%" PRIu64 "] %s %s:%d\t (%s) " fmt "\e[0m\n", ms, \ - level, __FILENAME__, __LINE__, name, ##__VA_ARGS__); \ +#define CHPP_LINUX_LOG(level, color, fmt, ...) \ + { \ + char name[16]; \ + uint64_t currentTimeMs = chppGetCurrentTimeNs() / 1000000; \ + uint64_t sec = currentTimeMs / 1000; \ + uint64_t msec = currentTimeMs % 1000; \ + pthread_getname_np(pthread_self(), name, 16); \ + printf("\e[" color "m[%" PRIu64 ".%03" PRIu64 "] %s %s:%d\t (%s) " fmt \ + "\e[0m\n", \ + sec, msec, level, __FILENAME__, __LINE__, name, ##__VA_ARGS__); \ } #define CHPP_LOGE(fmt, ...) CHPP_LINUX_LOG("E", "91", fmt, ##__VA_ARGS__)
diff --git a/chpp/test/fake_link_sync_test.cpp b/chpp/test/fake_link_sync_test.cpp index f926dd6..d35152b 100644 --- a/chpp/test/fake_link_sync_test.cpp +++ b/chpp/test/fake_link_sync_test.cpp
@@ -191,4 +191,79 @@ EXPECT_FALSE(mFakeLink->waitForTxPacket()); } +// This test is essentially CheckRetryOnTimeout but with a twist: we send a +// packet, then don't send an ACK in the expected time so it gets retried, then +// after the retry, we send two equivalent ACKs back-to-back +TEST_F(FakeLinkSyncTests, DelayedThenDupeAck) { + // Post the TX packet + txPacket(); + ASSERT_TRUE(mFakeLink->waitForTxPacket()); + ASSERT_EQ(mFakeLink->getTxPacketCount(), 1); + (void)mFakeLink->popTxPacket(); // discard the first packet + + // Second wait should yield timeout + retry + ASSERT_TRUE(mFakeLink->waitForTxPacket()); + ASSERT_EQ(mFakeLink->getTxPacketCount(), 1); + + // Now deliver duplicate ACKs + ChppEmptyPacket ack = generateAck(mFakeLink->popTxPacket()); + chppRxDataCb(&mTransportContext, reinterpret_cast<uint8_t *>(&ack), + sizeof(ack)); + chppRxDataCb(&mTransportContext, reinterpret_cast<uint8_t *>(&ack), + sizeof(ack)); + + // We shouldn't get another packet (e.g. NAK) + EXPECT_FALSE(mFakeLink->waitForTxPacket()) + << "Got unexpected packet: " << asChpp(mFakeLink->popTxPacket()); + + // The next outbound packet should carry the next sequence number + txPacket(); + ASSERT_TRUE(mFakeLink->waitForTxPacket()); + EXPECT_EQ(asChpp(mFakeLink->popTxPacket()).header.seq, ack.header.ackSeq); +} + +// This tests the opposite side of DelayedThenDuplicateAck: confirms that if we +// receive a packet, then send an ACK, then we receive a duplicate, we send the +// ACK again +TEST_F(FakeLinkSyncTests, ResendAckOnDupe) { + // Note that seq and ackSeq should both be 1, since RESET/RESET_ACK will use 0 + constexpr uint8_t kSeq = 1; + constexpr uint8_t kAckSeq = 1; + auto rxPkt = generatePacketWithPayload<1>(kAckSeq, kSeq); + EXPECT_TRUE(chppRxDataCb(&mTransportContext, + reinterpret_cast<const uint8_t *>(&rxPkt), + sizeof(rxPkt))); + + ASSERT_TRUE(mFakeLink->waitForTxPacket()); + ASSERT_EQ(mFakeLink->getTxPacketCount(), 1); + std::vector<uint8_t> pkt = mFakeLink->popTxPacket(); + // We should get an ACK in response + EXPECT_TRUE(comparePacket(pkt, generateEmptyPacket(kSeq + 1))) + << "Expected first ACK for seq 1 but got: " << asEmptyPacket(pkt); + + // Pretend that we lost that ACK, so resend the same packet + EXPECT_TRUE(chppRxDataCb(&mTransportContext, + reinterpret_cast<const uint8_t *>(&rxPkt), + sizeof(rxPkt))); + + // We should get another ACK that matches the first + ASSERT_TRUE(mFakeLink->waitForTxPacket()); + ASSERT_EQ(mFakeLink->getTxPacketCount(), 1); + pkt = mFakeLink->popTxPacket(); + EXPECT_TRUE(comparePacket(pkt, generateEmptyPacket(kSeq + 1))) + << "Expected second ACK for seq 1 but got: " << asEmptyPacket(pkt); + + // Sending another packet should succeed + auto secondRxPkt = generatePacketWithPayload<2>(kAckSeq, kSeq + 1); + EXPECT_TRUE(chppRxDataCb(&mTransportContext, + reinterpret_cast<const uint8_t *>(&secondRxPkt), + sizeof(secondRxPkt))); + + ASSERT_TRUE(mFakeLink->waitForTxPacket()); + ASSERT_EQ(mFakeLink->getTxPacketCount(), 1); + pkt = mFakeLink->popTxPacket(); + EXPECT_TRUE(comparePacket(pkt, generateEmptyPacket(kSeq + 2))) + << "Expected ACK for seq 2 but got: " << asEmptyPacket(pkt); +} + } // namespace chpp::test
diff --git a/chpp/test/packet_util.cpp b/chpp/test/packet_util.cpp index 44a4b42..3617227 100644 --- a/chpp/test/packet_util.cpp +++ b/chpp/test/packet_util.cpp
@@ -16,6 +16,8 @@ #include "packet_util.h" +#include "chpp/app.h" + #include <cstring> namespace chpp::test { @@ -82,19 +84,134 @@ return pkt; } -ChppEmptyPacket generateAck(std::vector<uint8_t> &pkt) { +ChppEmptyPacket generateAck(const std::vector<uint8_t> &pkt) { // An ACK consists of an empty packet with the ackSeq set to the received // packet's seq + 1 (since ackSeq indicates the next seq value we expect), and // seq set to the received packet's ackSeq - 1 (since we don't increment seq // on empty packets and ackSeq indicates the next expected seq) - ChppTransportHeader &hdr = getHeader(pkt); + const ChppTransportHeader &hdr = getHeader(pkt); return generateEmptyPacket(/*acqSeq=*/hdr.seq + 1, /*seq=*/hdr.ackSeq - 1); } // Utilities for debugging ----------------------------------------------------- +const char *appErrorCodeToStr(uint8_t error) { + switch (error) { + case CHPP_APP_ERROR_NONE: + return "NONE"; + case CHPP_APP_ERROR_INVALID_COMMAND: + return "INVALID_COMMAND"; + case CHPP_APP_ERROR_INVALID_ARG: + return "INVALID_ARG"; + case CHPP_APP_ERROR_BUSY: + return "BUSY"; + case CHPP_APP_ERROR_OOM: + return "OOM"; + case CHPP_APP_ERROR_UNSUPPORTED: + return "UNSUPPORTED"; + case CHPP_APP_ERROR_TIMEOUT: + return "TIMEOUT"; + case CHPP_APP_ERROR_DISABLED: + return "DISABLED"; + case CHPP_APP_ERROR_RATELIMITED: + return "RATELIMITED"; + case CHPP_APP_ERROR_BLOCKED: + return "BLOCKED"; + case CHPP_APP_ERROR_INVALID_LENGTH: + return "INVALID_LENGTH"; + case CHPP_APP_ERROR_NOT_READY: + return "NOT_READY"; + case CHPP_APP_ERROR_BEYOND_CHPP: + return "BEYOND_CHPP"; + case CHPP_APP_ERROR_UNEXPECTED_RESPONSE: + return "UNEXPECTED_RESPONSE"; + case CHPP_APP_ERROR_CONVERSION_FAILED: + return "CONVERSION_FAILED"; + case CHPP_APP_ERROR_UNSPECIFIED: + return "UNSPECIFIED"; + default: + return "UNKNOWN"; + } +} + +const char *appMessageTypeToStr(uint8_t type) { + switch (type) { + case CHPP_MESSAGE_TYPE_CLIENT_REQUEST: + return "CLIENT_REQ"; + case CHPP_MESSAGE_TYPE_SERVICE_RESPONSE: + return "SERVICE_RESP"; + case CHPP_MESSAGE_TYPE_CLIENT_NOTIFICATION: + return "CLIENT_NOTIF"; + case CHPP_MESSAGE_TYPE_SERVICE_NOTIFICATION: + return "SERVICE_NOTIF"; + case CHPP_MESSAGE_TYPE_SERVICE_REQUEST: + return "SERVICE_REQ"; + case CHPP_MESSAGE_TYPE_CLIENT_RESPONSE: + return "CLIENT_RESP"; + default: + return "UNKNOWN"; + } +} + +const char *handleToStr(uint8_t handle) { + switch (handle) { + case CHPP_HANDLE_NONE: + return "(NONE)"; + case CHPP_HANDLE_LOOPBACK: + return "(LOOPBACK)"; + case CHPP_HANDLE_TIMESYNC: + return "(TIMESYNC)"; + case CHPP_HANDLE_DISCOVERY: + return "(DISCOVERY)"; + default: + return ""; + } +} + +const char *packetAttrToStr(uint8_t attr) { + switch (attr) { + case CHPP_TRANSPORT_ATTR_NONE: + return "none"; + case CHPP_TRANSPORT_ATTR_RESET: + return "reset"; + case CHPP_TRANSPORT_ATTR_RESET_ACK: + return "reset-ack"; + case CHPP_TRANSPORT_ATTR_LOOPBACK_REQUEST: + return "loopback-req"; + case CHPP_TRANSPORT_ATTR_LOOPBACK_RESPONSE: + return "loopback-rsp"; + default: + return "invalid"; + } +} + +const char *transportErrorToStr(uint8_t error) { + switch (error) { + case CHPP_TRANSPORT_ERROR_NONE: + return "none"; + case CHPP_TRANSPORT_ERROR_CHECKSUM: + return "checksum"; + case CHPP_TRANSPORT_ERROR_OOM: + return "oom"; + case CHPP_TRANSPORT_ERROR_BUSY: + return "busy"; + case CHPP_TRANSPORT_ERROR_HEADER: + return "header"; + case CHPP_TRANSPORT_ERROR_ORDER: + return "order"; + case CHPP_TRANSPORT_ERROR_TIMEOUT: + return "timeout"; + case CHPP_TRANSPORT_ERROR_MAX_RETRIES: + return "max-retries"; + case CHPP_TRANSPORT_ERROR_APPLAYER: + return "app-layer"; + default: + return "invalid"; + } +} + void dumpRaw(std::ostream &os, const void *ptr, size_t len) { - const char *buffer = static_cast<const char *>(ptr); + const uint8_t *buffer = static_cast<const uint8_t *>(ptr); char line[32]; char lineChars[32]; size_t offset = 0; @@ -150,64 +267,14 @@ } else { os << " (finished)"; } + uint8_t attr = CHPP_TRANSPORT_GET_ATTR(hdr.packetCode); + uint8_t error = CHPP_TRANSPORT_GET_ERROR(hdr.packetCode); os << std::endl << " packetCode: 0x" << std::hex << (unsigned)hdr.packetCode - << " (attr: "; - uint8_t attr = CHPP_TRANSPORT_GET_ATTR(hdr.packetCode); - switch (attr) { - case CHPP_TRANSPORT_ATTR_NONE: - os << "none"; - break; - case CHPP_TRANSPORT_ATTR_RESET: - os << "reset"; - break; - case CHPP_TRANSPORT_ATTR_RESET_ACK: - os << "reset-ack"; - break; - case CHPP_TRANSPORT_ATTR_LOOPBACK_REQUEST: - os << "loopback-req"; - break; - case CHPP_TRANSPORT_ATTR_LOOPBACK_RESPONSE: - os << "loopback-rsp"; - break; - default: - os << "invalid"; - } - os << " | error: "; - uint8_t error = CHPP_TRANSPORT_GET_ERROR(hdr.packetCode); - switch (error) { - case CHPP_TRANSPORT_ERROR_NONE: - os << "none"; - break; - case CHPP_TRANSPORT_ERROR_CHECKSUM: - os << "checksum"; - break; - case CHPP_TRANSPORT_ERROR_OOM: - os << "oom"; - break; - case CHPP_TRANSPORT_ERROR_BUSY: - os << "busy"; - break; - case CHPP_TRANSPORT_ERROR_HEADER: - os << "header"; - break; - case CHPP_TRANSPORT_ERROR_ORDER: - os << "order"; - break; - case CHPP_TRANSPORT_ERROR_TIMEOUT: - os << "timeout"; - break; - case CHPP_TRANSPORT_ERROR_MAX_RETRIES: - os << "max-retries"; - break; - case CHPP_TRANSPORT_ERROR_APPLAYER: - os << "app-layer"; - break; - default: - os << "invalid"; - } - os << ")" << std::endl - << " ackSeq: " << std::dec << (unsigned)hdr.ackSeq << std::endl + << " (attr: " << packetAttrToStr(attr) + << " | error: " << transportErrorToStr(error) << ")" << std::endl; + + os << " ackSeq: " << std::dec << (unsigned)hdr.ackSeq << std::endl << " seq: " << std::dec << (unsigned)hdr.seq << std::endl << " length: " << std::dec << hdr.length << std::endl << " reserved: " << std::dec << hdr.reserved << std::endl @@ -238,9 +305,30 @@ void dumpPacket(std::ostream &os, const ChppPacketPrefix &pkt) { dumpPreamble(os, pkt.preamble); dumpHeader(os, pkt.header); - os << "Payload {" << std::endl; - dumpRaw(os, pkt.payload, pkt.header.length); - os << "}" << std::endl; + size_t payloadOffset = 0; + if (CHPP_TRANSPORT_GET_ATTR(pkt.header.packetCode) == + CHPP_TRANSPORT_ATTR_NONE && + pkt.header.length >= sizeof(ChppAppHeader)) { + auto &appHdr = reinterpret_cast<const ChppAppHeader &>(*pkt.payload); + os << "AppHeader {" << std::endl; + os << " handle: 0x" << std::hex << (unsigned)appHdr.handle << " " + << handleToStr(appHdr.handle) << std::endl; + os << " type: " << std::dec << (unsigned)appHdr.type << " (" + << appMessageTypeToStr(appHdr.type) << ")" << std::endl; + os << " transaction: " << std::dec << (unsigned)appHdr.transaction + << std::endl; + os << " error: " << std::dec << (unsigned)appHdr.error << " (" + << appErrorCodeToStr(appHdr.error) << ")" << std::endl; + os << " command: " << std::dec << (unsigned)appHdr.command << std::endl; + os << "}" << std::endl; + payloadOffset = sizeof(ChppAppHeader); + } + size_t payloadSize = pkt.header.length - payloadOffset; + if (payloadSize > 0) { + os << "Payload (size " << payloadSize << ") {" << std::endl; + dumpRaw(os, &pkt.payload[payloadOffset], pkt.header.length - payloadOffset); + os << "}" << std::endl; + } const auto &footer = *reinterpret_cast<const ChppTransportFooter *>( &pkt.payload[pkt.header.length]);
diff --git a/chpp/test/packet_util.h b/chpp/test/packet_util.h index faedd08..42bceda 100644 --- a/chpp/test/packet_util.h +++ b/chpp/test/packet_util.h
@@ -18,12 +18,14 @@ * @file Utilities for working with raw CHPP packets in a test setting */ +#include <array> #include <cinttypes> #include <iostream> #include <vector> #include <gtest/gtest.h> +#include "chpp/app.h" #include "chpp/crc.h" #include "chpp/transport.h" @@ -53,6 +55,21 @@ uint8_t payload[1]; // Variable size per header.length } CHPP_PACKED_ATTR; +template <size_t kPayloadSize> +struct ChppPacketWithPayload { + uint16_t preamble; + ChppTransportHeader header; + uint8_t payload[kPayloadSize]; + ChppTransportFooter footer; +} CHPP_PACKED_ATTR; + +struct ChppPacketWithAppHeader { + uint16_t preamble; + ChppTransportHeader transportHeader; + ChppAppHeader appHeader; + uint8_t payload[]; +}; + // Utilities for packet creation ----------------------------------------------- //! Computes the CRC of one of the complete packet types defined above @@ -68,33 +85,72 @@ uint8_t error = CHPP_TRANSPORT_ERROR_NONE); //! Create an empty ACK packet for the given packet -ChppEmptyPacket generateAck(std::vector<uint8_t> &pkt); +ChppEmptyPacket generateAck(const std::vector<uint8_t> &pkt); + +//! Create a packet with payload of the given size. If a payload array is not +//! provided, it is set to all-zeros. +template <size_t kPayloadSize> +ChppPacketWithPayload<kPayloadSize> generatePacketWithPayload( + uint8_t ackSeq = 0, uint8_t seq = 0, + const std::span<uint8_t, kPayloadSize> *payload = nullptr) { + // clang-format off + ChppPacketWithPayload<kPayloadSize> pkt = { + .preamble = kPreamble, + .header = { + .flags = CHPP_TRANSPORT_FLAG_FINISHED_DATAGRAM, + .packetCode = static_cast<uint8_t>(CHPP_ATTR_AND_ERROR_TO_PACKET_CODE( + CHPP_TRANSPORT_ATTR_NONE, CHPP_TRANSPORT_ERROR_NONE)), + .ackSeq = ackSeq, + .seq = seq, + .length = kPayloadSize, + .reserved = 0, + }, + }; + // clang-format on + if (payload != nullptr) { + std::memcpy(pkt.payload, payload->data(), sizeof(pkt.payload)); + } + pkt.footer.checksum = computeCrc(pkt); + return pkt; +} // Utilities for packet parsing ------------------------------------------------ -inline ChppEmptyPacket &asEmptyPacket(std::vector<uint8_t> &pkt) { +inline const ChppEmptyPacket &asEmptyPacket(const std::vector<uint8_t> &pkt) { EXPECT_EQ(pkt.size(), sizeof(ChppEmptyPacket)); - return *reinterpret_cast<ChppEmptyPacket *>(pkt.data()); + return *reinterpret_cast<const ChppEmptyPacket *>(pkt.data()); } -inline ChppResetPacket &asResetPacket(std::vector<uint8_t> &pkt) { +inline const ChppResetPacket &asResetPacket(const std::vector<uint8_t> &pkt) { EXPECT_EQ(pkt.size(), sizeof(ChppResetPacket)); - return *reinterpret_cast<ChppResetPacket *>(pkt.data()); + return *reinterpret_cast<const ChppResetPacket *>(pkt.data()); } -inline ChppPacketPrefix &asChpp(std::vector<uint8_t> &pkt) { +inline const ChppPacketPrefix &asChpp(const std::vector<uint8_t> &pkt) { EXPECT_GE(pkt.size(), sizeof(ChppEmptyPacket)); - return *reinterpret_cast<ChppPacketPrefix *>(pkt.data()); + return *reinterpret_cast<const ChppPacketPrefix *>(pkt.data()); } -inline ChppTransportHeader &getHeader(std::vector<uint8_t> &pkt) { +inline const ChppTransportHeader &getHeader(const std::vector<uint8_t> &pkt) { static_assert(CHPP_PREAMBLE_LEN_BYTES == sizeof(uint16_t)); EXPECT_GE(pkt.size(), sizeof(uint16_t) + sizeof(ChppTransportHeader)); - return *reinterpret_cast<ChppTransportHeader *>(&pkt[sizeof(uint16_t)]); + return *reinterpret_cast<const ChppTransportHeader *>(&pkt[sizeof(uint16_t)]); +} + +inline const ChppPacketWithAppHeader &asApp(const std::vector<uint8_t> &pkt) { + EXPECT_GE(pkt.size(), + sizeof(ChppPacketWithAppHeader) + sizeof(ChppTransportFooter)); + return *reinterpret_cast<const ChppPacketWithAppHeader *>(pkt.data()); } // Utilities for debugging ----------------------------------------------------- +const char *appErrorCodeToStr(uint8_t error); +const char *appMessageTypeToStr(uint8_t type); +const char *handleToStr(uint8_t handle); +const char *packetAttrToStr(uint8_t attr); +const char *transportErrorToStr(uint8_t error); + //! Tuned for outputting a raw binary buffer (e.g. payload or full packet) void dumpRaw(std::ostream &os, const void *ptr, size_t len);
diff --git a/chpp/transport.c b/chpp/transport.c index 53687c0..5ba5751 100644 --- a/chpp/transport.c +++ b/chpp/transport.c
@@ -540,7 +540,7 @@ */ static void chppProcessResetAck(struct ChppTransportState *context) { if (context->resetState == CHPP_RESET_STATE_NONE) { - CHPP_LOGE("Unexpected reset-ack seq=%" PRIu8 " code=0x%" PRIx8, + CHPP_LOGW("Unexpected reset-ack seq=%" PRIu8 " code=0x%" PRIx8, context->rxHeader.seq, context->rxHeader.packetCode); // In a reset race condition with both endpoints sending resets and // reset-acks, the sent resets and reset-acks will both have a sequence @@ -604,8 +604,18 @@ // There are packets to send out (could be new or retx) // Note: For a future ACK window > 1, makes more sense to cap the NACKs // to one instead of flooding with out of order NACK errors. - chppEnqueueTxPacket(context, CHPP_ATTR_AND_ERROR_TO_PACKET_CODE( - CHPP_TRANSPORT_ATTR_NONE, errorCode)); + + // If the sender is retrying a packet we've already received successfully, + // send an ACK so it will continue normally + enum ChppTransportErrorCode errorCodeToSend = errorCode; + if (context->rxHeader.length > 0 && + context->rxHeader.seq == context->rxStatus.expectedSeq - 1) { + errorCodeToSend = CHPP_TRANSPORT_ERROR_NONE; + } + + chppEnqueueTxPacket( + context, CHPP_ATTR_AND_ERROR_TO_PACKET_CODE(CHPP_TRANSPORT_ATTR_NONE, + errorCodeToSend)); } if (errorCode == CHPP_TRANSPORT_ERROR_ORDER) { @@ -767,7 +777,8 @@ context->rxStatus.receivedAckSeq = rxAckSeq; if (context->txStatus.txAttempts > 1) { CHPP_LOGW("Seq %" PRIu8 " ACK'd after %" PRIuSIZE " reTX", - context->rxHeader.seq, context->txStatus.txAttempts - 1); + context->rxHeader.ackSeq - 1, + context->txStatus.txAttempts - 1); } context->txStatus.txAttempts = 0; @@ -1560,6 +1571,7 @@ // TODO(b/192359485): Consider removing this function, or making it more robust. void chppEnqueueTxErrorDatagram(struct ChppTransportState *context, enum ChppTransportErrorCode errorCode) { + chppMutexLock(&context->mutex); bool resetting = (context->resetState == CHPP_RESET_STATE_RESETTING); if (resetting) { CHPP_LOGE("Discarding app error 0x%" PRIx8 " (resetting)", errorCode); @@ -1582,6 +1594,7 @@ chppEnqueueTxPacket(context, CHPP_ATTR_AND_ERROR_TO_PACKET_CODE( CHPP_TRANSPORT_ATTR_NONE, errorCode)); } + chppMutexUnlock(&context->mutex); } uint64_t chppTransportGetTimeUntilNextDoWorkNs( @@ -1688,11 +1701,13 @@ const uint64_t currentTimeNs = chppGetCurrentTimeNs(); const bool isTxTimeout = currentTimeNs - context->txStatus.lastTxTimeNs >= CHPP_TRANSPORT_TX_TIMEOUT_NS; + const bool isResetting = context->resetState == CHPP_RESET_STATE_RESETTING; // Call chppTransportDoWork for both TX and request timeouts. if (isTxTimeout) { - CHPP_LOGE("ACK timeout. Tx t=%" PRIu64, - context->txStatus.lastTxTimeNs / CHPP_NSEC_PER_MSEC); + CHPP_LOGE("ACK timeout. Tx t=%" PRIu64 ", attempt %zu, isResetting=%d", + context->txStatus.lastTxTimeNs / CHPP_NSEC_PER_MSEC, + context->txStatus.txAttempts, isResetting); chppTransportDoWork(context); } else { const uint64_t requestTimeoutNs = @@ -1704,9 +1719,8 @@ } } - if ((context->resetState == CHPP_RESET_STATE_RESETTING) && - (currentTimeNs - context->resetTimeNs >= - CHPP_TRANSPORT_RESET_TIMEOUT_NS)) { + if (isResetting && (currentTimeNs - context->resetTimeNs >= + CHPP_TRANSPORT_RESET_TIMEOUT_NS)) { if (context->resetCount + 1 < CHPP_TRANSPORT_MAX_RESET) { CHPP_LOGE("RESET-ACK timeout; retrying"); context->resetCount++; @@ -1714,6 +1728,7 @@ CHPP_TRANSPORT_ERROR_TIMEOUT); } else { CHPP_LOGE("RESET-ACK timeout; giving up"); + context->txStatus.txAttempts = 0; context->resetState = CHPP_RESET_STATE_PERMANENT_FAILURE; chppClearTxDatagramQueue(context); }
diff --git a/chre_api/CMakeLists.txt b/chre_api/CMakeLists.txt new file mode 100644 index 0000000..26e429d --- /dev/null +++ b/chre_api/CMakeLists.txt
@@ -0,0 +1,34 @@ +include($ENV{PW_ROOT}/pw_build/pigweed.cmake) +include(backend.cmake) + +# The interface which provides the base CHRE API for nanoapps including +# "chre.h", "chre/version.h", etc. +# +# Note that this does not implement the interface, this is done either by the +# runtime or the nanoapp support lib DSO for dynamic nanoapp builds -- neither +# of which nanoapps are permitted to directly depend on. +pw_add_facade(chre.chre_api INTERFACE + BACKEND + chre.chre_api_BACKEND + HEADERS + include/chre_api/chre.h + include/chre_api/chre/audio.h + include/chre_api/chre/ble.h + include/chre_api/chre/common.h + include/chre_api/chre/event.h + include/chre_api/chre/gnss.h + include/chre_api/chre/nanoapp.h + include/chre_api/chre/re.h + include/chre_api/chre/sensor.h + include/chre_api/chre/sensor_types.h + include/chre_api/chre/toolchain.h + include/chre_api/chre/user_settings.h + include/chre_api/chre/version.h + include/chre_api/chre/wifi.h + include/chre_api/chre/wwan.h + PUBLIC_INCLUDES + include + include/chre_api + PUBLIC_DEPS + chre.variant.config +)
diff --git a/chre_api/backend.cmake b/chre_api/backend.cmake new file mode 100644 index 0000000..e4c9d8b --- /dev/null +++ b/chre_api/backend.cmake
@@ -0,0 +1,6 @@ +include_guard(GLOBAL) + +include($ENV{PW_ROOT}/pw_build/pigweed.cmake) + +# Backend for chre.chre_api. +pw_add_backend_variable(chre.chre_api_BACKEND)
diff --git a/chre_api/include/chre_api/chre/ble.h b/chre_api/include/chre_api/chre/ble.h index dc8e900..230fe7d 100644 --- a/chre_api/include/chre_api/chre/ble.h +++ b/chre_api/include/chre_api/chre/ble.h
@@ -56,16 +56,16 @@ * @{ */ //! No BLE APIs are supported -#define CHRE_BLE_CAPABILITIES_NONE UINT32_C(0) +#define CHRE_BLE_CAPABILITIES_NONE (UINT32_C(0)) //! CHRE supports BLE scanning -#define CHRE_BLE_CAPABILITIES_SCAN UINT32_C(1 << 0) +#define CHRE_BLE_CAPABILITIES_SCAN (UINT32_C(1) << 0) //! CHRE BLE supports batching of scan results, either through Android-specific //! HCI (OCF: 0x156), or by the CHRE framework, internally. //! @since v1.7 Platforms with this capability must also support flushing scan //! results during a batched scan. -#define CHRE_BLE_CAPABILITIES_SCAN_RESULT_BATCHING UINT32_C(1 << 1) +#define CHRE_BLE_CAPABILITIES_SCAN_RESULT_BATCHING (UINT32_C(1) << 1) //! CHRE BLE scan supports best-effort hardware filtering. If filtering is //! available, chreBleGetFilterCapabilities() returns a bitmap indicating the @@ -74,10 +74,14 @@ //! must be met for this flag: //! If only one nanoapp is requesting BLE scans and there are no BLE scans from //! the AP, only filtered results will be provided to the nanoapp. -#define CHRE_BLE_CAPABILITIES_SCAN_FILTER_BEST_EFFORT UINT32_C(1 << 2) +#define CHRE_BLE_CAPABILITIES_SCAN_FILTER_BEST_EFFORT (UINT32_C(1) << 2) //! CHRE BLE supports reading the RSSI of a specified LE-ACL connection handle. -#define CHRE_BLE_CAPABILITIES_READ_RSSI UINT32_C(1 << 3) +#define CHRE_BLE_CAPABILITIES_READ_RSSI (UINT32_C(1) << 3) + +//! CHRE supports offloading a Bluetooth connection socket for bidirectional +//! data transfer over a Connection-Oriented Channel (COC). +#define CHRE_BLE_CAPABILITIES_LE_COC_SOCKET UINT32_C (UINT32_C(1) << 4) /** @} */ /** @@ -95,24 +99,24 @@ * @{ */ //! No CHRE BLE filters are supported -#define CHRE_BLE_FILTER_CAPABILITIES_NONE UINT32_C(0) +#define CHRE_BLE_FILTER_CAPABILITIES_NONE (UINT32_C(0)) //! CHRE BLE supports RSSI filters -#define CHRE_BLE_FILTER_CAPABILITIES_RSSI UINT32_C(1 << 1) +#define CHRE_BLE_FILTER_CAPABILITIES_RSSI (UINT32_C(1) << 1) //! CHRE BLE supports Broadcaster Address filters (Corresponding HCI OCF: //! 0x0157, Sub-command: 0x02) //! @since v1.9 -#define CHRE_BLE_FILTER_CAPABILITIES_BROADCASTER_ADDRESS UINT32_C(1 << 2) +#define CHRE_BLE_FILTER_CAPABILITIES_BROADCASTER_ADDRESS (UINT32_C(1) << 2) //! CHRE BLE supports Manufacturer Data filters (Corresponding HCI OCF: 0x0157, //! Sub-command: 0x06) //! @since v1.8 -#define CHRE_BLE_FILTER_CAPABILITIES_MANUFACTURER_DATA UINT32_C(1 << 6) +#define CHRE_BLE_FILTER_CAPABILITIES_MANUFACTURER_DATA (UINT32_C(1) << 6) //! CHRE BLE supports Service Data filters (Corresponding HCI OCF: 0x0157, //! Sub-command: 0x07) -#define CHRE_BLE_FILTER_CAPABILITIES_SERVICE_DATA UINT32_C(1 << 7) +#define CHRE_BLE_FILTER_CAPABILITIES_SERVICE_DATA (UINT32_C(1) << 7) /** @} */ /** @@ -194,6 +198,47 @@ */ #define CHRE_EVENT_BLE_SCAN_STATUS_CHANGE CHRE_BLE_EVENT_ID(5) +/** + * nanoappHandleEvent argument: struct chreBleSocketConnectionEvent + * + * This is a unicast event that is sent to a nanoapp when an offloaded socket is + * connected and is available to be used by the nanoapp. The nanoapp must call + * chreBleSocketAccept() to accept ownership of the socket and + * subscribe to CHRE_EVENT_BLE_SOCKET_PACKET events. + * + * @since v1.11 + */ +#define CHRE_EVENT_BLE_SOCKET_CONNECTION CHRE_BLE_EVENT_ID(6) + +/** + * nanoappHandleEvent argument: struct chreBleSocketDisconnectionEvent + * + * This is a unicast event that is sent to a nanoapp when an offloaded socket is + * disconnected and can no longer be used by the nanoapp. + * + * @since v1.11 + */ +#define CHRE_EVENT_BLE_SOCKET_DISCONNECTION CHRE_BLE_EVENT_ID(7) + +/** + * nanoappHandleEvent argument: struct chreBleSocketPacketEvent + * + * This event is sent when the nanoapp receives a packet from the offload + * socket. + * + * @since v1.11 + */ +#define CHRE_EVENT_BLE_SOCKET_PACKET CHRE_BLE_EVENT_ID(8) + +/** + * nanoappHandleEvent argument: NULL + * + * This event is sent when the socket is available to send packets again. + * + * @since v1.11 + */ +#define CHRE_EVENT_BLE_SOCKET_SEND_AVAILABLE CHRE_BLE_EVENT_ID(9) + // NOTE: Do not add new events with ID > 15 /** @} */ @@ -677,6 +722,102 @@ }; /** + * Notifies a nanoapp that a socket has been connected and offloaded and is + * ready to be used. The nanoapp is expected to accept ownership of the socket + * by calling the chreBleSocketAccept() API. If the nanoapp does not accept + * ownership of the socket, the transfer of ownership to the nanoapp is aborted. + * + * @since v1.11 + */ +struct chreBleSocketConnectionEvent { + //! Unique identifier for this socket connection. This ID in CHRE matches the + //! ID used on the host side. It is valid only while the socket is connected. + uint64_t socketId; + + //! Descriptive socket name provided by the host app that initiated the socket + //! offload request. This is not guaranteed to be unique across the system, + //! but can help the offload app understand the purpose of the socket when it + //! receives a socket connection event. This pointer is only valid for the + //! duration of the event. + const char *socketName; + + //! When sending a packet to the socket via chreBleSocketSend(), the length + //! must not exceed this value. + uint16_t maxTxPacketLength; + + //! When the nanoapp receives packets from the socket via the + //! chreBleSocketPacketEvent, the length will not exceed this value. + uint16_t maxRxPacketLength; +}; + +/** + * Notifies a nanoapp that a socket has been disconnected and can no longer be + * used by the nanoapp. Once a socket is disconnected, the same socket ID will + * not be reconnected. If the nanoapp wants to continue using an offloaded + * socket, a new offloaded socket must be created and connected. + * + * @since v1.11 + */ +struct chreBleSocketDisconnectionEvent { + //! @see chreBleSocketConnectionEvent.socketId + uint64_t socketId; +}; + +/** + * Notifies a nanoapp that it has received a packet from a socket. + * + * @since v1.11 + */ +struct chreBleSocketPacketEvent { + //! @see chreBleSocketConnectionEvent.socketId + uint64_t socketId; + + //! Length of data in bytes. The length will not exceed the maxRxPacketLength + //! provided in the CHRE event CHRE_EVENT_BLE_SOCKET_CONNECTION. + uint16_t length; + + //! Packet payload that is length bytes. + const uint8_t *data; +}; + +/** + * Result code used with chreBleSocketSend(). + * + * @since v1.11 + */ +enum chreBleSocketSendStatus { + //! The packet has successfully been sent to the platform layer. + CHRE_BLE_SOCKET_SEND_STATUS_SUCCESS = 1, + + //! The packet will not be sent. + CHRE_BLE_SOCKET_SEND_STATUS_FAILURE = 2, + + //! The packet cannot be sent at this time because too many packets are in + //! flight. The nanoapp will be notified via a + //! CHRE_EVENT_BLE_SOCKET_SEND_AVAILABLE event when the socket is available to + //! send the packet. + CHRE_BLE_SOCKET_SEND_STATUS_QUEUE_FULL = 3, +}; + +/** + * Callback which frees the packet sent via chreBleSocketSend(). + * + * This callback is (optionally) provided to the chreBleSocketSend() function as + * a means for freeing the packet. When this callback is invoked, the packet is + * no longer needed and can be released. Note that this in no way assures that + * said packet was sent to the offload socket, simply that this memory is no + * longer needed. + * + * @param data The data argument from chreBleSocketSend(). + * @param length The length argument from chreBleSocketSend(). + * + * @see chreBleSocketSend() + * + * @since v1.11 + */ +typedef void(chreBleSocketPacketFreeFunction)(void *data, uint16_t length); + +/** * Retrieves a set of flags indicating the BLE features supported by the * current CHRE implementation. The value returned by this function must be * consistent for the entire duration of the nanoapp's execution. @@ -938,6 +1079,52 @@ bool chreBleGetScanStatus(struct chreBleScanStatus *status); /** + * Accepts that this nanoapp owns the socket and subscribes to + * CHRE_EVENT_BLE_SOCKET_PACKET events from this socket. This API is only + * valid to call while handling the CHRE_EVENT_BLE_SOCKET_CONNECTION event. + * + * @param socketId @see chreBleSocketConnectionEvent.socketId + * @return True if CHRE confirms that socket ownership has been transferred. + * + * @since v1.11 + */ +bool chreBleSocketAccept(uint64_t socketId); + +/** + * Sends a packet to the socket with the corresponding socketId. This API can + * only be used after the nanoapp has received a + * CHRE_EVENT_BLE_SOCKET_CONNECTION event indicating the offloaded socket is + * connected and has accepted ownership of the socket by calling + * chreBleSocketAccept(). + * + * NOTE: freeCallback WILL NOT be invoked if the return status is + * CHRE_BLE_SOCKET_SEND_STATUS_QUEUE_FULL. + * + * @param socketId @see chreBleSocketConnectionEvent.socketId + * @param data Packet to be sent to the socket that is length bytes. After this + * API is called, ownership of this memory passes to CHRE and the nanoapp + * must ensure that the packet remains valid and unmodified until the + * freeCallback is invoked. + * @param length Length of packet to be sent to the socket in bytes. Cannot + * exceed the maxTxPacketLength provided in the CHRE event + * CHRE_EVENT_BLE_SOCKET_CONNECTION. + * @param freeCallback Callback invoked to indicate that the packet data buffer + * is not needed by CHRE anymore. Note that invocation of this function does + * not mean that the packet has been delivered, only that memory can be + * released. This is guaranteed to be invoked if this function returns + * CHRE_BLE_SOCKET_SEND_STATUS_SUCCESS or + * CHRE_BLE_SOCKET_SEND_STATUS_FAILURE, but WILL NOT be invoked for + * CHRE_BLE_SOCKET_SEND_STATUS_QUEUE_FULL. This may be invoked + * synchronously, so nanoapp developers should not call chreBleSocketSend() + * from within the callback to avoid potential infinite recursion. + * @return A value from enum chreBleSocketSendStatus. + * + * @since v1.11 + */ +int32_t chreBleSocketSend(uint64_t socketId, const void *data, uint16_t length, + chreBleSocketPacketFreeFunction *freeCallback); + +/** * Definitions for handling unsupported CHRE BLE scenarios. */ #else // defined(CHRE_NANOAPP_USES_BLE) || !defined(CHRE_IS_NANOAPP_BUILD) @@ -958,6 +1145,15 @@ #define chreBleReadRssiAsync(...) \ CHRE_BUILD_ERROR(CHRE_BLE_PERM_ERROR_STRING "chreBleReadRssiAsync") +#define chreBleGetScanStatus(...) \ + CHRE_BUILD_ERROR(CHRE_BLE_PERM_ERROR_STRING "chreBleGetScanStatus") + +#define chreBleSocketAccept(...) \ + CHRE_BUILD_ERROR(CHRE_BLE_PERM_ERROR_STRING "chreBleSocketAccept") + +#define chreBleSocketSend(...) \ + CHRE_BUILD_ERROR(CHRE_BLE_PERM_ERROR_STRING "chreBleSocketSend") + #endif // defined(CHRE_NANOAPP_USES_BLE) || !defined(CHRE_IS_NANOAPP_BUILD) #ifdef __cplusplus
diff --git a/chre_api/include/chre_api/chre/event.h b/chre_api/include/chre_api/chre/event.h index d08b7d0..fb56733 100644 --- a/chre_api/include/chre_api/chre/event.h +++ b/chre_api/include/chre_api/chre/event.h
@@ -26,6 +26,7 @@ */ #include <stdbool.h> +#include <stddef.h> #include <stdint.h> #include <stdlib.h> @@ -202,6 +203,31 @@ #define CHRE_EVENT_RELIABLE_MSG_ASYNC_RESULT UINT16_C(0x000B) /** + * nanoappHandleEvent argument: struct chreMessageFromEndpointData + * + * The format of the 'message' part of this structure is left undefined, + * and it's up to the nanoapp and endpoint to have an established protocol + * beforehand. + * + * On receiving the first message from an endpoint, the nanoapp can assume + * a session with the sessionId has been created and can be used to send + * messages to the endpoint. The nanoapp will receive a + * CHRE_EVENT_ENDPOINT_SESSION_CLOSED event when the session is closed. + * + * @since v1.11 + */ +#define CHRE_EVENT_MESSAGE_FROM_ENDPOINT UINT16_C(0x000C) + +/** + * nanoappHandleEvent argument: struct chreEndpointSessionClosedData + * + * Indicates that a session with an endpoint has been closed. + * + * @since v1.11 + */ +#define CHRE_EVENT_ENDPOINT_SESSION_CLOSED UINT16_C(0x000D) + +/** * First possible value for CHRE_EVENT_SENSOR events. * * This allows us to separately define our CHRE_EVENT_SENSOR_* events in @@ -425,6 +451,68 @@ }; /** + * Data provided with CHRE_EVENT_MESSAGE_FROM_ENDPOINT. + */ +struct chreMessageFromEndpointData { + /** + * Message type supplied by the endpoint. + */ + uint32_t messageType; + + /** + * Message permissions supplied by the endpoint. The format is specified by + * the CHRE_MESSAGE_PERMISSION_* values if the endpoint is a nanoapp, else + * it is specified by the endpoint. These permissions are enforced by CHRE. + * A nanoapp without the required permissions will not receive the message. + */ + uint32_t messagePermissions; + + /** + * The message from the endpoint. + * + * These contents are of a format that the endpoint and nanoapp must have + * established beforehand. + * + * This data is 'messageSize' bytes in length. Note that if 'messageSize' + * is 0, this might contain NULL. + */ + const void *message; + + /** + * The size, in bytes of the following 'message'. + * + * This can be 0. + */ + size_t messageSize; + + /** + * The session ID of the message. A session is the active connection between + * two endpoints. The receiving nanoapp or endpoint initiated the session + * before sending this message. If the nanoapp has not yet received a + * message with this session ID, it can assume the session was created by + * the nanoapp or other endpoint. The nanoapp may send messages to the other + * endpoint with this session ID. + */ + uint16_t sessionId; +}; + +/** + * Data provided with CHRE_EVENT_ENDPOINT_SESSION_CLOSED. + */ +struct chreEndpointSessionClosedData { + /** + * The message hub ID and endpoint ID of the other party in the session. + */ + uint64_t hubId; + uint64_t endpointId; + + /** + * The ID of the session that was closed. + */ + uint16_t sessionId; +}; + +/** * Provides metadata for a nanoapp in the system. */ struct chreNanoappInfo { @@ -471,7 +559,7 @@ */ uint8_t rpcServiceCount; - /* + /** * Array of RPC services published by this nanoapp. * Services are published via chrePublishRpcServices. * The array contains rpcServiceCount entries.
diff --git a/chre_api/include/chre_api/chre/gnss.h b/chre_api/include/chre_api/chre/gnss.h index a326e85..75d0168 100644 --- a/chre_api/include/chre_api/chre/gnss.h +++ b/chre_api/include/chre_api/chre/gnss.h
@@ -55,21 +55,21 @@ */ //! A lack of flags indicates that GNSS is not supported in this CHRE -#define CHRE_GNSS_CAPABILITIES_NONE UINT32_C(0) +#define CHRE_GNSS_CAPABILITIES_NONE (UINT32_C(0)) //! GNSS position fixes are supported via chreGnssLocationSessionStartAsync() -#define CHRE_GNSS_CAPABILITIES_LOCATION UINT32_C(1 << 0) +#define CHRE_GNSS_CAPABILITIES_LOCATION (UINT32_C(1) << 0) //! GNSS raw measurements are supported via //! chreGnssMeasurementSessionStartAsync() -#define CHRE_GNSS_CAPABILITIES_MEASUREMENTS UINT32_C(1 << 1) +#define CHRE_GNSS_CAPABILITIES_MEASUREMENTS (UINT32_C(1) << 1) //! Location fixes supplied from chreGnssConfigurePassiveLocationListener() //! are tapped in at the GNSS engine level, so they include additional fixes //! such as those requested by the AP, and not just those requested by other //! nanoapps within CHRE (which is the case when this flag is not set) #define CHRE_GNSS_CAPABILITIES_GNSS_ENGINE_BASED_PASSIVE_LISTENER \ - UINT32_C(1 << 2) + (UINT32_C(1) << 2) /** @} */ @@ -120,34 +120,34 @@ // Flags indicating the Accumulated Delta Range's states // (ref: GnssAccumulatedDeltaRangeState) -#define CHRE_GNSS_ADR_STATE_UNKNOWN UINT16_C(0) -#define CHRE_GNSS_ADR_STATE_VALID UINT16_C(1 << 0) -#define CHRE_GNSS_ADR_STATE_RESET UINT16_C(1 << 1) -#define CHRE_GNSS_ADR_STATE_CYCLE_SLIP UINT16_C(1 << 2) +#define CHRE_GNSS_ADR_STATE_UNKNOWN (UINT16_C(0)) +#define CHRE_GNSS_ADR_STATE_VALID (UINT16_C(1) << 0) +#define CHRE_GNSS_ADR_STATE_RESET (UINT16_C(1) << 1) +#define CHRE_GNSS_ADR_STATE_CYCLE_SLIP (UINT16_C(1) << 2) // Flags to indicate what fields in chreGnssClock are valid (ref: GnssClockFlags) -#define CHRE_GNSS_CLOCK_HAS_LEAP_SECOND UINT16_C(1 << 0) -#define CHRE_GNSS_CLOCK_HAS_TIME_UNCERTAINTY UINT16_C(1 << 1) -#define CHRE_GNSS_CLOCK_HAS_FULL_BIAS UINT16_C(1 << 2) -#define CHRE_GNSS_CLOCK_HAS_BIAS UINT16_C(1 << 3) -#define CHRE_GNSS_CLOCK_HAS_BIAS_UNCERTAINTY UINT16_C(1 << 4) -#define CHRE_GNSS_CLOCK_HAS_DRIFT UINT16_C(1 << 5) -#define CHRE_GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY UINT16_C(1 << 6) +#define CHRE_GNSS_CLOCK_HAS_LEAP_SECOND (UINT16_C(1) << 0) +#define CHRE_GNSS_CLOCK_HAS_TIME_UNCERTAINTY (UINT16_C(1) << 1) +#define CHRE_GNSS_CLOCK_HAS_FULL_BIAS (UINT16_C(1) << 2) +#define CHRE_GNSS_CLOCK_HAS_BIAS (UINT16_C(1) << 3) +#define CHRE_GNSS_CLOCK_HAS_BIAS_UNCERTAINTY (UINT16_C(1) << 4) +#define CHRE_GNSS_CLOCK_HAS_DRIFT (UINT16_C(1) << 5) +#define CHRE_GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY (UINT16_C(1) << 6) // Flags to indicate which values are valid in a GpsLocation // (ref: GpsLocationFlags) -#define CHRE_GPS_LOCATION_HAS_LAT_LONG UINT16_C(1 << 0) -#define CHRE_GPS_LOCATION_HAS_ALTITUDE UINT16_C(1 << 1) -#define CHRE_GPS_LOCATION_HAS_SPEED UINT16_C(1 << 2) -#define CHRE_GPS_LOCATION_HAS_BEARING UINT16_C(1 << 3) -#define CHRE_GPS_LOCATION_HAS_ACCURACY UINT16_C(1 << 4) +#define CHRE_GPS_LOCATION_HAS_LAT_LONG (UINT16_C(1) << 0) +#define CHRE_GPS_LOCATION_HAS_ALTITUDE (UINT16_C(1) << 1) +#define CHRE_GPS_LOCATION_HAS_SPEED (UINT16_C(1) << 2) +#define CHRE_GPS_LOCATION_HAS_BEARING (UINT16_C(1) << 3) +#define CHRE_GPS_LOCATION_HAS_ACCURACY (UINT16_C(1) << 4) //! @since v1.3 -#define CHRE_GPS_LOCATION_HAS_ALTITUDE_ACCURACY UINT16_C(1 << 5) +#define CHRE_GPS_LOCATION_HAS_ALTITUDE_ACCURACY (UINT16_C(1) << 5) //! @since v1.3 -#define CHRE_GPS_LOCATION_HAS_SPEED_ACCURACY UINT16_C(1 << 6) +#define CHRE_GPS_LOCATION_HAS_SPEED_ACCURACY (UINT16_C(1) << 6) //! @since v1.3 -#define CHRE_GPS_LOCATION_HAS_BEARING_ACCURACY UINT16_C(1 << 7) +#define CHRE_GPS_LOCATION_HAS_BEARING_ACCURACY (UINT16_C(1) << 7) /** * The maximum number of instances of struct chreGnssMeasurement that may be @@ -161,21 +161,21 @@ #define CHRE_GNSS_MAX_MEASUREMENT_PRE_1_5 UINT8_C(64) // Flags indicating the GNSS measurement state (ref: GnssMeasurementState) -#define CHRE_GNSS_MEASUREMENT_STATE_UNKNOWN UINT16_C(0) -#define CHRE_GNSS_MEASUREMENT_STATE_CODE_LOCK UINT16_C(1 << 0) -#define CHRE_GNSS_MEASUREMENT_STATE_BIT_SYNC UINT16_C(1 << 1) -#define CHRE_GNSS_MEASUREMENT_STATE_SUBFRAME_SYNC UINT16_C(1 << 2) -#define CHRE_GNSS_MEASUREMENT_STATE_TOW_DECODED UINT16_C(1 << 3) -#define CHRE_GNSS_MEASUREMENT_STATE_MSEC_AMBIGUOUS UINT16_C(1 << 4) -#define CHRE_GNSS_MEASUREMENT_STATE_SYMBOL_SYNC UINT16_C(1 << 5) -#define CHRE_GNSS_MEASUREMENT_STATE_GLO_STRING_SYNC UINT16_C(1 << 6) -#define CHRE_GNSS_MEASUREMENT_STATE_GLO_TOD_DECODED UINT16_C(1 << 7) -#define CHRE_GNSS_MEASUREMENT_STATE_BDS_D2_BIT_SYNC UINT16_C(1 << 8) -#define CHRE_GNSS_MEASUREMENT_STATE_BDS_D2_SUBFRAME_SYNC UINT16_C(1 << 9) -#define CHRE_GNSS_MEASUREMENT_STATE_GAL_E1BC_CODE_LOCK UINT16_C(1 << 10) -#define CHRE_GNSS_MEASUREMENT_STATE_GAL_E1C_2ND_CODE_LOCK UINT16_C(1 << 11) -#define CHRE_GNSS_MEASUREMENT_STATE_GAL_E1B_PAGE_SYNC UINT16_C(1 << 12) -#define CHRE_GNSS_MEASUREMENT_STATE_SBAS_SYNC UINT16_C(1 << 13) +#define CHRE_GNSS_MEASUREMENT_STATE_UNKNOWN (UINT16_C(0)) +#define CHRE_GNSS_MEASUREMENT_STATE_CODE_LOCK (UINT16_C(1) << 0) +#define CHRE_GNSS_MEASUREMENT_STATE_BIT_SYNC (UINT16_C(1) << 1) +#define CHRE_GNSS_MEASUREMENT_STATE_SUBFRAME_SYNC (UINT16_C(1) << 2) +#define CHRE_GNSS_MEASUREMENT_STATE_TOW_DECODED (UINT16_C(1) << 3) +#define CHRE_GNSS_MEASUREMENT_STATE_MSEC_AMBIGUOUS (UINT16_C(1) << 4) +#define CHRE_GNSS_MEASUREMENT_STATE_SYMBOL_SYNC (UINT16_C(1) << 5) +#define CHRE_GNSS_MEASUREMENT_STATE_GLO_STRING_SYNC (UINT16_C(1) << 6) +#define CHRE_GNSS_MEASUREMENT_STATE_GLO_TOD_DECODED (UINT16_C(1) << 7) +#define CHRE_GNSS_MEASUREMENT_STATE_BDS_D2_BIT_SYNC (UINT16_C(1) << 8) +#define CHRE_GNSS_MEASUREMENT_STATE_BDS_D2_SUBFRAME_SYNC (UINT16_C(1) << 9) +#define CHRE_GNSS_MEASUREMENT_STATE_GAL_E1BC_CODE_LOCK (UINT16_C(1) << 10) +#define CHRE_GNSS_MEASUREMENT_STATE_GAL_E1C_2ND_CODE_LOCK (UINT16_C(1) << 11) +#define CHRE_GNSS_MEASUREMENT_STATE_GAL_E1B_PAGE_SYNC (UINT16_C(1) << 12) +#define CHRE_GNSS_MEASUREMENT_STATE_SBAS_SYNC (UINT16_C(1) << 13) #define CHRE_GNSS_MEASUREMENT_CARRIER_FREQUENCY_UNKNOWN 0.f
diff --git a/chre_api/include/chre_api/chre/re.h b/chre_api/include/chre_api/chre/re.h index 8d76987..24ebff6 100644 --- a/chre_api/include/chre_api/chre/re.h +++ b/chre_api/include/chre_api/chre/re.h
@@ -73,11 +73,11 @@ */ //! None of the optional capabilities are supported -#define CHRE_CAPABILITIES_NONE UINT32_C(0) +#define CHRE_CAPABILITIES_NONE (UINT32_C(0)) //! Support for reliable messages. //! @see chreSendReliableMessageAsync() -#define CHRE_CAPABILITIES_RELIABLE_MESSAGES UINT32_C(1 << 0) +#define CHRE_CAPABILITIES_RELIABLE_MESSAGES (UINT32_C(1) << 0) /** @} */
diff --git a/chre_api/include/chre_api/chre/version.h b/chre_api/include/chre_api/chre/version.h index 8f4e3d6..3dc4984 100644 --- a/chre_api/include/chre_api/chre/version.h +++ b/chre_api/include/chre_api/chre/version.h
@@ -164,12 +164,22 @@ * This version of the CHRE API is shipped with Android V. It adds support for * reliable messaging. * + * @see CHRE_API_VERSION + */ +#define CHRE_API_VERSION_1_10 UINT32_C(0x010a0000) + +/** + * Value for version 1.11 of the Context Hub Runtime Environment API interface. + * + * This version of the CHRE API is shipped with Android 16. It adds definitions + * for WWAN Cell Neighbors. + * * @note This version of the CHRE API has not been finalized yet, and is * currently considered a preview that is subject to change. * * @see CHRE_API_VERSION */ -#define CHRE_API_VERSION_1_10 UINT32_C(0x010a0000) +#define CHRE_API_VERSION_1_11 UINT32_C(0x010b0000) /** * Major and Minor Version of this Context Hub Runtime Environment API. @@ -188,7 +198,7 @@ * Note that version numbers can always be numerically compared with * expected results, so 1.0.0 < 1.0.4 < 1.1.0 < 2.0.300 < 3.5.0. */ -#define CHRE_API_VERSION CHRE_API_VERSION_1_10 +#define CHRE_API_VERSION CHRE_API_VERSION_1_11 /** * Utility macro to extract only the API major version of a composite CHRE
diff --git a/chre_api/include/chre_api/chre/wifi.h b/chre_api/include/chre_api/chre/wifi.h index 44d3d41..e02f419 100644 --- a/chre_api/include/chre_api/chre/wifi.h +++ b/chre_api/include/chre_api/chre/wifi.h
@@ -64,29 +64,29 @@ */ //! No WiFi APIs are supported -#define CHRE_WIFI_CAPABILITIES_NONE UINT32_C(0) +#define CHRE_WIFI_CAPABILITIES_NONE (UINT32_C(0)) //! Listening to scan results is supported, as enabled via //! chreWifiConfigureScanMonitorAsync() -#define CHRE_WIFI_CAPABILITIES_SCAN_MONITORING UINT32_C(1 << 0) +#define CHRE_WIFI_CAPABILITIES_SCAN_MONITORING (UINT32_C(1) << 0) //! Requesting WiFi scans on-demand is supported via chreWifiRequestScanAsync() -#define CHRE_WIFI_CAPABILITIES_ON_DEMAND_SCAN UINT32_C(1 << 1) +#define CHRE_WIFI_CAPABILITIES_ON_DEMAND_SCAN (UINT32_C(1) << 1) //! Specifying the radio chain preference in on-demand scan requests, and //! reporting it in scan events is supported //! @since v1.2 -#define CHRE_WIFI_CAPABILITIES_RADIO_CHAIN_PREF UINT32_C(1 << 2) +#define CHRE_WIFI_CAPABILITIES_RADIO_CHAIN_PREF (UINT32_C(1) << 2) //! Requesting RTT ranging is supported via chreWifiRequestRangingAsync() //! @since v1.2 -#define CHRE_WIFI_CAPABILITIES_RTT_RANGING UINT32_C(1 << 3) +#define CHRE_WIFI_CAPABILITIES_RTT_RANGING (UINT32_C(1) << 3) //! Specifies if WiFi NAN service subscription is supported. If a platform //! supports subscriptions, then it must also support RTT ranging for NAN //! services via chreWifiNanRequestRangingAsync() //! @since v1.6 -#define CHRE_WIFI_CAPABILITIES_NAN_SUB UINT32_C(1 << 4) +#define CHRE_WIFI_CAPABILITIES_NAN_SUB (UINT32_C(1) << 4) /** @} */ @@ -226,8 +226,8 @@ * @{ */ -#define CHRE_WIFI_BAND_MASK_2_4_GHZ UINT8_C(1 << 0) //!< 2.4 GHz -#define CHRE_WIFI_BAND_MASK_5_GHZ UINT8_C(1 << 1) //!< 5 GHz +#define CHRE_WIFI_BAND_MASK_2_4_GHZ (UINT8_C(1) << 0) //!< 2.4 GHz +#define CHRE_WIFI_BAND_MASK_5_GHZ (UINT8_C(1) << 1) //!< 5 GHz /** @} */ @@ -237,17 +237,17 @@ * @{ */ -#define CHRE_WIFI_SCAN_RESULT_FLAGS_NONE UINT8_C(0) +#define CHRE_WIFI_SCAN_RESULT_FLAGS_NONE UINT8_C(0) //! Element ID 61 (HT Operation) is present (see HT 7.3.2) -#define CHRE_WIFI_SCAN_RESULT_FLAGS_HT_OPS_PRESENT UINT8_C(1 << 0) +#define CHRE_WIFI_SCAN_RESULT_FLAGS_HT_OPS_PRESENT (UINT8_C(1) << 0) //! Element ID 192 (VHT Operation) is present (see VHT 8.4.2) -#define CHRE_WIFI_SCAN_RESULT_FLAGS_VHT_OPS_PRESENT UINT8_C(1 << 1) +#define CHRE_WIFI_SCAN_RESULT_FLAGS_VHT_OPS_PRESENT (UINT8_C(1) << 1) //! Element ID 127 (Extended Capabilities) is present, and bit 70 (Fine Timing //! Measurement Responder) is set to 1 (see IEEE Std 802.11-2016 9.4.2.27) -#define CHRE_WIFI_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER UINT8_C(1 << 2) +#define CHRE_WIFI_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER (UINT8_C(1) << 2) //! Retained for backwards compatibility //! @see CHRE_WIFI_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER @@ -256,12 +256,13 @@ //! HT Operation element indicates that a secondary channel is present //! (see HT 7.3.2.57) -#define CHRE_WIFI_SCAN_RESULT_FLAGS_HAS_SECONDARY_CHANNEL_OFFSET UINT8_C(1 << 3) +#define CHRE_WIFI_SCAN_RESULT_FLAGS_HAS_SECONDARY_CHANNEL_OFFSET \ + (UINT8_C(1) << 3) //! HT Operation element indicates that the secondary channel is below the //! primary channel (see HT 7.3.2.57) #define CHRE_WIFI_SCAN_RESULT_FLAGS_SECONDARY_CHANNEL_OFFSET_IS_BELOW \ - UINT8_C(1 << 4) + (UINT8_C(1) << 4) /** @} */ @@ -273,23 +274,23 @@ * @{ */ -#define CHRE_WIFI_SECURITY_MODE_UNKNOWN UINT8_C(0) +#define CHRE_WIFI_SECURITY_MODE_UNKNOWN (UINT8_C(0)) //! @deprecated since v1.10. Use CHRE_WIFI_SECURITY_MODE_UNKNOWN instead. -#define CHRE_WIFI_SECURITY_MODE_UNKONWN CHRE_WIFI_SECURITY_MODE_UNKNOWN +#define CHRE_WIFI_SECURITY_MODE_UNKONWN CHRE_WIFI_SECURITY_MODE_UNKNOWN -#define CHRE_WIFI_SECURITY_MODE_OPEN UINT8_C(1 << 0) //!< No auth/security -#define CHRE_WIFI_SECURITY_MODE_WEP UINT8_C(1 << 1) -#define CHRE_WIFI_SECURITY_MODE_PSK UINT8_C(1 << 2) //!< WPA-PSK or WPA2-PSK -#define CHRE_WIFI_SECURITY_MODE_EAP UINT8_C(1 << 3) //!< WPA-EAP or WPA2-EAP +#define CHRE_WIFI_SECURITY_MODE_OPEN (UINT8_C(1) << 0) //!< No auth/security +#define CHRE_WIFI_SECURITY_MODE_WEP (UINT8_C(1) << 1) +#define CHRE_WIFI_SECURITY_MODE_PSK (UINT8_C(1) << 2) //!< WPA-PSK or WPA2-PSK +#define CHRE_WIFI_SECURITY_MODE_EAP (UINT8_C(1) << 3) //!< WPA-EAP or WPA2-EAP //! @since v1.5 -#define CHRE_WIFI_SECURITY_MODE_SAE UINT8_C(1 << 4) +#define CHRE_WIFI_SECURITY_MODE_SAE (UINT8_C(1) << 4) //! @since v1.5 -#define CHRE_WIFI_SECURITY_MODE_EAP_SUITE_B UINT8_C(1 << 5) +#define CHRE_WIFI_SECURITY_MODE_EAP_SUITE_B (UINT8_C(1) << 5) //! @since v1.5 -#define CHRE_WIFI_SECURITY_MODE_OWE UINT8_C(1 << 6) +#define CHRE_WIFI_SECURITY_MODE_OWE (UINT8_C(1) << 6) /** @} */ @@ -300,9 +301,9 @@ * @{ */ -#define CHRE_WIFI_RADIO_CHAIN_UNKNOWN UINT8_C(0) -#define CHRE_WIFI_RADIO_CHAIN_0 UINT8_C(1 << 0) -#define CHRE_WIFI_RADIO_CHAIN_1 UINT8_C(1 << 1) +#define CHRE_WIFI_RADIO_CHAIN_UNKNOWN (UINT8_C(0)) +#define CHRE_WIFI_RADIO_CHAIN_0 (UINT8_C(1) << 0) +#define CHRE_WIFI_RADIO_CHAIN_1 (UINT8_C(1) << 1) /** @} */ @@ -320,7 +321,7 @@ //! If set, the nested chreWifiLci structure is populated; otherwise it is //! invalid and must be ignored -#define CHRE_WIFI_RTT_RESULT_HAS_LCI UINT8_C(1 << 0) +#define CHRE_WIFI_RTT_RESULT_HAS_LCI (UINT8_C(1) << 0) /** @} */ @@ -1281,6 +1282,8 @@ * @param cookie An opaque value that will be included in the chreAsyncResult * sent in relation to this request. * @return true if the request was accepted for processing, false otherwise. + * @since v1.6 + * @note Requires WiFi permission */ bool chreWifiNanRequestRangingAsync(const struct chreWifiNanRangingParams *params, const void *cookie);
diff --git a/chre_api/include/chre_api/chre/wwan.h b/chre_api/include/chre_api/chre/wwan.h index dc46182..80cbf3d 100644 --- a/chre_api/include/chre_api/chre/wwan.h +++ b/chre_api/include/chre_api/chre/wwan.h
@@ -58,10 +58,16 @@ */ //! No WWAN APIs are supported -#define CHRE_WWAN_CAPABILITIES_NONE UINT32_C(0) +#define CHRE_WWAN_CAPABILITIES_NONE (UINT32_C(0)) //! Current cell information can be queried via chreWwanGetCellInfoAsync() -#define CHRE_WWAN_GET_CELL_INFO UINT32_C(1 << 0) +#define CHRE_WWAN_GET_CELL_INFO (UINT32_C(1) << 0) + +//! The chreWwanCellInfoResult from chreWwanGetCellInfoAsync() will include +//! all available chreWwanCellInfo as entries in cells, not just a single +//! primary result. +//! @since v1.11 - Neighbor support in prior versions of the API is unspecified. +#define CHRE_WWAN_GET_CELL_NEIGHBOR_INFO (UINT32_C(1) << 1) /** @} */
diff --git a/chre_api/legacy/v1_10/chre.h b/chre_api/legacy/v1_10/chre.h new file mode 100644 index 0000000..9b87d08 --- /dev/null +++ b/chre_api/legacy/v1_10/chre.h
@@ -0,0 +1,201 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _CHRE_H_ +#define _CHRE_H_ + +/** + * @file + * This header file includes all the headers which combine to fully define the + * interface for the Context Hub Runtime Environment (CHRE). This interface is + * of interest to both implementers of CHREs and authors of nanoapps. The API + * documentation attempts to address concerns of both. + * + * See individual header files for API details, and general comments below + * for overall platform information. + */ + +#include <chre/audio.h> +#include <chre/ble.h> +#include <chre/common.h> +#include <chre/event.h> +#include <chre/gnss.h> +#include <chre/nanoapp.h> +#include <chre/re.h> +#include <chre/sensor.h> +#include <chre/toolchain.h> +#include <chre/user_settings.h> +#include <chre/version.h> +#include <chre/wifi.h> +#include <chre/wwan.h> + +/** + * @mainpage + * CHRE is the Context Hub Runtime Environment. CHRE is used in Android to run + * contextual applications, called nanoapps, in a low-power processing domain + * other than the applications processor that runs Android itself. The CHRE + * API, documented herein, is the common interface exposed to nanoapps for any + * compatible CHRE implementation. The CHRE API provides the ability for + * creating nanoapps that are code-compatible across different CHRE + * implementations and underlying platforms. Refer to the following sections for + * a discussion on some important details of CHRE that aren't explicitly exposed + * in the API itself. + * + * @section entry_points Entry points + * + * The following entry points are used to bind a nanoapp to the CHRE system, and + * all three must be implemented by any nanoapp (see chre/nanoapp.h): + * - nanoappStart: initialization + * - nanoappHandleEvent: hook for event-driven processing + * - nanoappEnd: graceful teardown + * + * The CHRE implementation must also ensure that it performs these functions + * prior to invoking nanoappStart, or after nanoappEnd returns: + * - bss section zeroed out (prior to nanoappStart) + * - static variables initialized (prior to nanoappStart) + * - global C++ constructors called (prior to nanoappStart) + * - global C++ destructors called (after nanoappEnd) + * + * @section threading Threading model + * + * A CHRE implementation is free to choose among many different + * threading models, including a single-threaded system or a multi-threaded + * system with preemption. The current platform definition is agnostic to this + * underlying choice. However, the CHRE implementation must ensure that time + * spent executing within a nanoapp does not significantly degrade or otherwise + * interfere with other functions of the system in which CHRE is implemented, + * especially latency-sensitive tasks such as sensor event delivery to the AP. + * In other words, it must ensure that these functions can either occur in + * parallel or preempt a nanoapp's execution. The current version of the API + * does not specify whether the implementation allows for CPU sharing between + * nanoapps on a more granular level than the handling of individual events [1]. + * In any case, event ordering from the perspective of an individual nanoapp + * must be FIFO, but the CHRE implementation may choose to violate total + * ordering of events across all nanoapps to achieve more fair resource sharing, + * but this is not required. + * + * This version of the CHRE API does require that all nanoapps are treated as + * non-reentrant, meaning that only one instance of program flow can be inside + * an individual nanoapp at any given time. That is, any of the functions of + * the nanoapp, including the entry points and all other callbacks, cannot be + * invoked if a previous invocation to the same or any other function in the + * nanoapp has not completed yet. + * + * For example, if a nanoapp is currently in nanoappHandleEvent(), the CHRE is + * not allowed to call nanoappHandleEvent() again, or to call a memory freeing + * callback. Similarly, if a nanoapp is currently in a memory freeing + * callback, the CHRE is not allowed to call nanoappHandleEvent(), or invoke + * another memory freeing callback. + * + * There are two exceptions to this rule: If an invocation of chreSendEvent() + * fails (returns 'false'), it is allowed to immediately invoke the memory + * freeing callback passed into that function. This is a rare case, and one + * where otherwise a CHRE implementation is likely to leak memory. Similarly, + * chreSendMessageToHost() is allowed to invoke the memory freeing callback + * directly, whether it returns 'true' or 'false'. This is because the CHRE + * implementation may copy the message data to its own buffer, and therefore + * wouldn't need the nanoapp-supplied buffer after chreSendMessageToHost() + * returns. + * + * For a nanoapp author, this means no thought needs to be given to + * synchronization issues with global objects, as they will, by definition, + * only be accessed by a single thread at once. + * + * [1]: Note to CHRE implementers: A future version of the CHRE platform may + * require multi-threading with preemption. This is mentioned as a heads up, + * and to allow implementors deciding between implementation approaches to + * make the most informed choice. + * + * @section timing Timing + * + * Nanoapps should expect to be running on a highly constrained system, with + * little memory and little CPU. Any single nanoapp should expect to + * be one of several nanoapps on the system, which also share the CPU with the + * CHRE and possibly other services as well. + * + * Thus, a nanoapp needs to be efficient in its memory and CPU usage. + * Also, as noted in the Threading Model section, a CHRE implementation may + * be single threaded. As a result, all methods invoked in a nanoapp + * (like nanoappStart, nanoappHandleEvent, memory free callbacks, etc.) + * must run "quickly". "Quickly" is difficult to define, as there is a + * diversity of Context Hub hardware. Nanoapp authors are strongly recommended + * to limit their application to consuming no more than 1 second of CPU time + * prior to returning control to the CHRE implementation. A CHRE implementation + * may consider a nanoapp as unresponsive if it spends more time than this to + * process a single event, and take corrective action. + * + * A nanoapp may have the need to occasionally perform a large block of + * calculations that exceeds the 1 second guidance. The recommended approach in + * this case is to split up the large block of calculations into smaller + * batches. In one call into the nanoapp, the nanoapp can perform the first + * batch, and then set a timer or send an event (chreSendEvent()) to itself + * indicating which batch should be done next. This will allow the nanoapp to + * perform the entire calculation over time, without monopolizing system + * resources. + * + * @section floats Floating point support + * + * The C type 'float' is used in this API, and thus a CHRE implementation + * is required to support 'float's. + * + * Support of the C types 'double' and 'long double' is optional for a + * CHRE implementation. Note that if a CHRE decides to support them, unlike + * 'float' support, there is no requirement that this support is particularly + * efficient. So nanoapp authors should be aware this may be inefficient. + * + * If a CHRE implementation chooses not to support 'double' or + * 'long double', then the build toolchain setup provided needs to set + * the preprocessor define CHRE_NO_DOUBLE_SUPPORT. + * + * @section compat CHRE and Nanoapp compatibility + * + * CHRE implementations must make affordances to maintain binary compatibility + * across minor revisions of the API version (e.g. v1.1 to v1.2). This applies + * to both running a nanoapp compiled for a newer version of the API on a CHRE + * implementation built against an older version (backwards compatibility), and + * vice versa (forwards compatibility). API changes that are acceptable in + * minor version changes that may require special measures to ensure binary + * compatibility include: addition of new functions; addition of arguments to + * existing functions when the default value used for nanoapps compiled against + * the old version is well-defined and does not affect existing functionality; + * and addition of fields to existing structures, even when this induces a + * binary layout change (this should be made rare via judicious use of reserved + * fields). API changes that must only occur alongside a major version change + * and are therefore not compatible include: removal of any function, argument, + * field in a data structure, or mandatory functional behavior that a nanoapp + * may depend on; any change in the interpretation of an existing data structure + * field that alters the way it was defined previously (changing the units of a + * field would fall under this, but appropriating a previously reserved field + * for some new functionality would not); and any change in functionality or + * expected behavior that conflicts with the previous definition. + * + * Note that the CHRE API only specifies the software interface between a + * nanoapp and the CHRE system - the binary interface (ABI) between nanoapp and + * CHRE is necessarily implementation-dependent. Therefore, the recommended + * approach to accomplish binary compatibility is to build a Nanoapp Support + * Library (NSL) that is specific to the CHRE implementation into the nanoapp + * binary, and use it to handle ABI details in a way that ensures compatibility. + * In addition, to accomplish forwards compatibility, the CHRE implementation is + * expected to recognize the CHRE API version that a nanoapp is targeting and + * engage compatibility behaviors where necessary. + * + * By definition, major API version changes (e.g. v1.1 to v2.0) break + * compatibility. Therefore, a CHRE implementation must not attempt to load a + * nanoapp that is targeting a newer major API version. + */ + +#endif /* _CHRE_H_ */ +
diff --git a/chre_api/legacy/v1_10/chre/audio.h b/chre_api/legacy/v1_10/chre/audio.h new file mode 100644 index 0000000..085329e --- /dev/null +++ b/chre_api/legacy/v1_10/chre/audio.h
@@ -0,0 +1,432 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// IWYU pragma: private, include "chre_api/chre.h" +// IWYU pragma: friend chre/.*\.h + +#ifndef _CHRE_AUDIO_H_ +#define _CHRE_AUDIO_H_ + +/** + * @file + * The API for requesting audio in the Context Hub Runtime Environment. + * + * This includes the definition of audio data structures and the ability to + * request audio streams. + */ + +#include <chre/event.h> + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The current compatibility version of the chreAudioDataEvent structure. + */ +#define CHRE_AUDIO_DATA_EVENT_VERSION UINT8_C(1) + +/** + * Produce an event ID in the block of IDs reserved for audio + * @param offset Index into audio event ID block; valid range [0,15] + */ +#define CHRE_AUDIO_EVENT_ID(offset) (CHRE_EVENT_AUDIO_FIRST_EVENT + (offset)) + +/** + * nanoappHandleEvent argument: struct chreAudioSourceStatusEvent + * + * Indicates a change in the format and/or rate of audio data provided to a + * nanoapp. + */ +#define CHRE_EVENT_AUDIO_SAMPLING_CHANGE CHRE_AUDIO_EVENT_ID(0) + +/** + * nanoappHandleEvent argument: struct chreAudioDataEvent + * + * Provides a buffer of audio data to a nanoapp. + */ +#define CHRE_EVENT_AUDIO_DATA CHRE_AUDIO_EVENT_ID(1) + +/** + * The maximum size of the name of an audio source including the + * null-terminator. + */ +#define CHRE_AUDIO_SOURCE_NAME_MAX_SIZE (40) + +/** + * Helper values for sample rates. + * + * @defgroup CHRE_AUDIO_SAMPLE_RATES + * @{ + */ + +//! 16kHz Audio Sample Data +#define CHRE_AUDIO_SAMPLE_RATE_16KHZ (16000) + +/** @} */ + +/** + * Formats for audio that can be provided to a nanoapp. + */ +enum chreAudioDataFormat { + /** + * Unsigned, 8-bit u-Law encoded data as specified by ITU-T G.711. + */ + CHRE_AUDIO_DATA_FORMAT_8_BIT_U_LAW = 0, + + /** + * Signed, 16-bit linear PCM data. Endianness must be native to the local + * processor. + */ + CHRE_AUDIO_DATA_FORMAT_16_BIT_SIGNED_PCM = 1, +}; + +/** + * A description of an audio source available to a nanoapp. + * + * This provides a description of an audio source with a name and a + * description of the format of the provided audio data. + */ +struct chreAudioSource { + /** + * A human readable name for this audio source. This is a C-style, + * null-terminated string. The length must be less than or equal to + * CHRE_AUDIO_SOURCE_NAME_MAX_SIZE bytes (including the null-terminator) and + * is expected to describe the source of the audio in US English. All + * characters must be printable (i.e.: isprint would return true for all + * characters in the name for the EN-US locale). The typical use of this field + * is for a nanoapp to log the name of the audio source that it is using. + * + * Example: "Camcorder Microphone" + */ + const char *name; + + /** + * The sampling rate in hertz of this mode. This value is rounded to the + * nearest integer. Typical values might include 16000, 44100 and 44800. + * + * If the requested audio source is preempted by another feature of the system + * (e.g. hotword), a gap may occur in received audio data. This is indicated + * to the client by posting a CHRE_EVENT_AUDIO_SAMPLING_CHANGE event. The + * nanoapp will then receive another CHRE_EVENT_AUDIO_SAMPLING_CHANGE event + * once the audio source is available again. + */ + uint32_t sampleRate; + + /** + * The minimum amount of time that this audio source can be buffered, in + * nanoseconds. Audio data is delivered to nanoapps in buffers. This specifies + * the minimum amount of data that can be delivered to a nanoapp without + * losing data. A request for a buffer that is smaller than this will fail. + */ + uint64_t minBufferDuration; + + /** + * The maximum amount of time that this audio source can be buffered, in + * nanoseconds. Audio data is delivered to nanoapps in buffers. This specifies + * the maximum amount of data that can be stored by the system in one event + * without losing data. A request for a buffer that is larger than this will + * fail. + */ + uint64_t maxBufferDuration; + + /** + * The format for data provided to the nanoapp. This will be assigned to one + * of the enum chreAudioDataFormat values. + */ + uint8_t format; +}; + +/** + * The current status of an audio source. + */ +struct chreAudioSourceStatus { + /** + * Set to true if the audio source is currently enabled by this nanoapp. If + * this struct is provided by a CHRE_EVENT_AUDIO_SAMPLING_CHANGE event, it + * must necessarily be set to true because sampling change events are only + * sent for sources which this nanoapp has actively subscribed to. If this + * struct is obtained from the chreAudioGetStatus API, it may be set to true + * or false depending on if audio is currently enabled. + */ + bool enabled; + + /** + * Set to true if the audio source is currently suspended and no audio data + * will be received from this source. + */ + bool suspended; +}; + +/** + * The nanoappHandleEvent argument for CHRE_EVENT_AUDIO_SAMPLING_CHANGE. + */ +struct chreAudioSourceStatusEvent { + /** + * The audio source which has completed a status change. + */ + uint32_t handle; + + /** + * The status of this audio source. + */ + struct chreAudioSourceStatus status; +}; + +/** + * The nanoappHandleEvent argument for CHRE_EVENT_AUDIO_DATA. + * + * One example of the sequence of events for a nanoapp to receive audio data is: + * + * 1. CHRE_EVENT_AUDIO_SAMPLING_CHANGE - Indicates that audio data is not + * suspended. + * 2. CHRE_EVENT_AUDIO_DATA - One buffer of audio samples. Potentially repeated. + * 3. CHRE_EVENT_AUDIO_SAMPLING_CHANGE - Indicates that audio data has suspended + * which indicates a gap in the audio. + * 4. CHRE_EVENT_AUDIO_SAMPLING_CHANGE - Indicates that audio data has resumed + * and that audio data may be delivered + * again if enough samples are buffered. + * 5. CHRE_EVENT_AUDIO_DATA - One buffer of audio samples. Potentially repeated. + * The nanoapp must tolerate a gap in the timestamps. + * + * This process repeats for as long as an active request is made for an audio + * source. A CHRE_EVENT_AUDIO_SAMPLING_CHANGE does not guarantee that the next + * event will be a CHRE_EVENT_AUDIO_DATA event when suspended is set to false. + * It may happen that the audio source is suspended before a complete buffer can + * be captured. This will cause another CHRE_EVENT_AUDIO_SAMPLING_CHANGE event + * to be dispatched with suspended set to true before a buffer is delivered. + * + * Audio events must be delivered to a nanoapp in order. + */ +struct chreAudioDataEvent { + /** + * Indicates the version of the structure, for compatibility purposes. Clients + * do not normally need to worry about this field; the CHRE implementation + * guarantees that the client only receives the structure version it expects. + */ + uint8_t version; + + /** + * Additional bytes reserved for future use; must be set to 0. + */ + uint8_t reserved[3]; + + /** + * The handle for which this audio data originated from. + */ + uint32_t handle; + + /** + * The base timestamp for this buffer of audio data, from the same time base + * as chreGetTime() (in nanoseconds). The audio API does not provide + * timestamps for each audio sample. This timestamp corresponds to the first + * sample of the buffer. Even though the value is expressed in nanoseconds, + * there is an expectation that the sample clock may drift and nanosecond + * level accuracy may not be possible. The goal is to be as accurate as + * possible within reasonable limitations of a given system. + */ + uint64_t timestamp; + + /** + * The sample rate for this buffer of data in hertz, rounded to the nearest + * integer. Fractional sampling rates are not supported. Typical values might + * include 16000, 44100 and 48000. + */ + uint32_t sampleRate; + + /** + * The number of samples provided with this buffer. + */ + uint32_t sampleCount; + + /** + * The format of this audio data. This enumeration and union of pointers below + * form a tagged struct. The consumer of this API must use this enum to + * determine which samples pointer below to dereference. This will be assigned + * to one of the enum chreAudioDataFormat values. + */ + uint8_t format; + + /** + * A union of pointers to various formats of sample data. These correspond to + * the valid chreAudioDataFormat values. + */ + union { + const uint8_t *samplesULaw8; + const int16_t *samplesS16; + }; +}; + +/** + * Retrieves information about an audio source supported by the current CHRE + * implementation. The source returned by the runtime must not change for the + * entire lifecycle of the Nanoapp and hot-pluggable audio sources are not + * supported. + * + * A simple example of iterating all available audio sources is provided here: + * + * struct chreAudioSource audioSource; + * for (uint32_t i = 0; chreAudioGetSource(i, &audioSource); i++) { + * chreLog(CHRE_LOG_INFO, "Found audio source: %s", audioSource.name); + * } + * + * Handles provided to this API must be a stable value for the entire duration + * of a nanoapp. Handles for all audio sources must be zero-indexed and + * contiguous. The following are examples of handles that could be provided to + * this API: + * + * Valid: 0 + * Valid: 0, 1, 2, 3 + * Invalid: 1, 2, 3 + * Invalid: 0, 2 + * + * @param handle The handle for an audio source to obtain details for. The + * range of acceptable handles must be zero-indexed and contiguous. + * @param audioSource A struct to populate with details of the audio source. + * @return true if the query was successful, false if the provided handle is + * invalid or the supplied audioSource is NULL. + * + * @since v1.2 + */ +bool chreAudioGetSource(uint32_t handle, struct chreAudioSource *audioSource); + +/** + * Nanoapps must define CHRE_NANOAPP_USES_AUDIO somewhere in their build + * system (e.g. Makefile) if the nanoapp needs to use the following audio APIs. + * In addition to allowing access to these APIs, defining this macro will also + * ensure CHRE enforces that all host clients this nanoapp talks to have the + * required Android permissions needed to listen to audio data by adding + * metadata to the nanoapp. + */ +#if defined(CHRE_NANOAPP_USES_AUDIO) || !defined(CHRE_IS_NANOAPP_BUILD) + +/** + * Configures delivery of audio data to the current nanoapp. Note that this may + * not fully disable the audio source if it is used by other clients in the + * system but it will halt data delivery to the nanoapp. + * + * The bufferDuration and deliveryInterval parameters as described below are + * used together to determine both how much and how often to deliver data to a + * nanoapp, respectively. A nanoapp will always be provided the requested + * amount of data at the requested interval, even if another nanoapp in CHRE + * requests larger/more frequent buffers or smaller/less frequent buffers. + * These two buffering parameters allow describing the duty cycle of captured + * audio data. If a nanoapp wishes to receive all available audio data, it will + * specify a bufferDuration and deliveryInterval that are equal. A 50% duty + * cycle would be achieved by specifying a deliveryInterval that is double the + * value of the bufferDuration provided. These parameters allow the audio + * subsystem to operate at less than 100% duty cycle and permits use of + * incomplete audio data without periodic reconfiguration of the source. + * + * Two examples are illustrated below: + * + * Target duty cycle: 50% + * bufferDuration: 2 + * deliveryInterval: 4 + * + * Time 0 1 2 3 4 5 6 7 + * Batch A B + * Sample -- -- a1 a2 -- -- b1 b2 + * Duration [ ] [ ] + * Interval [ ] [ ] + * + * + * Target duty cycle: 100% + * bufferDuration: 4 + * deliveryInterval: 4 + * + * Time 0 1 2 3 4 5 6 7 + * Batch A B + * Sample a1 a2 a3 a4 b1 b2 b3 b4 + * Duration [ ] [ ] + * Interval [ ] [ ] + * + * + * This is expected to reduce power overall. + * + * The first audio buffer supplied to the nanoapp may contain data captured + * prior to the request. This could happen if the microphone was already enabled + * and reading into a buffer prior to the nanoapp requesting audio data for + * itself. The nanoapp must tolerate this. + * + * It is important to note that multiple logical audio sources (e.g. different + * sample rate, format, etc.) may map to one physical audio source. It is + * possible for a nanoapp to request audio data from more than one logical + * source at a time. Audio data may be suspended for either the current or other + * requests. The CHRE_EVENT_AUDIO_SAMPLING_CHANGE will be posted to all clients + * if such a change occurs. It is also possible for the request to succeed and + * all audio sources are serviced simultaneously. This is implementation defined + * but at least one audio source must function correctly if it is advertised, + * under normal conditions (e.g. not required for some other system function, + * such as hotword). + * + * @param handle The handle for this audio source. The handle for the desired + * audio source can be determined using chreAudioGetSource(). + * @param enable true if enabling the source, false otherwise. When passed as + * false, the bufferDuration and deliveryInterval parameters are ignored. + * @param bufferDuration The amount of time to capture audio samples from this + * audio source, in nanoseconds per delivery interval. This value must be + * in the range of minBufferDuration/maxBufferDuration for this source or + * the request will fail. The number of samples captured per buffer will be + * derived from the sample rate of the source and the requested duration and + * rounded down to the nearest sample boundary. + * @param deliveryInterval Desired time between each CHRE_EVENT_AUDIO_DATA + * event. This allows specifying the complete duty cycle of a request + * for audio data, in nanoseconds. This value must be greater than or equal + * to bufferDuration or the request will fail due to an invalid + * configuration. + * @return true if the configuration was successful, false if invalid parameters + * were provided (non-existent handle, invalid buffering configuration). + * + * @since v1.2 + * @note Requires audio permission + */ +bool chreAudioConfigureSource(uint32_t handle, bool enable, + uint64_t bufferDuration, + uint64_t deliveryInterval); + +/** + * Gets the current chreAudioSourceStatus struct for a given audio handle. + * + * @param handle The handle for the audio source to query. The provided handle + * is obtained from a chreAudioSource which is requested from the + * chreAudioGetSource API. + * @param status The current status of the supplied audio source. + * @return true if the provided handle is valid and the status was obtained + * successfully, false if the handle was invalid or status is NULL. + * + * @since v1.2 + * @note Requires audio permission + */ +bool chreAudioGetStatus(uint32_t handle, struct chreAudioSourceStatus *status); + +#else /* defined(CHRE_NANOAPP_USES_AUDIO) || !defined(CHRE_IS_NANOAPP_BUILD) */ +#define CHRE_AUDIO_PERM_ERROR_STRING \ + "CHRE_NANOAPP_USES_AUDIO must be defined when building this nanoapp in " \ + "order to refer to " +#define chreAudioConfigureSource(...) \ + CHRE_BUILD_ERROR(CHRE_AUDIO_PERM_ERROR_STRING "chreAudioConfigureSource") +#define chreAudioGetStatus(...) \ + CHRE_BUILD_ERROR(CHRE_AUDIO_PERM_ERROR_STRING "chreAudioGetStatus") +#endif /* defined(CHRE_NANOAPP_USES_AUDIO) || !defined(CHRE_IS_NANOAPP_BUILD) */ + +#ifdef __cplusplus +} +#endif + +#endif /* _CHRE_AUDIO_H_ */
diff --git a/chre_api/legacy/v1_10/chre/ble.h b/chre_api/legacy/v1_10/chre/ble.h new file mode 100644 index 0000000..dc8e900 --- /dev/null +++ b/chre_api/legacy/v1_10/chre/ble.h
@@ -0,0 +1,967 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// IWYU pragma: private, include "chre_api/chre.h" +// IWYU pragma: friend chre/.*\.h + +#ifndef CHRE_BLE_H_ +#define CHRE_BLE_H_ + +/** + * @file + * CHRE BLE (Bluetooth Low Energy, Bluetooth LE) API. + * The CHRE BLE API currently supports BLE scanning features. + * + * The features in the CHRE BLE API are a subset and adaptation of Android + * capabilities as described in the Android BLE API and HCI requirements. + * ref: + * https://developer.android.com/guide/topics/connectivity/bluetooth/ble-overview + * ref: https://source.android.com/devices/bluetooth/hci_requirements + * + * All byte arrays in the CHRE BLE API follow the byte order used OTA unless + * specified otherwise, and multi-byte types, for example uint16_t, follow the + * processor's native byte order. One notable exception is addresses. Address + * fields in both scan filters and advertising reports must be in big endian + * byte order to match the Android Bluetooth API (ref: + * https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#getRemoteDevice(byte[])). + */ + +#include <chre/common.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The set of flags returned by chreBleGetCapabilities(). + * + * @defgroup CHRE_BLE_CAPABILITIES + * @{ + */ +//! No BLE APIs are supported +#define CHRE_BLE_CAPABILITIES_NONE UINT32_C(0) + +//! CHRE supports BLE scanning +#define CHRE_BLE_CAPABILITIES_SCAN UINT32_C(1 << 0) + +//! CHRE BLE supports batching of scan results, either through Android-specific +//! HCI (OCF: 0x156), or by the CHRE framework, internally. +//! @since v1.7 Platforms with this capability must also support flushing scan +//! results during a batched scan. +#define CHRE_BLE_CAPABILITIES_SCAN_RESULT_BATCHING UINT32_C(1 << 1) + +//! CHRE BLE scan supports best-effort hardware filtering. If filtering is +//! available, chreBleGetFilterCapabilities() returns a bitmap indicating the +//! specific filtering capabilities that are supported. +//! To differentiate best-effort vs. no filtering, the following requirement +//! must be met for this flag: +//! If only one nanoapp is requesting BLE scans and there are no BLE scans from +//! the AP, only filtered results will be provided to the nanoapp. +#define CHRE_BLE_CAPABILITIES_SCAN_FILTER_BEST_EFFORT UINT32_C(1 << 2) + +//! CHRE BLE supports reading the RSSI of a specified LE-ACL connection handle. +#define CHRE_BLE_CAPABILITIES_READ_RSSI UINT32_C(1 << 3) +/** @} */ + +/** + * The set of flags returned by chreBleGetFilterCapabilities(). + * + * The representative bit for each filtering capability is based on the sub-OCF + * of the Android filtering HCI vendor-specific command (LE_APCF_Command, OCF: + * 0x0157) for that particular filtering capability, as found in + * https://source.android.com/devices/bluetooth/hci_requirements + * + * For example, the Service Data filter has a sub-command of 0x7; hence + * the filtering capability is indicated by (1 << 0x7). + * + * @defgroup CHRE_BLE_FILTER_CAPABILITIES + * @{ + */ +//! No CHRE BLE filters are supported +#define CHRE_BLE_FILTER_CAPABILITIES_NONE UINT32_C(0) + +//! CHRE BLE supports RSSI filters +#define CHRE_BLE_FILTER_CAPABILITIES_RSSI UINT32_C(1 << 1) + +//! CHRE BLE supports Broadcaster Address filters (Corresponding HCI OCF: +//! 0x0157, Sub-command: 0x02) +//! @since v1.9 +#define CHRE_BLE_FILTER_CAPABILITIES_BROADCASTER_ADDRESS UINT32_C(1 << 2) + +//! CHRE BLE supports Manufacturer Data filters (Corresponding HCI OCF: 0x0157, +//! Sub-command: 0x06) +//! @since v1.8 +#define CHRE_BLE_FILTER_CAPABILITIES_MANUFACTURER_DATA UINT32_C(1 << 6) + +//! CHRE BLE supports Service Data filters (Corresponding HCI OCF: 0x0157, +//! Sub-command: 0x07) +#define CHRE_BLE_FILTER_CAPABILITIES_SERVICE_DATA UINT32_C(1 << 7) +/** @} */ + +/** + * Produce an event ID in the block of IDs reserved for BLE. + * + * Valid input range is [0, 15]. Do not add new events with ID > 15 + * (see chre/event.h) + * + * @param offset Index into BLE event ID block; valid range is [0, 15]. + * + * @defgroup CHRE_BLE_EVENT_ID + * @{ + */ +#define CHRE_BLE_EVENT_ID(offset) (CHRE_EVENT_BLE_FIRST_EVENT + (offset)) + +/** + * nanoappHandleEvent argument: struct chreAsyncResult + * + * Communicates the asynchronous result of a request to the BLE API. The + * requestType field in {@link #chreAsyncResult} is set to a value from enum + * chreBleRequestType. + * + * This is used for results of async config operations which need to + * interop with lower level code (potentially in a different thread) or send an + * HCI command to the FW and wait on the response. + */ +#define CHRE_EVENT_BLE_ASYNC_RESULT CHRE_BLE_EVENT_ID(0) + +/** + * nanoappHandleEvent argument: struct chreBleAdvertisementEvent + * + * Provides results of a BLE scan. + */ +#define CHRE_EVENT_BLE_ADVERTISEMENT CHRE_BLE_EVENT_ID(1) + +/** + * nanoappHandleEvent argument: struct chreAsyncResult + * + * Indicates that a flush request made via chreBleFlushAsync() is complete, and + * all batched advertisements resulting from the flush have been delivered via + * preceding CHRE_EVENT_BLE_ADVERTISEMENT events. + * + * @since v1.7 + */ +#define CHRE_EVENT_BLE_FLUSH_COMPLETE CHRE_BLE_EVENT_ID(2) + +/** + * nanoappHandleEvent argument: struct chreBleReadRssiEvent + * + * Provides the RSSI of an LE ACL connection following a call to + * chreBleReadRssiAsync(). + * + * @since v1.8 + */ +#define CHRE_EVENT_BLE_RSSI_READ CHRE_BLE_EVENT_ID(3) + +/** + * nanoappHandleEvent argument: struct chreBatchCompleteEvent + * + * This event is generated if the platform enabled batching, and when all + * events in a single batch has been delivered (for example, batching + * CHRE_EVENT_BLE_ADVERTISEMENT events if the platform has + * CHRE_BLE_CAPABILITIES_SCAN_RESULT_BATCHING enabled, and a non-zero + * reportDelayMs in chreBleStartScanAsync() was accepted). + * + * If the nanoapp receives a CHRE_EVENT_BLE_SCAN_STATUS_CHANGE with a non-zero + * reportDelayMs and enabled set to true, then this event must be generated. + * + * @since v1.8 + */ +#define CHRE_EVENT_BLE_BATCH_COMPLETE CHRE_BLE_EVENT_ID(4) + +/** + * nanoappHandleEvent argument: struct chreBleScanStatus + * + * This event is generated when the values in chreBleScanStatus changes. + * + * @since v1.8 + */ +#define CHRE_EVENT_BLE_SCAN_STATUS_CHANGE CHRE_BLE_EVENT_ID(5) + +// NOTE: Do not add new events with ID > 15 +/** @} */ + +/** + * Maximum BLE (legacy) advertisement payload data length, in bytes + * This is calculated by subtracting 2 (type + len) from 31 (max payload). + */ +#define CHRE_BLE_DATA_LEN_MAX (29) + +/** + * BLE device address length, in bytes. + */ +#define CHRE_BLE_ADDRESS_LEN (6) + +/** + * RSSI value (int8_t) indicating no RSSI threshold. + */ +#define CHRE_BLE_RSSI_THRESHOLD_NONE (-128) + +/** + * RSSI value (int8_t) indicating no RSSI value available. + */ +#define CHRE_BLE_RSSI_NONE (127) + +/** + * Tx power value (int8_t) indicating no Tx power value available. + */ +#define CHRE_BLE_TX_POWER_NONE (127) + +/** + * Indicates ADI field was not provided in advertisement. + */ +#define CHRE_BLE_ADI_NONE (0xFF) + +/** + * The CHRE BLE advertising event type is based on the BT Core Spec v5.2, + * Vol 4, Part E, Section 7.7.65.13, LE Extended Advertising Report event, + * Event_Type. + * + * Note: helper functions are provided to avoid bugs, e.g. a nanoapp doing + * (eventTypeAndDataStatus == ADV_IND) instead of properly masking off reserved + * and irrelevant bits. + * + * @defgroup CHRE_BLE_EVENT + * @{ + */ +// Extended event types +#define CHRE_BLE_EVENT_MASK_TYPE (0x1f) +#define CHRE_BLE_EVENT_TYPE_FLAG_CONNECTABLE (1 << 0) +#define CHRE_BLE_EVENT_TYPE_FLAG_SCANNABLE (1 << 1) +#define CHRE_BLE_EVENT_TYPE_FLAG_DIRECTED (1 << 2) +#define CHRE_BLE_EVENT_TYPE_FLAG_SCAN_RSP (1 << 3) +#define CHRE_BLE_EVENT_TYPE_FLAG_LEGACY (1 << 4) + +// Data status +#define CHRE_BLE_EVENT_MASK_DATA_STATUS (0x3 << 5) +#define CHRE_BLE_EVENT_DATA_STATUS_COMPLETE (0x0 << 5) +#define CHRE_BLE_EVENT_DATA_STATUS_MORE_DATA_PENDING (0x1 << 5) +#define CHRE_BLE_EVENT_DATA_STATUS_DATA_TRUNCATED (0x2 << 5) + +// Legacy event types +#define CHRE_BLE_EVENT_TYPE_LEGACY_ADV_IND \ + (CHRE_BLE_EVENT_TYPE_FLAG_LEGACY | CHRE_BLE_EVENT_TYPE_FLAG_CONNECTABLE | \ + CHRE_BLE_EVENT_TYPE_FLAG_SCANNABLE) +#define CHRE_BLE_EVENT_TYPE_LEGACY_DIRECT_IND \ + (CHRE_BLE_EVENT_TYPE_FLAG_LEGACY | CHRE_BLE_EVENT_TYPE_FLAG_CONNECTABLE) +#define CHRE_BLE_EVENT_TYPE_LEGACY_ADV_SCAN_IND \ + (CHRE_BLE_EVENT_TYPE_FLAG_LEGACY | CHRE_BLE_EVENT_TYPE_FLAG_SCANNABLE) +#define CHRE_BLE_EVENT_TYPE_LEGACY_ADV_NONCONN_IND \ + (CHRE_BLE_EVENT_TYPE_FLAG_LEGACY) +#define CHRE_BLE_EVENT_TYPE_LEGACY_SCAN_RESP_ADV_IND \ + (CHRE_BLE_EVENT_TYPE_FLAG_SCAN_RSP | CHRE_BLE_EVENT_TYPE_LEGACY_ADV_IND) +#define CHRE_BLE_EVENT_TYPE_LEGACY_SCAN_RESP_ADV_SCAN_IND \ + (CHRE_BLE_EVENT_TYPE_FLAG_SCAN_RSP | CHRE_BLE_EVENT_TYPE_LEGACY_ADV_SCAN_IND) +/** @} */ + +/** + * The maximum amount of time allowed to elapse between the call to + * chreBleFlushAsync() and when CHRE_EVENT_BLE_FLUSH_COMPLETE is delivered to + * the nanoapp on a successful flush. + */ +#define CHRE_BLE_FLUSH_COMPLETE_TIMEOUT_NS (5 * CHRE_NSEC_PER_SEC) + +/** + * Indicates a type of request made in this API. Used to populate the resultType + * field of struct chreAsyncResult sent with CHRE_EVENT_BLE_ASYNC_RESULT. + */ +enum chreBleRequestType { + CHRE_BLE_REQUEST_TYPE_START_SCAN = 1, + CHRE_BLE_REQUEST_TYPE_STOP_SCAN = 2, + CHRE_BLE_REQUEST_TYPE_FLUSH = 3, //!< @since v1.7 + CHRE_BLE_REQUEST_TYPE_READ_RSSI = 4, //!< @since v1.8 +}; + +/** + * CHRE BLE scan modes identify functional scan levels without specifying or + * guaranteeing particular scan parameters (e.g. duty cycle, interval, radio + * chain). + * + * The actual scan parameters may be platform dependent and may change without + * notice in real time based on contextual cues, etc. + * + * Scan modes should be selected based on use cases as described. + */ +enum chreBleScanMode { + //! A background scan level for always-running ambient applications. + //! A representative duty cycle may be between 3 - 10 % (tentative, and + //! with no guarantees). + CHRE_BLE_SCAN_MODE_BACKGROUND = 1, + + //! A foreground scan level to be used for short periods. + //! A representative duty cycle may be between 10 - 20 % (tentative, and + //! with no guarantees). + CHRE_BLE_SCAN_MODE_FOREGROUND = 2, + + //! A very high duty cycle scan level to be used for very short durations. + //! A representative duty cycle may be between 50 - 100 % (tentative, and + //! with no guarantees). + CHRE_BLE_SCAN_MODE_AGGRESSIVE = 3, +}; + +/** + * Selected AD Types are available among those defined in the Bluetooth spec. + * Assigned Numbers, Generic Access Profile. + * ref: https://www.bluetooth.com/specifications/assigned-numbers/ + */ +enum chreBleAdType { + //! Service Data with 16-bit UUID + //! @since v1.8 CHRE_BLE_AD_TYPE_SERVICE_DATA_WITH_UUID_16 was renamed + //! CHRE_BLE_AD_TYPE_SERVICE_DATA_WITH_UUID_16_LE to reflect that nanoapps + //! compiled against v1.8+ should use OTA format for service data filters. + CHRE_BLE_AD_TYPE_SERVICE_DATA_WITH_UUID_16_LE = 0x16, + + //! Manufacturer Specific Data + //! @since v1.8 + CHRE_BLE_AD_TYPE_MANUFACTURER_DATA = 0xff, +}; + +/** + * Generic filters are used to filter for the presence of AD structures in the + * data field of LE Extended Advertising Report events (ref: BT Core Spec v5.3, + * Vol 3, Part E, Section 11). + * + * The CHRE generic filter structure represents a generic filter on an AD Type + * as defined in the Bluetooth spec Assigned Numbers, Generic Access Profile + * (ref: https://www.bluetooth.com/specifications/assigned-numbers/). This + * generic structure is used by the Android HCI Advertising Packet Content + * Filter (APCF) AD Type sub-command 0x09 (ref: + * https://source.android.com/docs/core/connect/bluetooth/hci_requirements#le_apcf_command-ad_type_sub_cmd). + * + * The filter is matched when an advertisement event contains an AD structure in + * its data field that matches the following criteria: + * AdStructure.type == type + * AdStructure.data & dataMask == data & dataMask + * + * The maximum data length is limited to the maximum possible legacy + * advertisement payload data length (29 bytes). The data and dataMask must be + * in OTA format. For each zero bit of the dataMask, the corresponding + * data bit must also be zero. + * + * Note that the CHRE implementation may not support every kind of filter that + * can be represented by this structure. Use chreBleGetFilterCapabilities() to + * discover supported filtering capabilities at runtime. + * + * Example 1: To filter on a 16 bit service data UUID of 0xFE2C, the following + * settings would be used: + * type = CHRE_BLE_AD_TYPE_SERVICE_DATA_WITH_UUID_16_LE + * len = 2 + * data = {0x2C, 0xFE} + * dataMask = {0xFF, 0xFF} + * + * Example 2: To filter for manufacturer data of 0x12, 0x34 from Google (0x00E0), + * the following settings would be used: + * type = CHRE_BLE_AD_TYPE_MANUFACTURER_DATA + * len = 4 + * data = {0xE0, 0x00, 0x12, 0x34} + * dataMask = {0xFF, 0xFF, 0xFF, 0xFF} + * + * Refer to "Supplement to the Bluetooth Core Specification for details (v9, + * Part A, Section 1.4)" for details regarding the manufacturer data format. + */ +struct chreBleGenericFilter { + //! Acceptable values among enum chreBleAdType + uint8_t type; + + /** + * Length of data and dataMask. AD payloads shorter than this length will not + * be matched by the filter. Length must be greater than 0. + */ + uint8_t len; + + //! Used in combination with dataMask to filter an advertisement + uint8_t data[CHRE_BLE_DATA_LEN_MAX]; + + //! Used in combination with data to filter an advertisement + uint8_t dataMask[CHRE_BLE_DATA_LEN_MAX]; +}; + +/** + * Broadcaster address filters are used to filter by the address field of the LE + * Extended Advertising Report event which is defined in the BT Core Spec v5.3, + * Vol 4, Part E, Section 7.7.65.13. + * + * The CHRE broadcaster address filter structure is modeled after the + * Advertising Packet Content Filter (APCF) HCI broadcaster address sub-command + * 0x02 (ref: + * https://source.android.com/docs/core/connect/bluetooth/hci_requirements#le_apcf_command-broadcast_address_sub_cmd). + * However, it differs from this HCI command in two major ways: + * + * 1) The CHRE broadcaster address filter does not filter by address type at + * this time. If a nanoapp wants to filter for a particular address type, it + * must check the addressType field of the chreBleAdvertisingReport. + * + * 2) The broadcasterAddress must be in big endian byte order to match the + * format of the Android Bluetooth API (ref: + * https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#getRemoteDevice(byte[])). + * This is intended to allow easier integration between nanoapp and Host + * code. + * + * The filter is matched when an advertisement even meets the following + * criteria: + * broadcasterAddress == chreBleAdvertisingReport.address. + * + * Example: To filter on the address (01:02:03:AB:CD:EF), the following + * settings would be used: + * broadcasterAddress = {0x01, 0x02, 0x03, 0xAB, 0xCD, 0xEF} + * + * @since v1.9 + */ +struct chreBleBroadcasterAddressFilter { + //! 6-byte Broadcaster address + uint8_t broadcasterAddress[CHRE_BLE_ADDRESS_LEN]; +}; + +/** + * CHRE Bluetooth LE scan filters. + * + * @see chreBleScanFilterV1_9 for further details. + * + * @deprecated as of v1.9 due to the addition of the + * chreBleBroadcasterAddressFilter. New code should use chreBleScanFilterV1_9 + * instead of this struct. This struct will be removed in a future version. + */ +struct chreBleScanFilter { + //! RSSI threshold filter (Corresponding HCI OCF: 0x0157, Sub: 0x01), where + //! advertisements with RSSI values below this threshold may be disregarded. + //! An rssiThreshold value of CHRE_BLE_RSSI_THRESHOLD_NONE indicates no RSSI + //! filtering. + int8_t rssiThreshold; + + //! Number of generic scan filters provided in the scanFilters array. + //! A scanFilterCount value of 0 indicates no generic scan filters. + uint8_t scanFilterCount; + + //! Pointer to an array of scan filters. If the array contains more than one + //! entry, advertisements matching any of the entries will be returned + //! (functional OR). + const struct chreBleGenericFilter *scanFilters; +}; + +/** + * CHRE Bluetooth LE scan filters are based on a combination of an RSSI + * threshold, generic filters, and broadcaster address filters. + * + * When multiple filters are specified, rssiThreshold is combined with the other + * filters via functional AND, and the other filters are all combined as + * functional OR. In other words, an advertisement matches the filter if: + * rssi >= rssiThreshold + * AND (matchAny(genericFilters) OR matchAny(broadcasterAddressFilters)) + * + * CHRE-provided filters are implemented in a best-effort manner, depending on + * HW capabilities of the system and available resources. Therefore, provided + * scan results may be a superset of the specified filters. Nanoapps should try + * to take advantage of CHRE scan filters as much as possible, but must design + * their logic as to not depend on CHRE filtering. + * + * The syntax of CHRE scan filter definition is modeled after a combination of + * multiple Android HCI Advertising Packet Content Filter (APCF) sub commands + * including the RSSI threshold from the set filtering parameters sub command + * (ref: + * https://source.android.com/docs/core/connect/bluetooth/hci_requirements#le_apcf_command-set_filtering_parameters_sub_cmd). + * @see chreBleGenericFilter and chreBleBroadcasterAddressFilter for details + * about other APCF sub commands referenced. + * + * @since v1.9 + */ +struct chreBleScanFilterV1_9 { + //! RSSI threshold filter (Corresponding HCI OCF: 0x0157, Sub: 0x01), where + //! advertisements with RSSI values below this threshold may be disregarded. + //! An rssiThreshold value of CHRE_BLE_RSSI_THRESHOLD_NONE indicates no RSSI + //! filtering. + int8_t rssiThreshold; + + //! Number of generic filters provided in the scanFilters array. A + //! genericFilterCount value of 0 indicates no generic filters. + uint8_t genericFilterCount; + + //! Pointer to an array of generic filters. If the array contains more than + //! one entry, advertisements matching any of the entries will be returned + //! (functional OR). This is expected to be null if genericFilterCount is 0. + const struct chreBleGenericFilter *genericFilters; + + //! Number of broadcaster address filters provided in the + //! broadcasterAddressFilters array. A broadcasterAddressFilterCount value + //! of 0 indicates no broadcaster address filters. + uint8_t broadcasterAddressFilterCount; + + //! Pointer to an array of broadcaster address filters. If the array contains + //! more than one entry, advertisements matching any of the entries will be + //! returned (functional OR). This is expected to be null if + //! broadcasterAddressFilterCount is 0. + const struct chreBleBroadcasterAddressFilter *broadcasterAddressFilters; +}; + +/** + * CHRE BLE advertising address type is based on the BT Core Spec v5.2, Vol 4, + * Part E, Section 7.7.65.13, LE Extended Advertising Report event, + * Address_Type. + */ +enum chreBleAddressType { + //! Public device address. + CHRE_BLE_ADDRESS_TYPE_PUBLIC = 0x00, + + //! Random device address. + CHRE_BLE_ADDRESS_TYPE_RANDOM = 0x01, + + //! Public identity address (corresponds to resolved private address). + CHRE_BLE_ADDRESS_TYPE_PUBLIC_IDENTITY = 0x02, + + //! Random (static) Identity Address (corresponds to resolved private + //! address) + CHRE_BLE_ADDRESS_TYPE_RANDOM_IDENTITY = 0x03, + + //! No address provided (anonymous advertisement). + CHRE_BLE_ADDRESS_TYPE_NONE = 0xff, +}; + +/** + * CHRE BLE physical (PHY) channel encoding type, if supported, is based on the + * BT Core Spec v5.2, Vol 4, Part E, Section 7.7.65.13, LE Extended Advertising + * Report event, entries Primary_PHY and Secondary_PHY. + */ +enum chreBlePhyType { + //! No packets on this PHY (only on the secondary channel), or feature not + //! supported. + CHRE_BLE_PHY_NONE = 0x00, + + //! LE 1 MBPS PHY encoding. + CHRE_BLE_PHY_1M = 0x01, + + //! LE 2 MBPS PHY encoding (only on the secondary channel). + CHRE_BLE_PHY_2M = 0x02, + + //! LE long-range coded PHY encoding. + CHRE_BLE_PHY_CODED = 0x03, +}; + +/** + * The CHRE BLE Advertising Report event is based on the BT Core Spec v5.2, + * Vol 4, Part E, Section 7.7.65.13, LE Extended Advertising Report event, with + * the following differences: + * + * 1) A CHRE timestamp field, which can be useful if CHRE is batching results. + * 2) Reordering of the rssi and periodicAdvertisingInterval fields for memory + * alignment (prevent padding). + * 3) Addition of four reserved bytes to reclaim padding. + * 4) The address fields are formatted in big endian byte order to match the + * order specified for BluetoothDevices in the Android Bluetooth API (ref: + * https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#getRemoteDevice(byte[])). + */ +struct chreBleAdvertisingReport { + //! The base timestamp, in nanoseconds, in the same time base as chreGetTime() + uint64_t timestamp; + + //! @see CHRE_BLE_EVENT + uint8_t eventTypeAndDataStatus; + + //! Advertising address type as defined in enum chreBleAddressType + uint8_t addressType; + + //! Advertising device address. Formatted in big endian byte order. + uint8_t address[CHRE_BLE_ADDRESS_LEN]; + + //! Advertiser PHY on primary advertising physical channel, if supported, as + //! defined in enum chreBlePhyType. + uint8_t primaryPhy; + + //! Advertiser PHY on secondary advertising physical channel, if supported, as + //! defined in enum chreBlePhyType. + uint8_t secondaryPhy; + + //! Value of the Advertising SID subfield in the ADI field of the PDU among + //! the range of [0, 0x0f]. + //! CHRE_BLE_ADI_NONE indicates no ADI field was provided. + //! Other values are reserved. + uint8_t advertisingSid; + + //! Transmit (Tx) power in dBm. Typical values are [-127, 20]. + //! CHRE_BLE_TX_POWER_NONE indicates Tx power not available. + int8_t txPower; + + //! Interval of the periodic advertising in 1.25 ms intervals, i.e. + //! time = periodicAdvertisingInterval * 1.25 ms + //! 0 means no periodic advertising. Minimum value is otherwise 6 (7.5 ms). + uint16_t periodicAdvertisingInterval; + + //! RSSI in dBm. Typical values are [-127, 20]. + //! CHRE_BLE_RSSI_NONE indicates RSSI is not available. + int8_t rssi; + + //! Direct address type (i.e. only accept connection requests from a known + //! peer device) as defined in enum chreBleAddressType. + uint8_t directAddressType; + + //! Direct address (i.e. only accept connection requests from a known peer + //! device). Formatted in big endian byte order. + uint8_t directAddress[CHRE_BLE_ADDRESS_LEN]; + + //! Length of data field. Acceptable range is [0, 62] for legacy and + //! [0, 255] for extended advertisements. + uint16_t dataLength; + + //! dataLength bytes of data, or null if dataLength is 0. This represents + //! the ADV_IND payload, optionally concatenated with SCAN_RSP, as indicated + //! by eventTypeAndDataStatus. + const uint8_t *data; + + //! Reserved for future use; set to 0 + uint32_t reserved; +}; + +/** + * A CHRE BLE Advertising Event can contain any number of CHRE BLE Advertising + * Reports (i.e. advertisements). + */ +struct chreBleAdvertisementEvent { + //! Reserved for future use; set to 0 + uint16_t reserved; + + //! Number of advertising reports in this event + uint16_t numReports; + + //! Array of length numReports + const struct chreBleAdvertisingReport *reports; +}; + +/** + * The RSSI read on a particular LE connection handle, based on the parameters + * in BT Core Spec v5.3, Vol 4, Part E, Section 7.5.4, Read RSSI command + */ +struct chreBleReadRssiEvent { + //! Structure which contains the cookie associated with the original request, + //! along with an error code that indicates request success or failure. + struct chreAsyncResult result; + + //! The handle upon which CHRE attempted to read RSSI. + uint16_t connectionHandle; + + //! The RSSI of the last packet received on this connection, if valid + //! (-127 to 20) + int8_t rssi; +}; + +/** + * Describes the current status of the BLE request in the platform. + * + * @since v1.8 + */ +struct chreBleScanStatus { + //! The currently configured report delay in the scan configuration. + //! If enabled is false, this value does not have meaning. + uint32_t reportDelayMs; + + //! True if the BLE scan is currently enabled. This can be set to false + //! if BLE scan was temporarily disabled (e.g. BT subsystem is down, + //! or due to user settings). + bool enabled; + + //! Reserved for future use - set to zero. + uint8_t reserved[3]; +}; + +/** + * Retrieves a set of flags indicating the BLE features supported by the + * current CHRE implementation. The value returned by this function must be + * consistent for the entire duration of the nanoapp's execution. + * + * The client must allow for more flags to be set in this response than it knows + * about, for example if the implementation supports a newer version of the API + * than the client was compiled against. + * + * @return A bitmask with zero or more CHRE_BLE_CAPABILITIES_* flags set. @see + * CHRE_BLE_CAPABILITIES + * + * @since v1.6 + */ +uint32_t chreBleGetCapabilities(void); + +/** + * Retrieves a set of flags indicating the BLE filtering features supported by + * the current CHRE implementation. The value returned by this function must be + * consistent for the entire duration of the nanoapp's execution. + * + * The client must allow for more flags to be set in this response than it knows + * about, for example if the implementation supports a newer version of the API + * than the client was compiled against. + * + * @return A bitmask with zero or more CHRE_BLE_FILTER_CAPABILITIES_* flags set. + * @see CHRE_BLE_FILTER_CAPABILITIES + * + * @since v1.6 + */ +uint32_t chreBleGetFilterCapabilities(void); + +/** + * Helper function to extract event type from eventTypeAndDataStatus as defined + * in the BT Core Spec v5.2, Vol 4, Part E, Section 7.7.65.13, LE Extended + * Advertising Report event, entry Event_Type. + * + * @see CHRE_BLE_EVENT + * + * @param eventTypeAndDataStatus Combined event type and data status + * + * @return The event type portion of eventTypeAndDataStatus + */ +static inline uint8_t chreBleGetEventType(uint8_t eventTypeAndDataStatus) { + return (eventTypeAndDataStatus & CHRE_BLE_EVENT_MASK_TYPE); +} + +/** + * Helper function to extract data status from eventTypeAndDataStatus as defined + * in the BT Core Spec v5.2, Vol 4, Part E, Section 7.7.65.13, LE Extended + * Advertising Report event, entry Event_Type. + * + * @see CHRE_BLE_EVENT + * + * @param eventTypeAndDataStatus Combined event type and data status + * + * @return The data status portion of eventTypeAndDataStatus + */ +static inline uint8_t chreBleGetDataStatus(uint8_t eventTypeAndDataStatus) { + return (eventTypeAndDataStatus & CHRE_BLE_EVENT_MASK_DATA_STATUS); +} + +/** + * Helper function to to combine an event type with a data status to create + * eventTypeAndDataStatus as defined in the BT Core Spec v5.2, Vol 4, Part E, + * Section 7.7.65.13, LE Extended Advertising Report event, entry Event_Type. + * + * @see CHRE_BLE_EVENT + * + * @param eventType Event type + * @param dataStatus Data status + * + * @return A combined eventTypeAndDataStatus + */ +static inline uint8_t chreBleGetEventTypeAndDataStatus(uint8_t eventType, + uint8_t dataStatus) { + return ((eventType & CHRE_BLE_EVENT_MASK_TYPE) | + (dataStatus & CHRE_BLE_EVENT_MASK_DATA_STATUS)); +} + +/** + * Nanoapps must define CHRE_NANOAPP_USES_BLE somewhere in their build + * system (e.g. Makefile) if the nanoapp needs to use the following BLE APIs. + * In addition to allowing access to these APIs, defining this macro will also + * ensure CHRE enforces that all host clients this nanoapp talks to have the + * required Android permissions needed to access BLE functionality by adding + * metadata to the nanoapp. + */ +#if defined(CHRE_NANOAPP_USES_BLE) || !defined(CHRE_IS_NANOAPP_BUILD) + +/** + * Start Bluetooth LE (BLE) scanning on CHRE. + * + * @see chreBleStartScanAsyncV1_9 for further details. + * + * @deprecated as of v1.9 due to the addition of the chreBleScanFilterV1_9 + * struct and a cookie parameter. New code should use + * chreBleStartScanAsyncV1_9() instead of this function. This function will be + * removed in a future version. + */ +bool chreBleStartScanAsync(enum chreBleScanMode mode, uint32_t reportDelayMs, + const struct chreBleScanFilter *filter); + +/** + * Start Bluetooth LE (BLE) scanning on CHRE. + * + * The result of the operation will be delivered asynchronously via the CHRE + * event CHRE_EVENT_BLE_ASYNC_RESULT. + * + * The scan results will be delivered asynchronously via the CHRE event + * CHRE_EVENT_BLE_ADVERTISEMENT. + * + * If CHRE_USER_SETTING_BLE_AVAILABLE is disabled, CHRE is expected to return an + * async result with error CHRE_ERROR_FUNCTION_DISABLED. If this setting is + * enabled, the Bluetooth subsystem may still be powered down in the scenario + * where the main Bluetooth toggle is disabled, but the Bluetooth scanning + * setting is enabled, and there is no request for BLE to be enabled at the + * Android level. In this scenario, CHRE will return an async result with error + * CHRE_ERROR_FUNCTION_DISABLED. + * + * To ensure that Bluetooth remains powered on in this settings configuration so + * that a nanoapp can scan, the nanoapp's Android host entity should use the + * BluetoothAdapter.enableBLE() API to register this request with the Android + * Bluetooth stack. + * + * If chreBleStartScanAsync() is called while a previous scan has been started, + * the previous scan will be stopped first and replaced with the new scan. + * + * Note that some corresponding Android parameters are missing from the CHRE + * API, where the following default or typical parameters are used: + * Callback type: CALLBACK_TYPE_ALL_MATCHES + * Result type: SCAN_RESULT_TYPE_FULL + * Match mode: MATCH_MODE_AGGRESSIVE + * Number of matches per filter: MATCH_NUM_MAX_ADVERTISEMENT + * Legacy-only: false + * PHY type: PHY_LE_ALL_SUPPORTED + * + * A CHRE_EVENT_BLE_SCAN_STATUS_CHANGE will be generated if the values in + * chreBleScanStatus changes as a result of this call. + * + * @param mode Scanning mode selected among enum chreBleScanMode + * @param reportDelayMs Maximum requested batching delay in ms. 0 indicates no + * batching. Note that the system may deliver results + * before the maximum specified delay is reached. + * @param filter Pointer to the requested best-effort filter configuration as + * defined by struct chreBleScanFilter. The ownership of filter + * and its nested elements remains with the caller, and the caller + * may release it as soon as chreBleStartScanAsync() returns. + * @param cookie An opaque value that will be included in the chreAsyncResult + * sent as a response to this request. + * + * @return True to indicate that the request was accepted. False otherwise. + * + * @since v1.9 + */ +bool chreBleStartScanAsyncV1_9(enum chreBleScanMode mode, + uint32_t reportDelayMs, + const struct chreBleScanFilterV1_9 *filter, + const void *cookie); + +/** + * Stops a CHRE BLE scan. + * + * @see chreBleStopScanAsyncV1_9 for further details. + * + * @deprecated as of v1.9 due to the addition of the cookie parameter. New code + * should use chreBleStopScanAsyncV1_9() instead of this function. This function + * will be removed in a future version. + */ +bool chreBleStopScanAsync(void); + +/** + * Stops a CHRE BLE scan. + * + * The result of the operation will be delivered asynchronously via the CHRE + * event CHRE_EVENT_BLE_ASYNC_RESULT. + * + * @param cookie An opaque value that will be included in the chreAsyncResult + * sent as a response to this request. + * + * @return True to indicate that the request was accepted. False otherwise. + * + * @since v1.9 + */ +bool chreBleStopScanAsyncV1_9(const void *cookie); + +/** + * Requests to immediately deliver batched scan results. The nanoapp must + * have an active BLE scan request. If a request is accepted, it will be treated + * as though the reportDelayMs has expired for a batched scan. Upon accepting + * the request, CHRE works to immediately deliver scan results currently kept in + * batching memory, if any, via regular CHRE_EVENT_BLE_ADVERTISEMENT events, + * followed by a CHRE_EVENT_BLE_FLUSH_COMPLETE event. + * + * If the underlying system fails to complete the flush operation within + * CHRE_BLE_FLUSH_COMPLETE_TIMEOUT_NS, CHRE will send a + * CHRE_EVENT_BLE_FLUSH_COMPLETE event with CHRE_ERROR_TIMEOUT. + * + * If multiple flush requests are made prior to flush completion, then the + * requesting nanoapp will receive all batched samples existing at the time of + * the latest flush request. In this case, the number of + * CHRE_EVENT_BLE_FLUSH_COMPLETE events received must equal the number of flush + * requests made. + * + * If chreBleStopScanAsync() is called while a flush operation is in progress, + * it is unspecified whether the flush operation will complete successfully or + * return an error, such as CHRE_ERROR_FUNCTION_DISABLED, but in any case, + * CHRE_EVENT_BLE_FLUSH_COMPLETE must still be delivered. The same applies if + * the Bluetooth user setting is disabled during a flush operation. + * + * If called while running on a CHRE API version below v1.7, this function + * returns false and has no effect. + * + * @param cookie An opaque value that will be included in the chreAsyncResult + * sent as a response to this request. + * + * @return True to indicate the request was accepted. False otherwise. + * + * @since v1.7 + */ +bool chreBleFlushAsync(const void *cookie); + +/** + * Requests to read the RSSI of a peer device on the given LE connection + * handle. + * + * If the request is accepted, the response will be delivered in a + * CHRE_EVENT_BLE_RSSI_READ event with the same cookie. + * + * The request may be rejected if resources are not available to service the + * request (such as if too many outstanding requests already exist). If so, the + * client may retry later. + * + * Note that the connectionHandle is valid only while the connection remains + * active. If a peer device disconnects then reconnects, the handle may change. + * BluetoothDevice#getConnectionHandle() can be used from the Android framework + * to get the latest handle upon reconnection. + * + * @param connectionHandle + * @param cookie An opaque value that will be included in the chreAsyncResult + * embedded in the response to this request. + * @return True if the request has been accepted and dispatched to the + * controller. False otherwise. + * + * @since v1.8 + * + */ +bool chreBleReadRssiAsync(uint16_t connectionHandle, const void *cookie); + +/** + * Retrieves the current state of the BLE scan on the platform. + * + * @param status A non-null pointer to where the scan status will be + * populated. + * + * @return True if the status was obtained successfully. + * + * @since v1.8 + */ +bool chreBleGetScanStatus(struct chreBleScanStatus *status); + +/** + * Definitions for handling unsupported CHRE BLE scenarios. + */ +#else // defined(CHRE_NANOAPP_USES_BLE) || !defined(CHRE_IS_NANOAPP_BUILD) + +#define CHRE_BLE_PERM_ERROR_STRING \ + "CHRE_NANOAPP_USES_BLE must be defined when building this nanoapp in " \ + "order to refer to " + +#define chreBleStartScanAsync(...) \ + CHRE_BUILD_ERROR(CHRE_BLE_PERM_ERROR_STRING "chreBleStartScanAsync") + +#define chreBleStopScanAsync(...) \ + CHRE_BUILD_ERROR(CHRE_BLE_PERM_ERROR_STRING "chreBleStopScanAsync") + +#define chreBleFlushAsync(...) \ + CHRE_BUILD_ERROR(CHRE_BLE_PERM_ERROR_STRING "chreBleFlushAsync") + +#define chreBleReadRssiAsync(...) \ + CHRE_BUILD_ERROR(CHRE_BLE_PERM_ERROR_STRING "chreBleReadRssiAsync") + +#endif // defined(CHRE_NANOAPP_USES_BLE) || !defined(CHRE_IS_NANOAPP_BUILD) + +#ifdef __cplusplus +} +#endif + +#endif /* CHRE_BLE_H_ */
diff --git a/chre_api/legacy/v1_10/chre/common.h b/chre_api/legacy/v1_10/chre/common.h new file mode 100644 index 0000000..beecc46 --- /dev/null +++ b/chre_api/legacy/v1_10/chre/common.h
@@ -0,0 +1,208 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// IWYU pragma: private, include "chre_api/chre.h" +// IWYU pragma: friend chre/.*\.h + +#ifndef _CHRE_COMMON_H_ +#define _CHRE_COMMON_H_ + +/** + * @file + * Definitions shared across multiple CHRE header files + */ + +#include <stdbool.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Mask of the 5 most significant bytes in a 64-bit nanoapp or CHRE platform + * identifier, which represents the vendor ID portion of the ID. + */ +#define CHRE_VENDOR_ID_MASK UINT64_C(0xFFFFFFFFFF000000) + +/** + * Vendor ID "Googl". Used in nanoapp IDs and CHRE platform IDs developed and + * released by Google. + */ +#define CHRE_VENDOR_ID_GOOGLE UINT64_C(0x476F6F676C000000) + +/** + * Vendor ID "GoogT". Used for nanoapp IDs associated with testing done by + * Google. + */ +#define CHRE_VENDOR_ID_GOOGLE_TEST UINT64_C(0x476F6F6754000000) + +/** + * Helper macro to mask off all bytes other than the vendor ID (most significant + * 5 bytes) in 64-bit nanoapp and CHRE platform identifiers. + * + * @see chreGetNanoappInfo() + * @see chreGetPlatformId() + */ +#define CHRE_EXTRACT_VENDOR_ID(id) ((id) & CHRE_VENDOR_ID_MASK) + +/** + * Number of nanoseconds in one second, represented as an unsigned 64-bit + * integer + */ +#define CHRE_NSEC_PER_SEC UINT64_C(1000000000) + +/** + * General timeout for asynchronous API requests. Unless specified otherwise, a + * function call that returns data asynchronously via an event, such as + * CHRE_EVENT_ASYNC_GNSS_RESULT, must do so within this amount of time. + */ +#define CHRE_ASYNC_RESULT_TIMEOUT_NS (5 * CHRE_NSEC_PER_SEC) + +/** + * A generic listing of error codes for use in {@link #chreAsyncResult} and + * elsewhere. In general, module-specific error codes may be added to this enum, + * but effort should be made to come up with a generic name that still captures + * the meaning of the error. + */ +// LINT.IfChange +enum chreError { + //! No error occurred + CHRE_ERROR_NONE = 0, + + //! An unspecified failure occurred + CHRE_ERROR = 1, + + //! One or more supplied arguments are invalid + CHRE_ERROR_INVALID_ARGUMENT = 2, + + //! Unable to satisfy request because the system is busy + CHRE_ERROR_BUSY = 3, + + //! Unable to allocate memory + CHRE_ERROR_NO_MEMORY = 4, + + //! The requested feature is not supported + CHRE_ERROR_NOT_SUPPORTED = 5, + + //! A timeout occurred while processing the request + CHRE_ERROR_TIMEOUT = 6, + + //! The relevant capability is disabled, for example due to a user + //! configuration that takes precedence over this request + CHRE_ERROR_FUNCTION_DISABLED = 7, + + //! The request was rejected due to internal rate limiting of the requested + //! functionality - the client may try its request again after waiting an + //! unspecified amount of time + CHRE_ERROR_REJECTED_RATE_LIMIT = 8, + + //! The requested functionality is not currently accessible from the CHRE, + //! because another client, such as the main applications processor, is + //! currently controlling it. + CHRE_ERROR_FUNCTION_RESTRICTED_TO_OTHER_MASTER = 9, + CHRE_ERROR_FUNCTION_RESTRICTED_TO_OTHER_CLIENT = 9, + + //! This request is no longer valid. It may have been replaced by a newer + //! request before taking effect. + //! @since v1.6 + CHRE_ERROR_OBSOLETE_REQUEST = 10, + + //! A transient error occurred. The request can be retried. + //! @since v1.10 + CHRE_ERROR_TRANSIENT = 11, + + //! Unable to satisfy request because of missing permissions. + //! @since v1.10 + CHRE_ERROR_PERMISSION_DENIED = 12, + + //! Unable to satisfy request because the destination is not found. + //! @since v1.10 + CHRE_ERROR_DESTINATION_NOT_FOUND = 13, + + //!< Do not exceed this value when adding new error codes + CHRE_ERROR_LAST = UINT8_MAX, +}; +// LINT.ThenChange(../../../../core/include/chre/core/api_manager_common.h) + +/** + * Generic data structure to indicate the result of an asynchronous operation. + * + * @note + * The general model followed by CHRE for asynchronous operations is that a + * request function returns a boolean value that indicates whether the request + * was accepted for further processing. The actual result of the operation is + * provided in a subsequent event sent with an event type that is defined in the + * specific API. Typically, a "cookie" parameter is supplied to allow the client + * to tie the response to a specific request, or pass data through, etc. The + * response is expected to be delivered within CHRE_ASYNC_RESULT_TIMEOUT_NS if + * not specified otherwise. + * + * The CHRE implementation must allow for multiple asynchronous requests to be + * outstanding at a given time, under reasonable resource constraints. Further, + * requests must be processed in the same order as supplied by the client of the + * API in order to maintain causality. Using GNSS as an example, if a client + * calls chreGnssLocationSessionStartAsync() and then immediately calls + * chreGnssLocationSessionStopAsync(), the final result must be that the + * location session is stopped. Whether requests always complete in the + * order that they are given is implementation-defined. For example, if a client + * calls chreGnssLocationSessionStart() and then immediately calls + * chreGnssMeasurementSessionStart(), it is possible for the + * CHRE_EVENT_GNSS_RESULT associated with the measurement session to be + * delivered before the one for the location session. + */ +struct chreAsyncResult { + //! Indicates the request associated with this result. The interpretation of + //! values in this field is dependent upon the event type provided when this + //! result was delivered. + uint8_t requestType; + + //! Set to true if the request was successfully processed + bool success; + + //! If the request failed (success is false), this is set to a value from + //! enum chreError (other than CHRE_ERROR_NONE), which may provide + //! additional information about the nature of the failure. + //! @see #chreError + uint8_t errorCode; + + //! Reserved for future use, set to 0 + uint8_t reserved; + + //! Set to the cookie parameter given to the request function tied to this + //! result + const void *cookie; +}; + +/** + * A structure to store an event describing the end of batched events. + * + * @since v1.8 + */ +struct chreBatchCompleteEvent { + //! Indicates the type of event (of type CHRE_EVENT_TYPE_*) that was + //! batched. + uint16_t eventType; + + //! Reserved for future use, set to 0 + uint8_t reserved[2]; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _CHRE_COMMON_H_ */
diff --git a/chre_api/legacy/v1_10/chre/event.h b/chre_api/legacy/v1_10/chre/event.h new file mode 100644 index 0000000..d08b7d0 --- /dev/null +++ b/chre_api/legacy/v1_10/chre/event.h
@@ -0,0 +1,1044 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// IWYU pragma: private, include "chre_api/chre.h" +// IWYU pragma: friend chre/.*\.h + +#ifndef _CHRE_EVENT_H_ +#define _CHRE_EVENT_H_ + +/** + * @file + * Context Hub Runtime Environment API dealing with events and messages. + */ + +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> + +#include <chre/toolchain.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The CHRE implementation is required to provide the following preprocessor + * defines via the build system. + * + * CHRE_MESSAGE_TO_HOST_MAX_SIZE: The maximum size, in bytes, allowed for + * a message sent to chreSendMessageToHostEndpoint(). This must be at least + * CHRE_MESSAGE_TO_HOST_MINIMUM_MAX_SIZE. If the system supports a larger + * maximum size, it will be defined as the return value of + * chreGetMessageToHostMaxSize(). + */ +#ifndef CHRE_MESSAGE_TO_HOST_MAX_SIZE +#error CHRE_MESSAGE_TO_HOST_MAX_SIZE must be defined by the CHRE implementation +#endif + +/** + * The minimum size, in bytes, any CHRE implementation will use for + * CHRE_MESSAGE_TO_HOST_MAX_SIZE is set to 1000 for v1.5+ CHRE implementations, + * and 128 for v1.0-v1.4 implementations (previously kept in + * CHRE_MESSAGE_TO_HOST_MINIMUM_MAX_SIZE, which has been removed). + * + * All CHRE implementations supporting v1.5+ must support the raised limit of + * 1000 bytes, however a nanoapp compiled against v1.5 cannot assume this + * limit if there is a possibility their binary will run on a v1.4 or earlier + * implementation that had a lower limit. To allow for nanoapp compilation in + * these situations, CHRE_MESSAGE_TO_HOST_MAX_SIZE must be set to the minimum + * value the nanoapp may encounter, and CHRE_NANOAPP_SUPPORTS_PRE_V1_5 can be + * defined to skip the compile-time check. + */ +#if (!defined(CHRE_NANOAPP_SUPPORTS_PRE_V1_5) && \ + CHRE_MESSAGE_TO_HOST_MAX_SIZE < 1000) || \ + (defined(CHRE_NANOAPP_SUPPORTS_PRE_V1_5) && \ + CHRE_MESSAGE_TO_HOST_MAX_SIZE < 128) +#error CHRE_MESSAGE_TO_HOST_MAX_SIZE is too small. +#endif + +/** + * CHRE_MESSAGE_TO_HOST_MAX_SIZE must be less than or equal to 4096. If the system + * supports a larger maximum size, it will be defined as the return value of + * chreGetMessageToHostMaxSize(). + */ +#if CHRE_MESSAGE_TO_HOST_MAX_SIZE > 4096 +#error CHRE_MESSAGE_TO_HOST_MAX_SIZE must be <= 4096 +#endif + +/** + * The lowest numerical value legal for a user-defined event. + * + * The system reserves all event values from 0 to 0x7FFF, inclusive. + * User events may use any value in the range 0x8000 to 0xFFFF, inclusive. + * + * Note that the same event values might be used by different nanoapps + * for different meanings. This is not a concern, as these values only + * have meaning when paired with the originating nanoapp. + */ +#define CHRE_EVENT_FIRST_USER_VALUE UINT16_C(0x8000) + +/** + * nanoappHandleEvent argument: struct chreMessageFromHostData + * + * The format of the 'message' part of this structure is left undefined, + * and it's up to the nanoapp and host to have an established protocol + * beforehand. + */ +#define CHRE_EVENT_MESSAGE_FROM_HOST UINT16_C(0x0001) + +/** + * nanoappHandleEvent argument: 'cookie' given to chreTimerSet() method. + * + * Indicates that a timer has elapsed, in accordance with how chreTimerSet() was + * invoked. + */ +#define CHRE_EVENT_TIMER UINT16_C(0x0002) + +/** + * nanoappHandleEvent argument: struct chreNanoappInfo + * + * Indicates that a nanoapp has successfully started (its nanoappStart() + * function has been called, and it returned true) and is able to receive events + * sent via chreSendEvent(). Note that this event is not sent for nanoapps that + * were started prior to the current nanoapp - use chreGetNanoappInfo() to + * determine if another nanoapp is already running. + * + * @see chreConfigureNanoappInfoEvents + * @since v1.1 + */ +#define CHRE_EVENT_NANOAPP_STARTED UINT16_C(0x0003) + +/** + * nanoappHandleEvent argument: struct chreNanoappInfo + * + * Indicates that a nanoapp has stopped executing and is no longer able to + * receive events sent via chreSendEvent(). Any events sent prior to receiving + * this event are not guaranteed to have been delivered. + * + * @see chreConfigureNanoappInfoEvents + * @since v1.1 + */ +#define CHRE_EVENT_NANOAPP_STOPPED UINT16_C(0x0004) + +/** + * nanoappHandleEvent argument: NULL + * + * Indicates that CHRE has observed the host wake from low-power sleep state. + * + * @see chreConfigureHostSleepStateEvents + * @since v1.2 + */ +#define CHRE_EVENT_HOST_AWAKE UINT16_C(0x0005) + +/** + * nanoappHandleEvent argument: NULL + * + * Indicates that CHRE has observed the host enter low-power sleep state. + * + * @see chreConfigureHostSleepStateEvents + * @since v1.2 + */ +#define CHRE_EVENT_HOST_ASLEEP UINT16_C(0x0006) + +/** + * nanoappHandleEvent argument: NULL + * + * Indicates that CHRE is collecting debug dumps. Nanoapps can call + * chreDebugDumpLog() to log their debug data while handling this event. + * + * @see chreConfigureDebugDumpEvent + * @see chreDebugDumpLog + * @since v1.4 + */ +#define CHRE_EVENT_DEBUG_DUMP UINT16_C(0x0007) + +/** + * nanoappHandleEvent argument: struct chreHostEndpointNotification + * + * Notifications event regarding a host endpoint. + * + * @see chreConfigureHostEndpointNotifications + * @since v1.6 + */ +#define CHRE_EVENT_HOST_ENDPOINT_NOTIFICATION UINT16_C(0x0008) + +/** + * Indicates a RPC request from a nanoapp. + * + * @since v1.9 + */ +#define CHRE_EVENT_RPC_REQUEST UINT16_C(0x00009) + +/** + * Indicates a RPC response from a nanoapp. + * + * @since v1.9 + */ +#define CHRE_EVENT_RPC_RESPONSE UINT16_C(0x0000A) + +/** + * nanoappHandleEvent argument: struct chreAsyncResult + * + * Async status for reliable messages. The resultType field + * will be populated with a value of 0. + * + * @see chreSendReliableMessageAsync + * @since v1.10 + */ +#define CHRE_EVENT_RELIABLE_MSG_ASYNC_RESULT UINT16_C(0x000B) + +/** + * First possible value for CHRE_EVENT_SENSOR events. + * + * This allows us to separately define our CHRE_EVENT_SENSOR_* events in + * chre/sensor.h, without fear of collision with other event values. + */ +#define CHRE_EVENT_SENSOR_FIRST_EVENT UINT16_C(0x0100) + +/** + * Last possible value for CHRE_EVENT_SENSOR events. + * + * This allows us to separately define our CHRE_EVENT_SENSOR_* events in + * chre/sensor.h, without fear of collision with other event values. + */ +#define CHRE_EVENT_SENSOR_LAST_EVENT UINT16_C(0x02FF) + +/** + * First event in the block reserved for GNSS. These events are defined in + * chre/gnss.h. + */ +#define CHRE_EVENT_GNSS_FIRST_EVENT UINT16_C(0x0300) +#define CHRE_EVENT_GNSS_LAST_EVENT UINT16_C(0x030F) + +/** + * First event in the block reserved for WiFi. These events are defined in + * chre/wifi.h. + */ +#define CHRE_EVENT_WIFI_FIRST_EVENT UINT16_C(0x0310) +#define CHRE_EVENT_WIFI_LAST_EVENT UINT16_C(0x031F) + +/** + * First event in the block reserved for WWAN. These events are defined in + * chre/wwan.h. + */ +#define CHRE_EVENT_WWAN_FIRST_EVENT UINT16_C(0x0320) +#define CHRE_EVENT_WWAN_LAST_EVENT UINT16_C(0x032F) + +/** + * First event in the block reserved for audio. These events are defined in + * chre/audio.h. + */ +#define CHRE_EVENT_AUDIO_FIRST_EVENT UINT16_C(0x0330) +#define CHRE_EVENT_AUDIO_LAST_EVENT UINT16_C(0x033F) + +/** + * First event in the block reserved for settings changed notifications. + * These events are defined in chre/user_settings.h + * + * @since v1.5 + */ +#define CHRE_EVENT_SETTING_CHANGED_FIRST_EVENT UINT16_C(0x340) +#define CHRE_EVENT_SETTING_CHANGED_LAST_EVENT UINT16_C(0x34F) + +/** + * First event in the block reserved for Bluetooth LE. These events are defined + * in chre/ble.h. + */ +#define CHRE_EVENT_BLE_FIRST_EVENT UINT16_C(0x0350) +#define CHRE_EVENT_BLE_LAST_EVENT UINT16_C(0x035F) + +/** + * First in the extended range of values dedicated for internal CHRE + * implementation usage. + * + * This range is semantically the same as the internal event range defined + * below, but has been extended to allow for more implementation-specific events + * to be used. + * + * @since v1.1 + */ +#define CHRE_EVENT_INTERNAL_EXTENDED_FIRST_EVENT UINT16_C(0x7000) + +/** + * First in a range of values dedicated for internal CHRE implementation usage. + * + * If a CHRE wishes to use events internally, any values within this range + * are assured not to be taken by future CHRE API additions. + */ +#define CHRE_EVENT_INTERNAL_FIRST_EVENT UINT16_C(0x7E00) + +/** + * Last in a range of values dedicated for internal CHRE implementation usage. + * + * If a CHRE wishes to use events internally, any values within this range + * are assured not to be taken by future CHRE API additions. + */ +#define CHRE_EVENT_INTERNAL_LAST_EVENT UINT16_C(0x7FFF) + +/** + * A special value for the hostEndpoint argument in + * chreSendMessageToHostEndpoint() that indicates that the message should be + * delivered to all host endpoints. This value will not be used in the + * hostEndpoint field of struct chreMessageFromHostData supplied with + * CHRE_EVENT_MESSAGE_FROM_HOST. + * + * @since v1.1 + */ +#define CHRE_HOST_ENDPOINT_BROADCAST UINT16_C(0xFFFF) + +/** + * A special value for hostEndpoint in struct chreMessageFromHostData that + * indicates that a host endpoint is unknown or otherwise unspecified. This + * value may be received in CHRE_EVENT_MESSAGE_FROM_HOST, but it is not valid to + * provide it to chreSendMessageToHostEndpoint(). + * + * @since v1.1 + */ +#define CHRE_HOST_ENDPOINT_UNSPECIFIED UINT16_C(0xFFFE) + +/** + * Bitmask values that can be given as input to the messagePermissions parameter + * of chreSendMessageWithPermissions(). These values are typically used by + * nanoapps when they used data from the corresponding CHRE APIs to produce the + * message contents being sent and is used to attribute permissions usage on + * the Android side. See chreSendMessageWithPermissions() for more details on + * how these values are used when sending a message. + * + * Values in the range + * [CHRE_MESSAGE_PERMISSION_VENDOR_START, CHRE_MESSAGE_PERMISSION_VENDOR_END] + * are reserved for vendors to use when adding support for permission-gated APIs + * in their implementations. + * + * On the Android side, CHRE permissions are mapped as follows: + * - CHRE_MESSAGE_PERMISSION_AUDIO: android.permission.RECORD_AUDIO + * - CHRE_MESSAGE_PERMISSION_GNSS, CHRE_MESSAGE_PERMISSION_WIFI, and + * CHRE_MESSAGE_PERMISSION_WWAN: android.permission.ACCESS_FINE_LOCATION, and + * android.permissions.ACCESS_BACKGROUND_LOCATION + * + * @since v1.5 + * + * @defgroup CHRE_MESSAGE_PERMISSION + * @{ + */ + +#define CHRE_MESSAGE_PERMISSION_NONE UINT32_C(0) +#define CHRE_MESSAGE_PERMISSION_AUDIO UINT32_C(1) +#define CHRE_MESSAGE_PERMISSION_GNSS (UINT32_C(1) << 1) +#define CHRE_MESSAGE_PERMISSION_WIFI (UINT32_C(1) << 2) +#define CHRE_MESSAGE_PERMISSION_WWAN (UINT32_C(1) << 3) +#define CHRE_MESSAGE_PERMISSION_BLE (UINT32_C(1) << 4) +#define CHRE_MESSAGE_PERMISSION_VENDOR_START (UINT32_C(1) << 24) +#define CHRE_MESSAGE_PERMISSION_VENDOR_END (UINT32_C(1) << 31) + +/** @} */ + +/** + * Reserved message type for RPC messages. + * + * @see chreSendMessageWithPermissions + * + * @since v1.9 + */ +#define CHRE_MESSAGE_TYPE_RPC UINT32_C(0x7FFFFFF5) + +/** + * @see chrePublishRpcServices + * + * @since v1.8 + */ +#define CHRE_MINIMUM_RPC_SERVICE_LIMIT UINT8_C(4) + +/** + * Data provided with CHRE_EVENT_MESSAGE_FROM_HOST. + */ +struct chreMessageFromHostData { + /** + * Message type supplied by the host. + * + * @note In CHRE API v1.0, support for forwarding this field from the host + * was not strictly required, and some implementations did not support it. + * However, its support is mandatory as of v1.1. + */ + union { + /** + * The preferred name to use when referencing this field. + * + * @since v1.1 + */ + uint32_t messageType; + + /** + * @deprecated This is the name for the messageType field used in v1.0. + * Left to allow code to compile against both v1.0 and v1.1 of the API + * definition without needing to use #ifdefs. This will be removed in a + * future API update - use messageType instead. + */ + uint32_t reservedMessageType; + }; + + /** + * The size, in bytes of the following 'message'. + * + * This can be 0. + */ + uint32_t messageSize; + + /** + * The message from the host. + * + * These contents are of a format that the host and nanoapp must have + * established beforehand. + * + * This data is 'messageSize' bytes in length. Note that if 'messageSize' + * is 0, this might be NULL. + */ + const void *message; + + /** + * An identifier for the host-side entity that sent this message. Unless + * this is set to CHRE_HOST_ENDPOINT_UNSPECIFIED, it can be used in + * chreSendMessageToHostEndpoint() to send a directed reply that will only + * be received by the given entity on the host. Endpoint identifiers are + * opaque values assigned at runtime, so they cannot be assumed to always + * describe a specific entity across restarts. + * + * If running on a CHRE API v1.0 implementation, this field will always be + * set to CHRE_HOST_ENDPOINT_UNSPECIFIED. + * + * @since v1.1 + */ + uint16_t hostEndpoint; +}; + +/** + * Provides metadata for a nanoapp in the system. + */ +struct chreNanoappInfo { + /** + * Nanoapp identifier. The convention for populating this value is to set + * the most significant 5 bytes to a value that uniquely identifies the + * vendor, and the lower 3 bytes identify the nanoapp. + */ + uint64_t appId; + + /** + * Nanoapp version. The semantics of this field are defined by the nanoapp, + * however nanoapps are recommended to follow the same scheme used for the + * CHRE version exposed in chreGetVersion(). That is, the most significant + * byte represents the major version, the next byte the minor version, and + * the lower two bytes the patch version. + */ + uint32_t version; + + /** + * The instance ID of this nanoapp, which can be used in chreSendEvent() to + * address an event specifically to this nanoapp. This identifier is + * guaranteed to be unique among all nanoapps in the system. + * + * As of CHRE API v1.6, instance ID is guaranteed to never be greater than + * UINT16_MAX. This allows for the instance ID be packed with other data + * inside a 32-bit integer (useful for RPC routing). + */ + uint32_t instanceId; + + /** + * Reserved for future use. + * Always set to 0. + */ + uint8_t reserved[3]; + + /** + * The number of RPC services exposed by this nanoapp. + * The service details are available in the rpcServices array. + * Must always be set to 0 when running on a CHRE implementation prior to + * v1.8 + * + * @since v1.8 + */ + uint8_t rpcServiceCount; + + /* + * Array of RPC services published by this nanoapp. + * Services are published via chrePublishRpcServices. + * The array contains rpcServiceCount entries. + * + * The pointer is only valid when rpcServiceCount is greater than 0. + * + * @since v1.8 + */ + const struct chreNanoappRpcService *rpcServices; +}; + +/** + * The types of notification events that can be included in struct + * chreHostEndpointNotification. + * + * @defgroup HOST_ENDPOINT_NOTIFICATION_TYPE + * @{ + */ +#define HOST_ENDPOINT_NOTIFICATION_TYPE_DISCONNECT UINT8_C(0) +/** @} */ + +/** + * Data provided in CHRE_EVENT_HOST_ENDPOINT_NOTIFICATION. + */ +struct chreHostEndpointNotification { + /** + * The ID of the host endpoint that this notification is for. + */ + uint16_t hostEndpointId; + + /** + * The type of notification this event represents, which should be + * one of the HOST_ENDPOINT_NOTIFICATION_TYPE_* values. + */ + uint8_t notificationType; + + /** + * Reserved for future use, must be zero. + */ + uint8_t reserved; +}; + +//! The maximum length of a host endpoint's name. +#define CHRE_MAX_ENDPOINT_NAME_LEN (51) + +//! The maximum length of a host endpoint's tag. +#define CHRE_MAX_ENDPOINT_TAG_LEN (51) + +/** + * The type of host endpoint that can be used in the hostEndpointType field + * of chreHostEndpointInfo. + * + * @since v1.6 + * + * @defgroup CHRE_HOST_ENDPOINT_TYPE_ + * @{ + */ + +//! The host endpoint is part of the Android system framework. +#define CHRE_HOST_ENDPOINT_TYPE_FRAMEWORK UINT8_C(0x00) + +//! The host endpoint is an Android app. +#define CHRE_HOST_ENDPOINT_TYPE_APP UINT8_C(0x01) + +//! The host endpoint is an Android native program. +#define CHRE_HOST_ENDPOINT_TYPE_NATIVE UINT8_C(0x02) + +//! Values in the range [CHRE_HOST_ENDPOINT_TYPE_VENDOR_START, +//! CHRE_HOST_ENDPOINT_TYPE_VENDOR_END] can be a custom defined host endpoint +//! type for platform-specific vendor use. +#define CHRE_HOST_ENDPOINT_TYPE_VENDOR_START UINT8_C(0x80) +#define CHRE_HOST_ENDPOINT_TYPE_VENDOR_END UINT8_C(0xFF) + +/** @} */ + +/** + * Provides metadata for a host endpoint. + * + * @since v1.6 + */ +struct chreHostEndpointInfo { + //! The endpoint ID of this host. + uint16_t hostEndpointId; + + //! The type of host endpoint, which must be set to one of the + //! CHRE_HOST_ENDPOINT_TYPE_* values or a value in the vendor-reserved + //! range. + uint8_t hostEndpointType; + + //! Flag indicating if the packageName/endpointName field is valid. + uint8_t isNameValid : 1; + + //! Flag indicating if the attributionTag/endpointTag field is valid. + uint8_t isTagValid : 1; + + //! A union of null-terminated host name strings. + union { + //! The Android package name associated with this host, valid if the + //! hostEndpointType is CHRE_HOST_ENDPOINT_TYPE_APP or + //! CHRE_HOST_ENDPOINT_TYPE_FRAMEWORK. Refer to the Android documentation + //! for the package attribute in the app manifest. + char packageName[CHRE_MAX_ENDPOINT_NAME_LEN]; + + //! A generic endpoint name that can be used for endpoints that + //! may not have a package name. + char endpointName[CHRE_MAX_ENDPOINT_NAME_LEN]; + }; + + //! A union of null-terminated host tag strings for further identification. + union { + //! The attribution tag associated with this host that is used to audit + //! access to data, which can be valid if the hostEndpointType is + //! CHRE_HOST_ENDPOINT_TYPE_APP. Refer to the Android documentation + //! regarding data audit using attribution tags. + char attributionTag[CHRE_MAX_ENDPOINT_TAG_LEN]; + + //! A generic endpoint tag that can be used for endpoints that + //! may not have an attribution tag. + char endpointTag[CHRE_MAX_ENDPOINT_TAG_LEN]; + }; +}; + +/** + * An RPC service exposed by a nanoapp. + * + * The implementation of the RPC interface is not defined by the HAL, and is written + * at the messaging endpoint layers (Android app and/or CHRE nanoapp). NanoappRpcService + * contains the informational metadata to be consumed by the RPC interface layer. + */ +struct chreNanoappRpcService { + /** + * The unique 64-bit ID of an RPC service exposed by a nanoapp. Note that + * the uniqueness is only required within the nanoapp's domain (i.e. the + * combination of the nanoapp ID and service id must be unique). + */ + uint64_t id; + + /** + * The software version of this service, which follows the sematic + * versioning scheme (see semver.org). It follows the format + * major.minor.patch, where major and minor versions take up one byte + * each, and the patch version takes up the final 2 bytes. + */ + uint32_t version; +}; + +/** + * Callback which frees data associated with an event. + * + * This callback is (optionally) provided to the chreSendEvent() method as + * a means for freeing the event data and performing any other cleanup + * necessary when the event is completed. When this callback is invoked, + * 'eventData' is no longer needed and can be released. + * + * @param eventType The 'eventType' argument from chreSendEvent(). + * @param eventData The 'eventData' argument from chreSendEvent(). + * + * @see chreSendEvent + */ +typedef void (chreEventCompleteFunction)(uint16_t eventType, void *eventData); + +/** + * Callback which frees a message. + * + * This callback is (optionally) provided to the chreSendMessageToHostEndpoint() + * method as a means for freeing the message. When this callback is invoked, + * 'message' is no longer needed and can be released. Note that this in + * no way assures that said message did or did not make it to the host, simply + * that this memory is no longer needed. + * + * @param message The 'message' argument from chreSendMessageToHostEndpoint(). + * @param messageSize The 'messageSize' argument from + * chreSendMessageToHostEndpoint(). + * + * @see chreSendMessageToHostEndpoint + */ +typedef void (chreMessageFreeFunction)(void *message, size_t messageSize); + + +/** + * Enqueue an event to be sent to another nanoapp. + * + * @param eventType This is a user-defined event type, of at least the + * value CHRE_EVENT_FIRST_USER_VALUE. It is illegal to attempt to use any + * of the CHRE_EVENT_* values reserved for the CHRE. + * @param eventData A pointer value that will be understood by the receiving + * app. Note that NULL is perfectly acceptable. It also is not required + * that this be a valid pointer, although if this nanoapp is intended to + * work on arbitrary CHRE implementations, then the size of a + * pointer cannot be assumed to be a certain size. Note that the caller + * no longer owns this memory after the call. + * @param freeCallback A pointer to a callback function. After the lifetime + * of 'eventData' is over (either through successful delivery or the event + * being dropped), this callback will be invoked. This argument is allowed + * to be NULL, in which case no callback will be invoked. + * @param targetInstanceId The ID of the instance we're delivering this event + * to. Note that this is allowed to be our own instance. The instance ID + * of a nanoapp can be retrieved by using chreGetNanoappInfoByInstanceId(). + * @return true if the event was enqueued, false otherwise. Note that even + * if this method returns 'false', the 'freeCallback' will be invoked, + * if non-NULL. Note in the 'false' case, the 'freeCallback' may be + * invoked directly from within chreSendEvent(), so it's necessary + * for nanoapp authors to avoid possible recursion with this. + * + * @see chreEventDataFreeFunction + */ +bool chreSendEvent(uint16_t eventType, void *eventData, + chreEventCompleteFunction *freeCallback, + uint32_t targetInstanceId); + +/** + * Send a message to the host, using the broadcast endpoint + * CHRE_HOST_ENDPOINT_BROADCAST. Refer to chreSendMessageToHostEndpoint() for + * further details. + * + * @see chreSendMessageToHostEndpoint + * + * @deprecated New code should use chreSendMessageToHostEndpoint() instead of + * this function. A future update to the API may cause references to this + * function to produce a compiler warning. + */ +bool chreSendMessageToHost(void *message, uint32_t messageSize, + uint32_t messageType, + chreMessageFreeFunction *freeCallback) + CHRE_DEPRECATED("Use chreSendMessageToHostEndpoint instead"); + +/** + * Send a message to the host, using CHRE_MESSAGE_PERMISSION_NONE for the + * associated message permissions. This method must only be used if no data + * provided by CHRE's audio, GNSS, WiFi, and WWAN APIs was used to produce the + * contents of the message being sent. Refer to chreSendMessageWithPermissions() + * for further details. + * + * @see chreSendMessageWithPermissions + * + * @since v1.1 + */ +bool chreSendMessageToHostEndpoint(void *message, size_t messageSize, + uint32_t messageType, uint16_t hostEndpoint, + chreMessageFreeFunction *freeCallback); + +/** + * Send a message to the host, waking it up if it is currently asleep. + * + * This message is by definition arbitrarily defined. Since we're not + * just a passing a pointer to memory around the system, but need to copy + * this into various buffers to send it to the host, the CHRE + * implementation cannot be asked to support an arbitrarily large message + * size. As a result, we have the CHRE implementation define + * CHRE_MESSAGE_TO_HOST_MAX_SIZE. + * + * CHRE_MESSAGE_TO_HOST_MAX_SIZE is not given a value by the Platform API. The + * Platform API does define CHRE_MESSAGE_TO_HOST_MINIMUM_MAX_SIZE, and requires + * that CHRE_MESSAGE_TO_HOST_MAX_SIZE is at least that value. + * + * As a result, if your message sizes are all less than + * CHRE_MESSAGE_TO_HOST_MINIMUM_MAX_SIZE, then you have no concerns on any + * CHRE implementation. If your message sizes are larger, you'll need to + * come up with a strategy for splitting your message across several calls + * to this method. As long as that strategy works for + * CHRE_MESSAGE_TO_HOST_MINIMUM_MAX_SIZE, it will work across all CHRE + * implementations (although on some implementations less calls to this + * method may be necessary). + * + * When sending a message to the host, the ContextHub service will enforce + * the host client has been granted Android-level permissions corresponding to + * the ones the nanoapp declares it uses through CHRE_NANOAPP_USES_AUDIO, etc. + * In addition to this, the permissions bitmask provided as input to this method + * results in the Android framework using app-ops to verify and log access upon + * message delivery to an application. This is primarily useful for ensuring + * accurate attribution for messages generated using permission-controlled data. + * The bitmask declared by the nanoapp for this message must be a + * subset of the permissions it declared it would use at build time or the + * message will be rejected. + * + * Nanoapps must use this method if the data they are sending contains or was + * derived from any data sampled through CHRE's audio, GNSS, WiFi, or WWAN APIs. + * Additionally, if vendors add APIs to expose data that would be guarded by a + * permission in Android, vendors must support declaring a message permission + * through this method. + * + * @param message Pointer to a block of memory to send to the host. + * NULL is acceptable only if messageSize is 0. If non-NULL, this + * must be a legitimate pointer (that is, unlike chreSendEvent(), a small + * integral value cannot be cast to a pointer for this). Note that the + * caller no longer owns this memory after the call. + * @param messageSize The size, in bytes, of the given message. If this exceeds + * CHRE_MESSAGE_TO_HOST_MAX_SIZE, the message will be rejected. + * @param messageType Message type sent to the app on the host. + * NOTE: In CHRE API v1.0, support for forwarding this field to the host was + * not strictly required, and some implementations did not support it. + * However, its support is mandatory as of v1.1. + * NOTE: The value CHRE_MESSAGE_TYPE_RPC is reserved for usage by RPC + * libraries and normally should not be directly used by nanoapps. + * @param hostEndpoint An identifier for the intended recipient of the message, + * or CHRE_HOST_ENDPOINT_BROADCAST if all registered endpoints on the host + * should receive the message. Endpoint identifiers are assigned on the + * host side, and nanoapps may learn of the host endpoint ID of an intended + * recipient via an initial message sent by the host. This parameter is + * always treated as CHRE_HOST_ENDPOINT_BROADCAST if running on a CHRE API + * v1.0 implementation. CHRE_HOST_ENDPOINT_BROADCAST isn't allowed to be + * specified if anything other than CHRE_MESSAGE_PERMISSION_NONE is given + * as messagePermissions since doing so would potentially attribute + * permissions usage to host clients that don't intend to consume the data. + * @param messagePermissions Bitmasked CHRE_MESSAGE_PERMISSION_ values that will + * be converted to corresponding Android-level permissions and attributed + * the host endpoint upon consumption of the message. + * @param freeCallback A pointer to a callback function. After the lifetime + * of 'message' is over (which does not assure that 'message' made it to + * the host, just that the transport layer no longer needs this memory), + * this callback will be invoked. This argument is allowed + * to be NULL, in which case no callback will be invoked. + * @return true if the message was accepted for transmission, false otherwise. + * Note that even if this method returns 'false', the 'freeCallback' will + * be invoked, if non-NULL. In either case, the 'freeCallback' may be + * invoked directly from within chreSendMessageToHostEndpoint(), so it's + * necessary for nanoapp authors to avoid possible recursion with this. + * + * @see chreMessageFreeFunction + * + * @since v1.5 + */ +bool chreSendMessageWithPermissions(void *message, size_t messageSize, + uint32_t messageType, uint16_t hostEndpoint, + uint32_t messagePermissions, + chreMessageFreeFunction *freeCallback); + +/** + * Send a reliable message to the host. + * + * A reliable message is similar to a message sent by + * chreSendMessageWithPermissions() with the difference that the host + * acknowledges the message by sending a status back to the nanoapp, and the + * CHRE implementation takes care of retries to help mitigate transient + * failures. The final result of attempting to deliver the message is given + * via a CHRE_EVENT_RELIABLE_MSG_ASYNC_RESULT event. The maximum time until the + * nanoapp will receive the result is CHRE_ASYNC_RESULT_TIMEOUT_NS. + * + * The free callback is invoked before the async status is delivered to the + * nanoapp via the CHRE_EVENT_RELIABLE_MSG_ASYNC_RESULT event and does not + * indicate successful delivery of the message. + * + * The API is similar to chreSendMessageWithPermissions() with a few + * differences: + * - chreSendReliableMessageAsync() takes an extra cookie that is part of the + * async result + * - When the message is accepted for transmission (the function returns true) + * then an async status is delivered to the nanoapp when the transmission + * completes either successfully or in error via the + * CHRE_EVENT_RELIABLE_MSG_ASYNC_RESULT event. + * - For any reliable messages pending completion at nanoapp unload: + * - At least one delivery attempt will be made. + * - The free callback will be invoked. + * - The async result event will not be delivered. + * - The error codes received are: + * - CHRE_ERROR_DESTINATION_NOT_FOUND if the destination was not found. + * - CHRE_ERROR if there was a permanent error. + * - CHRE_ERROR_TIMEOUT if there was no response from the recipient + * (a timeout). + * + * This is an optional feature, and this function will always return + * false if CHRE_CAPABILITIES_RELIABLE_MESSAGES is not indicated by + * chreGetCapabilities(). + * + * @see chreSendMessageWithPermissions + * + * @since v1.10 + */ +bool chreSendReliableMessageAsync(void *message, size_t messageSize, + uint32_t messageType, uint16_t hostEndpoint, + uint32_t messagePermissions, + chreMessageFreeFunction *freeCallback, + const void *cookie); + +/** + * Queries for information about a nanoapp running in the system. + * + * In the current API, appId is required to be unique, i.e. there cannot be two + * nanoapps running concurrently with the same appId. If this restriction is + * removed in a future API version and multiple instances of the same appId are + * present, this function must always return the first app to start. + * + * @param appId Identifier for the nanoapp that the caller is requesting + * information about. + * @param info Output parameter. If this function returns true, this structure + * will be populated with details of the specified nanoapp. + * @return true if a nanoapp with the given ID is currently running, and the + * supplied info parameter was populated with its information. + * + * @since v1.1 + */ +bool chreGetNanoappInfoByAppId(uint64_t appId, struct chreNanoappInfo *info); + +/** + * Queries for information about a nanoapp running in the system, using the + * runtime unique identifier. This method can be used to get information about + * the sender of an event. + * + * @param instanceId + * @param info Output parameter. If this function returns true, this structure + * will be populated with details of the specified nanoapp. + * @return true if a nanoapp with the given instance ID is currently running, + * and the supplied info parameter was populated with its information. + * + * @since v1.1 + */ +bool chreGetNanoappInfoByInstanceId(uint32_t instanceId, + struct chreNanoappInfo *info); + +/** + * Configures whether this nanoapp will be notified when other nanoapps in the + * system start and stop, via CHRE_EVENT_NANOAPP_STARTED and + * CHRE_EVENT_NANOAPP_STOPPED. These events are disabled by default, and if a + * nanoapp is not interested in interacting with other nanoapps, then it does + * not need to register for them. However, if inter-nanoapp communication is + * desired, nanoapps are recommended to call this function from nanoappStart(). + * + * If running on a CHRE platform that only supports v1.0 of the CHRE API, this + * function has no effect. + * + * @param enable true to enable these events, false to disable + * + * @see CHRE_EVENT_NANOAPP_STARTED + * @see CHRE_EVENT_NANOAPP_STOPPED + * + * @since v1.1 + */ +void chreConfigureNanoappInfoEvents(bool enable); + +/** + * Configures whether this nanoapp will be notified when the host (applications + * processor) transitions between wake and sleep, via CHRE_EVENT_HOST_AWAKE and + * CHRE_EVENT_HOST_ASLEEP. As chreSendMessageToHostEndpoint() wakes the host if + * it is asleep, these events can be used to opportunistically send data to the + * host only when it wakes up for some other reason. Note that this event is + * not instantaneous - there is an inherent delay in CHRE observing power state + * changes of the host processor, which may be significant depending on the + * implementation, especially in the wake to sleep direction. Therefore, + * nanoapps are not guaranteed that messages sent to the host between AWAKE and + * ASLEEP events will not trigger a host wakeup. However, implementations must + * ensure that the nominal wake-up notification latency is strictly less than + * the minimum wake-sleep time of the host processor. Implementations are also + * encouraged to minimize this and related latencies where possible, to avoid + * unnecessary host wake-ups. + * + * These events are only sent on transitions, so the initial state will not be + * sent to the nanoapp as an event - use chreIsHostAwake(). + * + * @param enable true to enable these events, false to disable + * + * @see CHRE_EVENT_HOST_AWAKE + * @see CHRE_EVENT_HOST_ASLEEP + * + * @since v1.2 + */ +void chreConfigureHostSleepStateEvents(bool enable); + +/** + * Retrieves the current sleep/wake state of the host (applications processor). + * Note that, as with the CHRE_EVENT_HOST_AWAKE and CHRE_EVENT_HOST_ASLEEP + * events, there is no guarantee that CHRE's view of the host processor's sleep + * state is instantaneous, and it may also change between querying the state and + * performing a host-waking action like sending a message to the host. + * + * @return true if by CHRE's own estimation the host is currently awake, + * false otherwise + * + * @since v1.2 + */ +bool chreIsHostAwake(void); + +/** + * Configures whether this nanoapp will be notified when CHRE is collecting + * debug dumps, via CHRE_EVENT_DEBUG_DUMP. This event is disabled by default, + * and if a nanoapp is not interested in logging its debug data, then it does + * not need to register for it. + * + * @param enable true to enable receipt of this event, false to disable. + * + * @see CHRE_EVENT_DEBUG_DUMP + * @see chreDebugDumpLog + * + * @since v1.4 + */ +void chreConfigureDebugDumpEvent(bool enable); + +/** + * Configures whether this nanoapp will receive updates regarding a host + * endpoint that is connected with the Context Hub. + * + * If this API succeeds, the nanoapp will receive disconnection notifications, + * via the CHRE_EVENT_HOST_ENDPOINT_NOTIFICATION event with an eventData of type + * chreHostEndpointNotification with its notificationType set to + * HOST_ENDPOINT_NOTIFICATION_TYPE_DISCONNECT, which can be invoked if the host + * has disconnected from the Context Hub either explicitly or implicitly (e.g. + * crashes). Nanoapps can use this notifications to clean up any resources + * associated with this host endpoint. + * + * @param hostEndpointId The host endpoint ID to configure notifications for. + * @param enable true to enable notifications. + * + * @return true on success + * + * @see chreMessageFromHostData + * @see chreHostEndpointNotification + * @see CHRE_EVENT_HOST_ENDPOINT_NOTIFICATION + * + * @since v1.6 + */ +bool chreConfigureHostEndpointNotifications(uint16_t hostEndpointId, + bool enable); + +/** + * Publishes RPC services from this nanoapp. + * + * When this API is invoked, the list of RPC services will be provided to + * host applications interacting with the nanoapp. + * + * This function must be invoked from nanoappStart(), to guarantee stable output + * of the list of RPC services supported by the nanoapp. + * + * Although nanoapps are recommended to only call this API once with all + * services it intends to publish, if it is called multiple times, each + * call will append to the list of published services. + * + * Starting in CHRE API v1.8, the implementation must allow for a nanoapp to + * publish at least CHRE_MINIMUM_RPC_SERVICE_LIMIT services and at most + * UINT8_MAX services. If calling this function would result in exceeding + * the limit, the services must not be published and it must return false. + * + * @param services A non-null pointer to the list of RPC services to publish. + * @param numServices The number of services to publish, i.e. the length of the + * services array. + * + * @return true if the publishing is successful. + * + * @since v1.6 + */ +bool chrePublishRpcServices(struct chreNanoappRpcService *services, + size_t numServices); + +/** + * Retrieves metadata for a given host endpoint ID. + * + * This API will provide metadata regarding an endpoint associated with a + * host endpoint ID. The nanoapp should use this API to determine more + * information about a host endpoint that has sent a message to the nanoapp, + * after receiving a chreMessageFromHostData (which includes the endpoint ID). + * + * If the given host endpoint ID is not associated with a valid host (or if the + * client has disconnected from the Android or CHRE framework, i.e. no longer + * able to send messages to CHRE), this method will return false and info will + * not be populated. + * + * @param hostEndpointId The endpoint ID of the host to get info for. + * @param info The non-null pointer to where the metadata will be stored. + * + * @return true if info has been successfully populated. + * + * @since v1.6 + */ +bool chreGetHostEndpointInfo(uint16_t hostEndpointId, + struct chreHostEndpointInfo *info); + +#ifdef __cplusplus +} +#endif + +#endif /* _CHRE_EVENT_H_ */ +
diff --git a/chre_api/legacy/v1_10/chre/gnss.h b/chre_api/legacy/v1_10/chre/gnss.h new file mode 100644 index 0000000..a326e85 --- /dev/null +++ b/chre_api/legacy/v1_10/chre/gnss.h
@@ -0,0 +1,607 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// IWYU pragma: private, include "chre_api/chre.h" +// IWYU pragma: friend chre/.*\.h + +#ifndef _CHRE_GNSS_H_ +#define _CHRE_GNSS_H_ + +/** + * @file + * Global Navigation Satellite System (GNSS) API. + * + * These structures and definitions are based on the Android N GPS HAL. + * Refer to that header file (located at this path as of the time of this + * comment: hardware/libhardware/include/hardware/gps.h) and associated + * documentation for further details and explanations for these fields. + * References in comments like "(ref: GnssAccumulatedDeltaRangeState)" map to + * the relevant element in the GPS HAL where additional information can be + * found. + * + * In general, the parts of this API that are taken from the GPS HAL follow the + * naming conventions established in that interface rather than the CHRE API + * conventions, in order to avoid confusion and enable code re-use where + * applicable. + */ + + +#include <stdbool.h> +#include <stdint.h> + +#include <chre/common.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The set of flags that may be returned by chreGnssGetCapabilities() + * @defgroup CHRE_GNSS_CAPABILITIES + * @{ + */ + +//! A lack of flags indicates that GNSS is not supported in this CHRE +#define CHRE_GNSS_CAPABILITIES_NONE UINT32_C(0) + +//! GNSS position fixes are supported via chreGnssLocationSessionStartAsync() +#define CHRE_GNSS_CAPABILITIES_LOCATION UINT32_C(1 << 0) + +//! GNSS raw measurements are supported via +//! chreGnssMeasurementSessionStartAsync() +#define CHRE_GNSS_CAPABILITIES_MEASUREMENTS UINT32_C(1 << 1) + +//! Location fixes supplied from chreGnssConfigurePassiveLocationListener() +//! are tapped in at the GNSS engine level, so they include additional fixes +//! such as those requested by the AP, and not just those requested by other +//! nanoapps within CHRE (which is the case when this flag is not set) +#define CHRE_GNSS_CAPABILITIES_GNSS_ENGINE_BASED_PASSIVE_LISTENER \ + UINT32_C(1 << 2) + +/** @} */ + +/** + * The current version of struct chreGnssDataEvent associated with this API + */ +#define CHRE_GNSS_DATA_EVENT_VERSION UINT8_C(0) + +/** + * The maximum time the CHRE implementation is allowed to elapse before sending + * an event with the result of an asynchronous request, unless specified + * otherwise + */ +#define CHRE_GNSS_ASYNC_RESULT_TIMEOUT_NS (5 * CHRE_NSEC_PER_SEC) + +/** + * Produce an event ID in the block of IDs reserved for GNSS + * @param offset Index into GNSS event ID block; valid range [0,15] + */ +#define CHRE_GNSS_EVENT_ID(offset) (CHRE_EVENT_GNSS_FIRST_EVENT + (offset)) + +/** + * nanoappHandleEvent argument: struct chreAsyncResult + * + * Communicates the asynchronous result of a request to the GNSS API, such as + * starting a location session via chreGnssLocationSessionStartAsync(). The + * requestType field in chreAsyncResult is set to a value from enum + * chreGnssRequestType. + */ +#define CHRE_EVENT_GNSS_ASYNC_RESULT CHRE_GNSS_EVENT_ID(0) + +/** + * nanoappHandleEvent argument: struct chreGnssLocationEvent + * + * Represents a location fix provided by the GNSS subsystem. + */ +#define CHRE_EVENT_GNSS_LOCATION CHRE_GNSS_EVENT_ID(1) + +/** + * nanoappHandleEvent argument: struct chreGnssDataEvent + * + * Represents a set of GNSS measurements with associated clock data. + */ +#define CHRE_EVENT_GNSS_DATA CHRE_GNSS_EVENT_ID(2) + +// NOTE: Do not add new events with ID > 15; only values 0-15 are reserved +// (see chre/event.h) + +// Flags indicating the Accumulated Delta Range's states +// (ref: GnssAccumulatedDeltaRangeState) +#define CHRE_GNSS_ADR_STATE_UNKNOWN UINT16_C(0) +#define CHRE_GNSS_ADR_STATE_VALID UINT16_C(1 << 0) +#define CHRE_GNSS_ADR_STATE_RESET UINT16_C(1 << 1) +#define CHRE_GNSS_ADR_STATE_CYCLE_SLIP UINT16_C(1 << 2) + +// Flags to indicate what fields in chreGnssClock are valid (ref: GnssClockFlags) +#define CHRE_GNSS_CLOCK_HAS_LEAP_SECOND UINT16_C(1 << 0) +#define CHRE_GNSS_CLOCK_HAS_TIME_UNCERTAINTY UINT16_C(1 << 1) +#define CHRE_GNSS_CLOCK_HAS_FULL_BIAS UINT16_C(1 << 2) +#define CHRE_GNSS_CLOCK_HAS_BIAS UINT16_C(1 << 3) +#define CHRE_GNSS_CLOCK_HAS_BIAS_UNCERTAINTY UINT16_C(1 << 4) +#define CHRE_GNSS_CLOCK_HAS_DRIFT UINT16_C(1 << 5) +#define CHRE_GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY UINT16_C(1 << 6) + +// Flags to indicate which values are valid in a GpsLocation +// (ref: GpsLocationFlags) +#define CHRE_GPS_LOCATION_HAS_LAT_LONG UINT16_C(1 << 0) +#define CHRE_GPS_LOCATION_HAS_ALTITUDE UINT16_C(1 << 1) +#define CHRE_GPS_LOCATION_HAS_SPEED UINT16_C(1 << 2) +#define CHRE_GPS_LOCATION_HAS_BEARING UINT16_C(1 << 3) +#define CHRE_GPS_LOCATION_HAS_ACCURACY UINT16_C(1 << 4) + +//! @since v1.3 +#define CHRE_GPS_LOCATION_HAS_ALTITUDE_ACCURACY UINT16_C(1 << 5) +//! @since v1.3 +#define CHRE_GPS_LOCATION_HAS_SPEED_ACCURACY UINT16_C(1 << 6) +//! @since v1.3 +#define CHRE_GPS_LOCATION_HAS_BEARING_ACCURACY UINT16_C(1 << 7) + +/** + * The maximum number of instances of struct chreGnssMeasurement that may be + * included in a single struct chreGnssDataEvent. + * + * The value of this struct was increased from 64 to 128 in CHRE v1.5. For + * nanoapps targeting CHRE v1.4 or lower, the measurement_count will be capped + * at 64. + */ +#define CHRE_GNSS_MAX_MEASUREMENT UINT8_C(128) +#define CHRE_GNSS_MAX_MEASUREMENT_PRE_1_5 UINT8_C(64) + +// Flags indicating the GNSS measurement state (ref: GnssMeasurementState) +#define CHRE_GNSS_MEASUREMENT_STATE_UNKNOWN UINT16_C(0) +#define CHRE_GNSS_MEASUREMENT_STATE_CODE_LOCK UINT16_C(1 << 0) +#define CHRE_GNSS_MEASUREMENT_STATE_BIT_SYNC UINT16_C(1 << 1) +#define CHRE_GNSS_MEASUREMENT_STATE_SUBFRAME_SYNC UINT16_C(1 << 2) +#define CHRE_GNSS_MEASUREMENT_STATE_TOW_DECODED UINT16_C(1 << 3) +#define CHRE_GNSS_MEASUREMENT_STATE_MSEC_AMBIGUOUS UINT16_C(1 << 4) +#define CHRE_GNSS_MEASUREMENT_STATE_SYMBOL_SYNC UINT16_C(1 << 5) +#define CHRE_GNSS_MEASUREMENT_STATE_GLO_STRING_SYNC UINT16_C(1 << 6) +#define CHRE_GNSS_MEASUREMENT_STATE_GLO_TOD_DECODED UINT16_C(1 << 7) +#define CHRE_GNSS_MEASUREMENT_STATE_BDS_D2_BIT_SYNC UINT16_C(1 << 8) +#define CHRE_GNSS_MEASUREMENT_STATE_BDS_D2_SUBFRAME_SYNC UINT16_C(1 << 9) +#define CHRE_GNSS_MEASUREMENT_STATE_GAL_E1BC_CODE_LOCK UINT16_C(1 << 10) +#define CHRE_GNSS_MEASUREMENT_STATE_GAL_E1C_2ND_CODE_LOCK UINT16_C(1 << 11) +#define CHRE_GNSS_MEASUREMENT_STATE_GAL_E1B_PAGE_SYNC UINT16_C(1 << 12) +#define CHRE_GNSS_MEASUREMENT_STATE_SBAS_SYNC UINT16_C(1 << 13) + +#define CHRE_GNSS_MEASUREMENT_CARRIER_FREQUENCY_UNKNOWN 0.f + +/** + * Indicates a type of request made in this API. Used to populate the resultType + * field of struct chreAsyncResult sent with CHRE_EVENT_GNSS_ASYNC_RESULT. + */ +enum chreGnssRequestType { + CHRE_GNSS_REQUEST_TYPE_LOCATION_SESSION_START = 1, + CHRE_GNSS_REQUEST_TYPE_LOCATION_SESSION_STOP = 2, + CHRE_GNSS_REQUEST_TYPE_MEASUREMENT_SESSION_START = 3, + CHRE_GNSS_REQUEST_TYPE_MEASUREMENT_SESSION_STOP = 4, +}; + +/** + * Constellation type associated with an SV + */ +enum chreGnssConstellationType { + CHRE_GNSS_CONSTELLATION_UNKNOWN = 0, + CHRE_GNSS_CONSTELLATION_GPS = 1, + CHRE_GNSS_CONSTELLATION_SBAS = 2, + CHRE_GNSS_CONSTELLATION_GLONASS = 3, + CHRE_GNSS_CONSTELLATION_QZSS = 4, + CHRE_GNSS_CONSTELLATION_BEIDOU = 5, + CHRE_GNSS_CONSTELLATION_GALILEO = 6, +}; + +/** + * Enumeration of available values for the chreGnssMeasurement multipath indicator + */ +enum chreGnssMultipathIndicator { + //! The indicator is not available or unknown + CHRE_GNSS_MULTIPATH_INDICATOR_UNKNOWN = 0, + //! The measurement is indicated to be affected by multipath + CHRE_GNSS_MULTIPATH_INDICATOR_PRESENT = 1, + //! The measurement is indicated to be not affected by multipath + CHRE_GNSS_MULTIPATH_INDICATOR_NOT_PRESENT = 2, +}; + +/** + * Represents an estimate of the GNSS clock time (see the Android GPS HAL for + * more detailed information) + */ +struct chreGnssClock { + //! The GNSS receiver hardware clock value in nanoseconds, including + //! uncertainty + int64_t time_ns; + + //! The difference between hardware clock inside GNSS receiver and the + //! estimated GNSS time in nanoseconds; contains bias uncertainty + int64_t full_bias_ns; + + //! Sub-nanosecond bias, adds to full_bias_ns + float bias_ns; + + //! The clock's drift in nanoseconds per second + float drift_nsps; + + //! 1-sigma uncertainty associated with the clock's bias in nanoseconds + float bias_uncertainty_ns; + + //! 1-sigma uncertainty associated with the clock's drift in nanoseconds + //! per second + float drift_uncertainty_nsps; + + //! While this number stays the same, timeNs should flow continuously + uint32_t hw_clock_discontinuity_count; + + //! A set of flags indicating the validity of the fields in this data + //! structure (see GNSS_CLOCK_HAS_*) + uint16_t flags; + + //! Reserved for future use; set to 0 + uint8_t reserved[2]; +}; + +/** + * Represents a GNSS measurement; contains raw and computed information (see the + * Android GPS HAL for more detailed information) + */ +struct chreGnssMeasurement { + //! Hardware time offset from time_ns for this measurement, in nanoseconds + int64_t time_offset_ns; + + //! Accumulated delta range since the last channel reset in micro-meters + int64_t accumulated_delta_range_um; + + //! Received GNSS satellite time at the time of measurement, in nanoseconds + int64_t received_sv_time_in_ns; + + //! 1-sigma uncertainty of received GNSS satellite time, in nanoseconds + int64_t received_sv_time_uncertainty_in_ns; + + //! Pseudorange rate at the timestamp in meters per second (uncorrected) + float pseudorange_rate_mps; + + //! 1-sigma uncertainty of pseudorange rate in meters per second + float pseudorange_rate_uncertainty_mps; + + //! 1-sigma uncertainty of the accumulated delta range in meters + float accumulated_delta_range_uncertainty_m; + + //! Carrier-to-noise density in dB-Hz, in the range of [0, 63] + float c_n0_dbhz; + + //! Signal to noise ratio (dB), power above observed noise at correlators + float snr_db; + + //! Satellite sync state flags (GNSS_MEASUREMENT_STATE_*) - sets modulus for + //! received_sv_time_in_ns + uint16_t state; + + //! Set of ADR state flags (GNSS_ADR_STATE_*) + uint16_t accumulated_delta_range_state; + + //! Satellite vehicle ID number + int16_t svid; + + //! Constellation of the given satellite vehicle + //! @see #chreGnssConstellationType + uint8_t constellation; + + //! @see #chreGnssMultipathIndicator + uint8_t multipath_indicator; + + //! Carrier frequency of the signal tracked in Hz. + //! For example, it can be the GPS central frequency for L1 = 1575.45 MHz, + //! or L2 = 1227.60 MHz, L5 = 1176.45 MHz, various GLO channels, etc. + //! + //! Set to CHRE_GNSS_MEASUREMENT_CARRIER_FREQUENCY_UNKNOWN if not reported. + //! + //! For an L1, L5 receiver tracking a satellite on L1 and L5 at the same + //! time, two chreGnssMeasurement structs must be reported for this same + //! satellite, in one of the measurement structs, all the values related to + //! L1 must be filled, and in the other all of the values related to L5 + //! must be filled. + //! @since v1.4 + float carrier_frequency_hz; +}; + +/** + * Data structure sent with events associated with CHRE_EVENT_GNSS_DATA, enabled + * via chreGnssMeasurementSessionStartAsync() + */ +struct chreGnssDataEvent { + //! Indicates the version of the structure, for compatibility purposes. + //! Clients do not normally need to worry about this field; the CHRE + //! implementation guarantees that it only sends the client the structure + //! version it expects. + uint8_t version; + + //! Number of chreGnssMeasurement entries included in this event. Must be in + //! the range [0, CHRE_GNSS_MAX_MEASUREMENT] + uint8_t measurement_count; + + //! Reserved for future use; set to 0 + uint8_t reserved[6]; + + struct chreGnssClock clock; + + //! Pointer to an array containing measurement_count measurements + const struct chreGnssMeasurement *measurements; +}; + +/** + * Data structure sent with events of type CHRE_EVENT_GNSS_LOCATION, enabled via + * chreGnssLocationSessionStartAsync(). This is modeled after GpsLocation in the + * GPS HAL, but does not use the double data type. + */ +struct chreGnssLocationEvent { + //! UTC timestamp for location fix in milliseconds since January 1, 1970 + uint64_t timestamp; + + //! Fixed point latitude, degrees times 10^7 (roughly centimeter resolution) + int32_t latitude_deg_e7; + + //! Fixed point longitude, degrees times 10^7 (roughly centimeter + //! resolution) + int32_t longitude_deg_e7; + + //! Altitude in meters above the WGS 84 reference ellipsoid + float altitude; + + //! Horizontal speed in meters per second + float speed; + + //! Clockwise angle between north and current heading, in degrees; range + //! [0, 360) + float bearing; + + //! Expected horizontal accuracy in meters such that a circle with a radius + //! of length 'accuracy' from the latitude and longitude has a 68% + //! probability of including the true location. + float accuracy; + + //! A set of flags indicating which fields in this structure are valid. + //! If any fields are not available, the flag must not be set and the field + //! must be initialized to 0. + //! @see #GpsLocationFlags + uint16_t flags; + + //! Reserved for future use; set to 0 + //! @since v1.3 + uint8_t reserved[2]; + + //! Expected vertical accuracy in meters such that a range of + //! 2 * altitude_accuracy centered around altitude has a 68% probability of + //! including the true altitude. + //! @since v1.3 + float altitude_accuracy; + + //! Expected speed accuracy in meters per second such that a range of + //! 2 * speed_accuracy centered around speed has a 68% probability of + //! including the true speed. + //! @since v1.3 + float speed_accuracy; + + //! Expected bearing accuracy in degrees such that a range of + //! 2 * bearing_accuracy centered around bearing has a 68% probability of + //! including the true bearing. + //! @since v1.3 + float bearing_accuracy; +}; + + +/** + * Retrieves a set of flags indicating the GNSS features supported by the + * current CHRE implementation. The value returned by this function must be + * consistent for the entire duration of the Nanoapp's execution. + * + * The client must allow for more flags to be set in this response than it knows + * about, for example if the implementation supports a newer version of the API + * than the client was compiled against. + * + * @return A bitmask with zero or more CHRE_GNSS_CAPABILITIES_* flags set + * + * @since v1.1 + */ +uint32_t chreGnssGetCapabilities(void); + +/** + * Nanoapps must define CHRE_NANOAPP_USES_GNSS somewhere in their build + * system (e.g. Makefile) if the nanoapp needs to use the following GNSS APIs. + * In addition to allowing access to these APIs, defining this macro will also + * ensure CHRE enforces that all host clients this nanoapp talks to have the + * required Android permissions needed to listen to GNSS data by adding metadata + * to the nanoapp. + */ +#if defined(CHRE_NANOAPP_USES_GNSS) || !defined(CHRE_IS_NANOAPP_BUILD) + +/** + * Initiates a GNSS positioning session, or changes the requested interval of an + * existing session. If starting or modifying the session was successful, then + * the GNSS engine will work on determining the device's position. + * + * This result of this request is delivered asynchronously via an event of type + * CHRE_EVENT_GNSS_ASYNC_RESULT. Refer to the note in {@link #chreAsyncResult} + * for more details. If the "Location" setting is disabled at the Android level, + * the CHRE implementation is expected to return a result with + * CHRE_ERROR_FUNCTION_DISABLED. + * + * If chreGnssGetCapabilities() returns a value that does not have the + * CHRE_GNSS_CAPABILITIES_LOCATION flag set, then this method will return false. + * + * @param minIntervalMs The desired minimum interval between location fixes + * delivered to the client via CHRE_EVENT_GNSS_LOCATION, in milliseconds. + * The requesting client must allow for fixes to be delivered at shorter + * or longer interval than requested. For example, adverse RF conditions + * may result in fixes arriving at a longer interval, etc. + * @param minTimeToNextFixMs The desired minimum time to the next location fix. + * If this is 0, the GNSS engine should start working on the next fix + * immediately. If greater than 0, the GNSS engine should not spend + * measurable power to produce a location fix until this amount of time + * has elapsed. + * @param cookie An opaque value that will be included in the chreAsyncResult + * sent in relation to this request. + * + * @return true if the request was accepted for processing, false otherwise + * + * @since v1.1 + * @note Requires GNSS permission + */ +bool chreGnssLocationSessionStartAsync(uint32_t minIntervalMs, + uint32_t minTimeToNextFixMs, + const void *cookie); + +/** + * Terminates an existing GNSS positioning session. If no positioning session + * is active at the time of this request, it is treated as if an active session + * was successfully ended. + * + * This result of this request is delivered asynchronously via an event of type + * CHRE_EVENT_GNSS_ASYNC_RESULT. Refer to the note in {@link #chreAsyncResult} + * for more details. + * + * After CHRE_EVENT_GNSS_ASYNC_RESULT is delivered to the client, no more + * CHRE_EVENT_GNSS_LOCATION events will be delievered until a new location + * session is started. + * + * If chreGnssGetCapabilities() returns a value that does not have the + * CHRE_GNSS_CAPABILITIES_LOCATION flag set, then this method will return false. + * + * @param cookie An opaque value that will be included in the chreAsyncResult + * sent in relation to this request. + * + * @return true if the request was accepted for processing, false otherwise + * + * @since v1.1 + * @note Requires GNSS permission + */ +bool chreGnssLocationSessionStopAsync(const void *cookie); + +/** + * Initiates a request to receive raw GNSS measurements. A GNSS measurement + * session can exist independently of location sessions. In other words, a + * Nanoapp is able to receive measurements at its requested interval both with + * and without an active location session. + * + * This result of this request is delivered asynchronously via an event of type + * CHRE_EVENT_GNSS_ASYNC_RESULT. Refer to the note in {@link #chreAsyncResult} + * for more details. If the "Location" setting is disabled at the Android level, + * the CHRE implementation is expected to return a result with + * CHRE_ERROR_FUNCTION_DISABLED. + * + * If chreGnssGetCapabilities() returns a value that does not have the + * CHRE_GNSS_CAPABILITIES_MEASUREMENTS flag set, then this method will return + * false. + * + * @param minIntervalMs The desired minimum interval between measurement reports + * delivered via CHRE_EVENT_GNSS_DATA. When requested at 1000ms or + * faster, and GNSS measurements are tracked, device should report + * measurements as fast as requested, and shall report no slower than + * once every 1000ms, on average. + * @param cookie An opaque value that will be included in the chreAsyncResult + * sent in relation to this request. + * + * @return true if the request was accepted for processing, false otherwise + * + * @since v1.1 + * @note Requires GNSS permission + */ +bool chreGnssMeasurementSessionStartAsync(uint32_t minIntervalMs, + const void *cookie); + +/** + * Terminates an existing raw GNSS measurement session. If no measurement + * session is active at the time of this request, it is treated as if an active + * session was successfully ended. + * + * This result of this request is delivered asynchronously via an event of type + * CHRE_EVENT_GNSS_ASYNC_RESULT. Refer to the note in {@link #chreAsyncResult} + * for more details. + * + * If chreGnssGetCapabilities() returns a value that does not have the + * CHRE_GNSS_CAPABILITIES_MEASUREMENTS flag set, then this method will return + * false. + * + * @param cookie An opaque value that will be included in the chreAsyncResult + * sent in relation to this request. + * + * @return true if the request was accepted for processing, false otherwise + * + * @since v1.1 + * @note Requires GNSS permission + */ +bool chreGnssMeasurementSessionStopAsync(const void *cookie); + +/** + * Controls whether this nanoapp will passively receive GNSS-based location + * fixes produced as a result of location sessions initiated by other entities. + * This function allows a nanoapp to opportunistically receive location fixes + * via CHRE_EVENT_GNSS_LOCATION events without imposing additional power cost, + * though with no guarantees as to when or how often those events will arrive. + * There will be no duplication of events if a passive location listener and + * location session are enabled in parallel. + * + * Enabling passive location listening is not required to receive events for an + * active location session started via chreGnssLocationSessionStartAsync(). This + * setting is independent of the active location session, so modifying one does + * not have an effect on the other. + * + * If chreGnssGetCapabilities() returns a value that does not have the + * CHRE_GNSS_CAPABILITIES_LOCATION flag set or the value returned by + * chreGetApiVersion() is less than CHRE_API_VERSION_1_2, then this method will + * return false. + * + * If chreGnssGetCapabilities() includes + * CHRE_GNSS_CAPABILITIES_GNSS_ENGINE_BASED_PASSIVE_LISTENER, the passive + * registration is recorded at the GNSS engine level, so events include fixes + * requested by the applications processor and potentially other non-CHRE + * clients. If this flag is not set, then only fixes requested by other nanoapps + * within CHRE are provided. + * + * @param enable true to receive opportunistic location fixes, false to disable + * + * @return true if the configuration was processed successfully, false on error + * or if this feature is not supported + * + * @since v1.2 + * @note Requires GNSS permission + */ +bool chreGnssConfigurePassiveLocationListener(bool enable); + +#else /* defined(CHRE_NANOAPP_USES_GNSS) || !defined(CHRE_IS_NANOAPP_BUILD) */ +#define CHRE_GNSS_PERM_ERROR_STRING \ + "CHRE_NANOAPP_USES_GNSS must be defined when building this nanoapp in " \ + "order to refer to " +#define chreGnssLocationSessionStartAsync(...) \ + CHRE_BUILD_ERROR(CHRE_GNSS_PERM_ERROR_STRING \ + "chreGnssLocationSessionStartAsync") +#define chreGnssLocationSessionStopAsync(...) \ + CHRE_BUILD_ERROR(CHRE_GNSS_PERM_ERROR_STRING \ + "chreGnssLocationSessionStopAsync") +#define chreGnssMeasurementSessionStartAsync(...) \ + CHRE_BUILD_ERROR(CHRE_GNSS_PERM_ERROR_STRING \ + "chreGnssMeasurementSessionStartAsync") +#define chreGnssMeasurementSessionStopAsync(...) \ + CHRE_BUILD_ERROR(CHRE_GNSS_PERM_ERROR_STRING \ + "chreGnssMeasurementSessionStopAsync") +#define chreGnssConfigurePassiveLocationListener(...) \ + CHRE_BUILD_ERROR(CHRE_GNSS_PERM_ERROR_STRING \ + "chreGnssConfigurePassiveLocationListener") +#endif /* defined(CHRE_NANOAPP_USES_GNSS) || !defined(CHRE_IS_NANOAPP_BUILD) */ + +#ifdef __cplusplus +} +#endif + +#endif /* _CHRE_GNSS_H_ */
diff --git a/chre_api/legacy/v1_10/chre/nanoapp.h b/chre_api/legacy/v1_10/chre/nanoapp.h new file mode 100644 index 0000000..3a1c362 --- /dev/null +++ b/chre_api/legacy/v1_10/chre/nanoapp.h
@@ -0,0 +1,96 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// IWYU pragma: private, include "chre_api/chre.h" +// IWYU pragma: friend chre/.*\.h + +#ifndef _CHRE_NANOAPP_H_ +#define _CHRE_NANOAPP_H_ + +/** + * @file + * Methods in the Context Hub Runtime Environment which must be implemented + * by the nanoapp. + */ + +#include <stdbool.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Method invoked by the CHRE when loading the nanoapp. + * + * Every CHRE method is legal to call from this method. + * + * @return 'true' if the nanoapp successfully started. 'false' if the nanoapp + * failed to properly initialize itself (for example, could not obtain + * sufficient memory from the heap). If this method returns 'false', the + * nanoapp will be unloaded by the CHRE (and nanoappEnd will + * _not_ be invoked in that case). + * @see nanoappEnd + */ +bool nanoappStart(void); + +/** + * Method invoked by the CHRE when there is an event for this nanoapp. + * + * Every CHRE method is legal to call from this method. + * + * @param senderInstanceId The Instance ID for the source of this event. + * Note that this may be CHRE_INSTANCE_ID, indicating that the event + * was generated by the CHRE. + * @param eventType The event type. This might be one of the CHRE_EVENT_* + * types defined in this API. But it might also be a user-defined event. + * @param eventData The associated data, if any, for this specific type of + * event. From the nanoapp's perspective, this eventData's lifetime ends + * when this method returns, and thus any data the nanoapp wishes to + * retain must be copied. Note that interpretation of event data is + * given by the event type, and for some events may not be a valid + * pointer. See documentation of the specific CHRE_EVENT_* types for how to + * interpret this data for those. Note that for user events, you will + * need to establish what this data means. + */ +void nanoappHandleEvent(uint32_t senderInstanceId, uint16_t eventType, + const void *eventData); + +/** + * Method invoked by the CHRE when unloading the nanoapp. + * + * It is not valid to attempt to send events or messages, or to invoke functions + * which will generate events to this app, within the nanoapp implementation of + * this function. That means it is illegal for the nanoapp invoke any of the + * following: + * + * - chreSendEvent() + * - chreSendMessageToHost() + * - chreSensorConfigure() + * - chreSensorConfigureModeOnly() + * - chreTimerSet() + * - etc. + * + * @see nanoappStart + */ +void nanoappEnd(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* _CHRE_NANOAPP_H_ */
diff --git a/chre_api/legacy/v1_10/chre/re.h b/chre_api/legacy/v1_10/chre/re.h new file mode 100644 index 0000000..b523a41 --- /dev/null +++ b/chre_api/legacy/v1_10/chre/re.h
@@ -0,0 +1,492 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// IWYU pragma: private, include "chre_api/chre.h" +// IWYU pragma: friend chre/.*\.h + +#ifndef _CHRE_RE_H_ +#define _CHRE_RE_H_ + +/** + * @file + * Some of the core Runtime Environment utilities of the Context Hub + * Runtime Environment. + * + * This includes functions for memory allocation, logging, and timers. + */ + +#include <stdarg.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> + +#include <chre/toolchain.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The instance ID for the CHRE. + * + * This ID is used to identify events generated by the CHRE (as + * opposed to events generated by another nanoapp). + */ +#define CHRE_INSTANCE_ID UINT32_C(0) + +/** + * A timer ID representing an invalid timer. + * + * This valid is returned by chreTimerSet() if a timer cannot be + * started. + */ +#define CHRE_TIMER_INVALID UINT32_C(-1) + + +/** + * The maximum size, in characters including null terminator, guaranteed for + * logging debug data with one call of chreDebugDumpLog() without getting + * truncated. + * + * @see chreDebugDumpLog + * @since v1.4 + */ +#define CHRE_DEBUG_DUMP_MINIMUM_MAX_SIZE 1000 + +/** + * The set of flags that may be returned by chreGetCapabilities() + * @defgroup CHRE_CAPABILITIES + * @{ + */ + +//! None of the optional capabilities are supported +#define CHRE_CAPABILITIES_NONE UINT32_C(0) + +//! Support for reliable messages. +//! @see chreSendReliableMessageAsync() +#define CHRE_CAPABILITIES_RELIABLE_MESSAGES UINT32_C(1 << 0) + +/** @} */ + +/** + * Logging levels used to indicate severity level of logging messages. + * + * CHRE_LOG_ERROR: Something fatal has happened, i.e. something that will have + * user-visible consequences and won't be recoverable without explicitly + * deleting some data, uninstalling applications, wiping the data + * partitions or reflashing the entire phone (or worse). + * CHRE_LOG_WARN: Something that will have user-visible consequences but is + * likely to be recoverable without data loss by performing some explicit + * action, ranging from waiting or restarting an app all the way to + * re-downloading a new version of an application or rebooting the device. + * CHRE_LOG_INFO: Something interesting to most people happened, i.e. when a + * situation is detected that is likely to have widespread impact, though + * isn't necessarily an error. + * CHRE_LOG_DEBUG: Used to further note what is happening on the device that + * could be relevant to investigate and debug unexpected behaviors. You + * should log only what is needed to gather enough information about what + * is going on about your component. + * + * There is currently no API to turn on/off logging by level, but we anticipate + * adding such in future releases. + * + * @see chreLog + */ +enum chreLogLevel { + CHRE_LOG_ERROR, + CHRE_LOG_WARN, + CHRE_LOG_INFO, + CHRE_LOG_DEBUG +}; + +/** + * Retrieves a set of flags indicating the CHRE optional features supported by + * the current implementation. The value returned by this function must be + * consistent for the entire duration of the nanoapp's execution. + * + * The client must allow for more flags to be set in this response than it knows + * about, for example if the implementation supports a newer version of the API + * than the client was compiled against. + * + * @return A bitmask with zero or more CHRE_CAPABILITIES_* flags set. + * + * @since v1.10 + */ +uint32_t chreGetCapabilities(void); + +/** + * Returns the maximum size in bytes of a message sent to the host. + * This function will always return a value greater than or equal to + * CHRE_MESSAGE_TO_HOST_MAX_SIZE. If the capability + * CHRE_CAPABILITIES_RELIABLE_MESSAGES is enabled, this function will + * return a value greater than or equal to 32000. + * + * On v1.9 or earlier platforms, this will always return CHRE_MESSAGE_TO_HOST_MAX_SIZE. + * + * @return The maximum message size in bytes. + * + * @since v1.10 + */ +uint32_t chreGetMessageToHostMaxSize(void); + +/** + * Get the application ID. + * + * The application ID is set by the loader of the nanoapp. This is not + * assured to be unique among all nanoapps running in the system. + * + * @return The application ID. + */ +uint64_t chreGetAppId(void); + +/** + * Get the instance ID. + * + * The instance ID is the CHRE handle to this nanoapp. This is assured + * to be unique among all nanoapps running in the system, and to be + * different from the CHRE_INSTANCE_ID. This is the ID used to communicate + * between nanoapps. + * + * @return The instance ID + */ +uint32_t chreGetInstanceId(void); + +/** + * A method for logging information about the system. + * + * The chreLog logging activity alone must not cause host wake-ups. For + * example, logs could be buffered in internal memory when the host is asleep, + * and delivered when appropriate (e.g. the host wakes up). If done this way, + * the internal buffer is recommended to be large enough (at least a few KB), so + * that multiple messages can be buffered. When these logs are sent to the host, + * they are strongly recommended to be made visible under the tag 'CHRE' in + * logcat - a future version of the CHRE API may make this a hard requirement. + * + * A log entry can have a variety of levels (@see LogLevel). This function + * allows a variable number of arguments, in a printf-style format. + * + * A nanoapp needs to be able to rely upon consistent printf format + * recognition across any platform, and thus we establish formats which + * are required to be handled by every CHRE implementation. Some of the + * integral formats may seem obscure, but this API heavily uses types like + * uint32_t and uint16_t. The platform independent macros for those printf + * formats, like PRId32 or PRIx16, end up using some of these "obscure" + * formats on some platforms, and thus are required. + * + * For the initial N release, our emphasis is on correctly getting information + * into the log, and minimizing the requirements for CHRE implementations + * beyond that. We're not as concerned about how the information is visually + * displayed. As a result, there are a number of format sub-specifiers which + * are "OPTIONAL" for the N implementation. "OPTIONAL" in this context means + * that a CHRE implementation is allowed to essentially ignore the specifier, + * but it must understand the specifier enough in order to properly skip it. + * + * For a nanoapp author, an OPTIONAL format means you might not get exactly + * what you want on every CHRE implementation, but you will always get + * something valid. + * + * To be clearer, here's an example with the OPTIONAL 0-padding for integers + * for different hypothetical CHRE implementations. + * Compliant, chose to implement OPTIONAL format: + * chreLog(level, "%04x", 20) ==> "0014" + * Compliant, chose not to implement OPTIONAL format: + * chreLog(level, "%04x", 20) ==> "14" + * Non-compliant, discarded format because the '0' was assumed to be incorrect: + * chreLog(level, "%04x", 20) ==> "" + * + * Note that some of the OPTIONAL specifiers will probably become + * required in future APIs. + * + * We also have NOT_SUPPORTED specifiers. Nanoapp authors should not use any + * NOT_SUPPORTED specifiers, as unexpected things could happen on any given + * CHRE implementation. A CHRE implementation is allowed to support this + * (for example, when using shared code which already supports this), but + * nanoapp authors need to avoid these. + * + * Unless specifically noted as OPTIONAL or NOT_SUPPORTED, format + * (sub-)specifiers listed below are required. + * + * While all CHRE implementations must support chreLog(), some platform + * implementations may support enhanced logging functionality only possible + * through a macro. This improved functionality is supported through + * platform-specific customization of the log macros provided in + * chre/util/nanoapp/log.h. All nanoapps are recommended to use these log + * macros where possible, as they will fall back to chreLog() as needed. + * + * OPTIONAL format sub-specifiers: + * - '-' (left-justify within the given field width) + * - '+' (precede the result with a '+' sign if it is positive) + * - ' ' (precede the result with a blank space if no sign is going to be + * output) + * - '#' (For 'o', 'x' or 'X', precede output with "0", "0x" or "0X", + * respectively. For floating point, unconditionally output a decimal + * point.) + * - '0' (left pad the number with zeroes instead of spaces when <width> + * needs padding) + * - <width> (A number representing the minimum number of characters to be + * output, left-padding with blank spaces if needed to meet the + * minimum) + * - '.'<precision> (A number which has different meaning depending on context.) + * - Integer context: Minimum number of digits to output, padding with + * leading zeros if needed to meet the minimum. + * - 'f' context: Number of digits to output after the decimal + * point (to the right of it). + * - 's' context: Maximum number of characters to output. + * + * Integral format specifiers: + * - 'd' (signed) + * - 'u' (unsigned) + * - 'o' (octal) + * - 'x' (hexadecimal, lower case) + * - 'X' (hexadecimal, upper case) + * + * Integral format sub-specifiers (as prefixes to an above integral format): + * - 'hh' (char) + * - 'h' (short) + * - 'l' (long) + * - 'll' (long long) + * - 'z' (size_t) + * - 't' (ptrdiff_t) + * + * Other format specifiers: + * - 'f' (floating point) + * - 'c' (character) + * - 's' (character string, terminated by '\0') + * - 'p' (pointer) + * - '%' (escaping the percent sign (i.e. "%%" becomes "%")) + * + * NOT_SUPPORTED specifiers: + * - 'n' (output nothing, but fill in a given pointer with the number + * of characters written so far) + * - '*' (indicates that the width/precision value comes from one of the + * arguments to the function) + * - 'e', 'E' (scientific notation output) + * - 'g', 'G' (Shortest floating point representation) + * + * @param level The severity level for this message. + * @param formatStr Either the entirety of the message, or a printf-style + * format string of the format documented above. + * @param ... A variable number of arguments necessary for the given + * 'formatStr' (there may be no additional arguments for some 'formatStr's). + */ +CHRE_PRINTF_ATTR(2, 3) +void chreLog(enum chreLogLevel level, const char *formatStr, ...); + +/** + * Get the system time. + * + * This returns a time in nanoseconds in reference to some arbitrary + * time in the past. This method is only useful for determining timing + * between events on the system, and is not useful for determining + * any sort of absolute time. + * + * This value must always increase (and must never roll over). This + * value has no meaning across CHRE reboots. + * + * @return The system time, in nanoseconds. + */ +uint64_t chreGetTime(void); + +/** + * Retrieves CHRE's current estimated offset between the local CHRE clock + * exposed in chreGetTime(), and the host-side clock exposed in the Android API + * SystemClock.elapsedRealtimeNanos(). This offset is formed as host time minus + * CHRE time, so that it can be added to the value returned by chreGetTime() to + * determine the current estimate of the host time. + * + * A call to this function must not require waking up the host and should return + * quickly. + * + * This function must always return a valid value from the earliest point that + * it can be called by a nanoapp. In other words, it is not valid to return + * some fixed/invalid value while waiting for the initial offset estimate to be + * determined - this initial offset must be ready before nanoapps are started. + * + * @return An estimate of the offset between CHRE's time returned in + * chreGetTime() and the time on the host given in the Android API + * SystemClock.elapsedRealtimeNanos(), accurate to within +/- 10 + * milliseconds, such that adding this offset to chreGetTime() produces the + * estimated current time on the host. This value may change over time to + * account for drift, etc., so multiple calls to this API may produce + * different results. + * + * @since v1.1 + */ +int64_t chreGetEstimatedHostTimeOffset(void); + +/** + * Convenience function to retrieve CHRE's estimate of the current time on the + * host, corresponding to the Android API SystemClock.elapsedRealtimeNanos(). + * + * @return An estimate of the current time on the host, accurate to within + * +/- 10 milliseconds. This estimate is *not* guaranteed to be + * monotonically increasing, and may move backwards as a result of receiving + * new information from the host. + * + * @since v1.1 + */ +static inline uint64_t chreGetEstimatedHostTime(void) { + int64_t offset = chreGetEstimatedHostTimeOffset(); + uint64_t time = chreGetTime(); + + // Just casting time to int64_t and adding the (potentially negative) offset + // should be OK under most conditions, but this way avoids issues if + // time >= 2^63, which is technically allowed since we don't specify a start + // value for chreGetTime(), though one would assume 0 is roughly boot time. + if (offset >= 0) { + time += (uint64_t) offset; + } else { + // Assuming chreGetEstimatedHostTimeOffset() is implemented properly, + // this will never underflow, because offset = hostTime - chreTime, + // and both times are monotonically increasing (e.g. when determining + // the offset, if hostTime is 0 and chreTime is 100 we'll have + // offset = -100, but chreGetTime() will always return >= 100 after that + // point). + time -= (uint64_t) (offset * -1); + } + + return time; +} + +/** + * Set a timer. + * + * When the timer fires, nanoappHandleEvent will be invoked with + * CHRE_EVENT_TIMER and with the given 'cookie'. + * + * A CHRE implementation is required to provide at least 32 + * timers. However, there's no assurance there will be any available + * for any given nanoapp (if it's loaded late, etc). + * + * @param duration Time, in nanoseconds, before the timer fires. + * @param cookie Argument that will be sent to nanoappHandleEvent upon the + * timer firing. This is allowed to be NULL and does not need to be + * a valid pointer (assuming the nanoappHandleEvent code is expecting such). + * @param oneShot If true, the timer will just fire once. If false, the + * timer will continue to refire every 'duration', until this timer is + * canceled (@see chreTimerCancel). + * + * @return The timer ID. If the system is unable to set a timer + * (no more available timers, etc.) then CHRE_TIMER_INVALID will + * be returned. + * + * @see nanoappHandleEvent + */ +uint32_t chreTimerSet(uint64_t duration, const void *cookie, bool oneShot); + +/** + * Cancel a timer. + * + * After this method returns, the CHRE assures there will be no more + * events sent from this timer, and any enqueued events from this timer + * will need to be evicted from the queue by the CHRE. + * + * @param timerId A timer ID obtained by this nanoapp via chreTimerSet(). + * @return true if the timer was cancelled, false otherwise. We may + * fail to cancel the timer if it's a one shot which (just) fired, + * or if the given timer ID is not owned by the calling app. + */ +bool chreTimerCancel(uint32_t timerId); + +/** + * Terminate this nanoapp. + * + * This takes effect immediately. + * + * The CHRE will no longer execute this nanoapp. The CHRE will not invoke + * nanoappEnd(), nor will it call any memory free callbacks in the nanoapp. + * + * The CHRE will unload/evict this nanoapp's code. + * + * @param abortCode A value indicating the reason for aborting. (Note that + * in this version of the API, there is no way for anyone to access this + * code, but future APIs may expose it.) + * @return Never. This method does not return, as the CHRE stops nanoapp + * execution immediately. + */ +void chreAbort(uint32_t abortCode) CHRE_NO_RETURN; + +/** + * Allocate a given number of bytes from the system heap. + * + * The nanoapp is required to free this memory via chreHeapFree() prior to + * the nanoapp ending. + * + * While the CHRE implementation is required to free up heap resources of + * a nanoapp when unloading it, future requirements and tests focused on + * nanoapps themselves may check for memory leaks, and will require nanoapps + * to properly manage their heap resources. + * + * @param bytes The number of bytes requested. + * @return A pointer to 'bytes' contiguous bytes of heap memory, or NULL + * if the allocation could not be performed. This pointer must be suitably + * aligned for any kind of variable. + * + * @see chreHeapFree. + */ +CHRE_MALLOC_ATTR +void *chreHeapAlloc(uint32_t bytes); + +/** + * Free a heap allocation. + * + * This allocation must be from a value returned from a chreHeapAlloc() call + * made by this nanoapp. In other words, it is illegal to free memory + * allocated by another nanoapp (or the CHRE). + * + * @param ptr 'ptr' is required to be a value returned from chreHeapAlloc(). + * Note that since chreHeapAlloc can return NULL, CHRE + * implementations must safely handle 'ptr' being NULL. + * + * @see chreHeapAlloc. + */ +void chreHeapFree(void *ptr); + +/** + * Logs the nanoapp's debug data into debug dumps. + * + * A debug dump is a string representation of information that can be used to + * diagnose and debug issues. While chreLog() is useful for logging events as + * they happen, the debug dump is a complementary function typically used to + * output a snapshot of a nanoapp's state, history, vital statistics, etc. The + * CHRE framework is required to pass this information to the debug method in + * the Context Hub HAL, where it can be captured in Android bugreports, etc. + * + * This function must only be called while handling CHRE_DEBUG_DUMP_EVENT, + * otherwise it will have no effect. A nanoapp can call this function multiple + * times while handling the event. If the resulting formatted string from a + * single call to this function is longer than CHRE_DEBUG_DUMP_MINIMUM_MAX_SIZE + * characters, it may get truncated. + * + * @param formatStr A printf-style format string of the format documented in + * chreLog(). + * @param ... A variable number of arguments necessary for the given 'formatStr' + * (there may be no additional arguments for some 'formatStr's). + * + * @see chreConfigureDebugDumpEvent + * @see chreLog + * + * @since v1.4 + */ +CHRE_PRINTF_ATTR(1, 2) +void chreDebugDumpLog(const char *formatStr, ...); + +#ifdef __cplusplus +} +#endif + +#endif /* _CHRE_RE_H_ */ +
diff --git a/chre_api/legacy/v1_10/chre/sensor.h b/chre_api/legacy/v1_10/chre/sensor.h new file mode 100644 index 0000000..551803e --- /dev/null +++ b/chre_api/legacy/v1_10/chre/sensor.h
@@ -0,0 +1,1132 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// IWYU pragma: private, include "chre_api/chre.h" +// IWYU pragma: friend chre/.*\.h + +#ifndef _CHRE_SENSOR_H_ +#define _CHRE_SENSOR_H_ + +/** + * @file + * API dealing with sensor interaction in the Context Hub Runtime + * Environment. + * + * This includes the definition of our sensor types and the ability to + * configure them for receiving events. + */ + +#include <stdbool.h> +#include <stdint.h> + +#include <chre/common.h> +#include <chre/event.h> +#include <chre/sensor_types.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Base value for all of the data events for sensors. + * + * The value for a data event FOO is + * CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_FOO + * + * This allows for easy mapping, and also explains why there are gaps + * in our values since we don't have all possible sensor types assigned. + */ +#define CHRE_EVENT_SENSOR_DATA_EVENT_BASE CHRE_EVENT_SENSOR_FIRST_EVENT + +/** + * nanoappHandleEvent argument: struct chreSensorThreeAxisData + * + * The data can be interpreted using the 'x', 'y', and 'z' fields within + * 'readings', or by the 3D array 'v' (v[0] == x; v[1] == y; v[2] == z). + * + * All values are in SI units (m/s^2) and measure the acceleration applied to + * the device. + */ +#define CHRE_EVENT_SENSOR_ACCELEROMETER_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_ACCELEROMETER) + +/** + * nanoappHandleEvent argument: struct chreSensorOccurrenceData + * + * Since this is a one-shot sensor, after this event is delivered to the + * nanoapp, the sensor automatically goes into DONE mode. Sensors of this + * type must be configured with a ONE_SHOT mode. + */ +#define CHRE_EVENT_SENSOR_INSTANT_MOTION_DETECT_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT) + +/** + * nanoappHandleEvent argument: struct chreSensorOccurrenceData + * + * Since this is a one-shot sensor, after this event is delivered to the + * nanoapp, the sensor automatically goes into DONE mode. Sensors of this + * type must be configured with a ONE_SHOT mode. + */ +#define CHRE_EVENT_SENSOR_STATIONARY_DETECT_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_STATIONARY_DETECT) + +/** + * nanoappHandleEvent argument: struct struct chreSensorOccurrenceData + * + * Since this is a one-shot sensor, after this event is delivered to the + * nanoapp, the sensor automatically goes into DONE mode. Sensors of this + * type must be configured with a ONE_SHOT mode. + */ +#define CHRE_EVENT_SENSOR_SIGNIFICANT_MOTION_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_SIGNIFICANT_MOTION) + +/** + * nanoappHandleEvent argument: struct chreSensorThreeAxisData + * + * The data can be interpreted using the 'x', 'y', and 'z' fields within + * 'readings', or by the 3D array 'v' (v[0] == x; v[1] == y; v[2] == z). + * + * All values are in radians/second and measure the rate of rotation + * around the X, Y and Z axis. + */ +#define CHRE_EVENT_SENSOR_GYROSCOPE_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_GYROSCOPE) + +/** + * nanoappHandleEvent argument: struct chreSensorThreeAxisData + * + * The data can be interpreted using the 'x', 'y', and 'z' fields within + * 'readings', or by the 3D array 'v' (v[0] == x; v[1] == y; v[2] == z). + * + * All values are in micro-Tesla (uT) and measure the geomagnetic + * field in the X, Y and Z axis. + */ +#define CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD) + +/** + * nanoappHandleEvent argument: struct chreSensorFloatData + * + * The data can be interpreted using the 'pressure' field within 'readings'. + * This value is in hectopascals (hPa). + */ +#define CHRE_EVENT_SENSOR_PRESSURE_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_PRESSURE) + +/** + * nanoappHandleEvent argument: struct chreSensorFloatData + * + * The data can be interpreted using the 'light' field within 'readings'. + * This value is in SI lux units. + */ +#define CHRE_EVENT_SENSOR_LIGHT_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_LIGHT) + +/** + * nanoappHandleEvent argument: struct chreSensorByteData + * + * The data is interpreted from the following fields in 'readings': + * o 'isNear': If set to 1, we are nearby (on the order of centimeters); + * if set to 0, we are far. The meaning of near/far in this field must be + * consistent with the Android definition. + * o 'invalid': If set to 1, this is not a valid reading of this data. + * As of CHRE API v1.2, this field is deprecated and must always be set to + * 0. If an invalid reading is generated by the sensor hardware, it must + * be dropped and not delivered to any nanoapp. + * + * In prior versions of the CHRE API, there can be an invalid event generated + * upon configuring this sensor. Thus, the 'invalid' field must be checked on + * the first event before interpreting 'isNear'. + */ +#define CHRE_EVENT_SENSOR_PROXIMITY_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_PROXIMITY) + +/** + * nanoappHandleEvent argument: struct chreSensorOccurrenceData + * + * This data is generated every time a step is taken by the user. + * + * This is backed by the same algorithm that feeds Android's + * SENSOR_TYPE_STEP_DETECTOR, and therefore sacrifices some accuracy to target + * an update latency of under 2 seconds. + * + * @since v1.3 + */ +#define CHRE_EVENT_SENSOR_STEP_DETECT_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_STEP_DETECT) + +/** + * nanoappHandleEvent argument: struct chreSensorUint64Data + * + * The value of the data is the cumulative number of steps taken by the user + * since the last reboot while the sensor is active. This data is generated + * every time a step is taken by the user. + * + * This is backed by the same algorithm that feeds Android's + * SENSOR_TYPE_STEP_COUNTER, and therefore targets high accuracy with under + * 10 seconds of update latency. + * + * @since v1.5 + */ +#define CHRE_EVENT_SENSOR_STEP_COUNTER_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_STEP_COUNTER) + +/** + * nanoappHandleEvent argument: struct chreSensorFloatData + * + * The value of the data is the measured hinge angle between 0 and 360 degrees + * inclusive. + * + * This is backed by the same algorithm that feeds Android's + * SENSOR_TYPE_HINGE_ANGLE. + * + * @since v1.5 + */ +#define CHRE_EVENT_SENSOR_HINGE_ANGLE_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_HINGE_ANGLE) + +/** + * nanoappHandleEvent argument: struct chreSensorThreeAxisData + * + * The data can be interpreted using the 'x', 'y', and 'z' fields within + * 'readings', or by the 3D array 'v' (v[0] == x; v[1] == y; v[2] == z). + * + * All values are in SI units (m/s^2) and measure the acceleration applied to + * the device. + */ +#define CHRE_EVENT_SENSOR_UNCALIBRATED_ACCELEROMETER_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_UNCALIBRATED_ACCELEROMETER) + +/** + * nanoappHandleEvent argument: struct chreSensorThreeAxisData + * + * The data can be interpreted using the 'x', 'y', and 'z' fields within + * 'readings', or by the 3D array 'v' (v[0] == x; v[1] == y; v[2] == z). + * + * All values are in radians/second and measure the rate of rotation + * around the X, Y and Z axis. + */ +#define CHRE_EVENT_SENSOR_UNCALIBRATED_GYROSCOPE_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_UNCALIBRATED_GYROSCOPE) + +/** + * nanoappHandleEvent argument: struct chreSensorThreeAxisData + * + * The data can be interpreted using the 'x', 'y', and 'z' fields within + * 'readings', or by the 3D array 'v' (v[0] == x; v[1] == y; v[2] == z). + * + * All values are in micro-Tesla (uT) and measure the geomagnetic + * field in the X, Y and Z axis. + */ +#define CHRE_EVENT_SENSOR_UNCALIBRATED_GEOMAGNETIC_FIELD_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_UNCALIBRATED_GEOMAGNETIC_FIELD) + +/** + * nanoappHandleEvent argument: struct chreSensorFloatData + * + * The data can be interpreted using the 'temperature' field within 'readings'. + * This value is in degrees Celsius. + */ +#define CHRE_EVENT_SENSOR_ACCELEROMETER_TEMPERATURE_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_ACCELEROMETER_TEMPERATURE) + +/** + * nanoappHandleEvent argument: struct chreSensorFloatData + * + * The data can be interpreted using the 'temperature' field within 'readings'. + * This value is in degrees Celsius. + */ +#define CHRE_EVENT_SENSOR_GYROSCOPE_TEMPERATURE_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_GYROSCOPE_TEMPERATURE) + +/** + * nanoappHandleEvent argument: struct chreSensorFloatData + * + * The data can be interpreted using the 'temperature' field within 'readings'. + * This value is in degrees Celsius. + */ +#define CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_TEMPERATURE_DATA \ + (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD_TEMPERATURE) + +/** + * First value for sensor events which are not data from the sensor. + * + * Unlike the data event values, these other event values don't have any + * mapping to sensor types. + */ +#define CHRE_EVENT_SENSOR_OTHER_EVENTS_BASE \ + (CHRE_EVENT_SENSOR_FIRST_EVENT + 0x0100) + +/** + * nanoappHandleEvent argument: struct chreSensorSamplingStatusEvent + * + * Indicates that the interval and/or the latency which this sensor is + * sampling at has changed. + */ +#define CHRE_EVENT_SENSOR_SAMPLING_CHANGE \ + (CHRE_EVENT_SENSOR_OTHER_EVENTS_BASE + 0) + +/** + * nanoappHandleEvent argument: struct chreSensorThreeAxisData + * + * The data can be interpreted using the 'x_bias', 'y_bias', and 'z_bias' + * field within 'readings', or by the 3D array 'bias' (bias[0] == x_bias; + * bias[1] == y_bias; bias[2] == z_bias). Bias is subtracted from uncalibrated + * data to generate calibrated data. + * + * All values are in radians/second and measure the rate of rotation + * around the X, Y and Z axis. + * + * If bias delivery is supported, this event is generated by default when + * chreSensorConfigure is called to enable for the sensor of type + * CHRE_SENSOR_TYPE_GYROSCOPE, or if bias delivery is explicitly enabled + * through chreSensorConfigureBiasEvents() for the sensor. + */ +#define CHRE_EVENT_SENSOR_GYROSCOPE_BIAS_INFO \ + (CHRE_EVENT_SENSOR_OTHER_EVENTS_BASE + 1) + +/** + * nanoappHandleEvent argument: struct chreSensorThreeAxisData + * + * The data can be interpreted using the 'x_bias', 'y_bias', and 'z_bias' + * field within 'readings', or by the 3D array 'bias' (bias[0] == x_bias; + * bias[1] == y_bias; bias[2] == z_bias). Bias is subtracted from uncalibrated + * data to generate calibrated data. + * + * All values are in micro-Tesla (uT) and measure the geomagnetic + * field in the X, Y and Z axis. + * + * If bias delivery is supported, this event is generated by default when + * chreSensorConfigure is called to enable for the sensor of type + * CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD, or if bias delivery is explicitly enabled + * through chreSensorConfigureBiasEvents() for the sensor. + */ +#define CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_BIAS_INFO \ + (CHRE_EVENT_SENSOR_OTHER_EVENTS_BASE + 2) + +/** + * nanoappHandleEvent argument: struct chreSensorThreeAxisData + * + * The data can be interpreted using the 'x_bias', 'y_bias', and 'z_bias' + * field within 'readings', or by the 3D array 'bias' (bias[0] == x_bias; + * bias[1] == y_bias; bias[2] == z_bias). Bias is subtracted from uncalibrated + * data to generate calibrated data. + * + * All values are in SI units (m/s^2) and measure the acceleration applied to + * the device. + * + * If bias delivery is supported, this event is generated by default when + * chreSensorConfigure is called to enable for the sensor of type + * CHRE_SENSOR_TYPE_ACCELEROMETER, or if bias delivery is explicitly enabled + * through chreSensorConfigureBiasEvents() for the sensor. + * + * @since v1.3 + */ +#define CHRE_EVENT_SENSOR_ACCELEROMETER_BIAS_INFO \ + (CHRE_EVENT_SENSOR_OTHER_EVENTS_BASE + 3) + +/** + * nanoappHandleEvent argument: struct chreSensorFlushCompleteEvent + * + * An event indicating that a flush request made by chreSensorFlushAsync has + * completed. + * + * @see chreSensorFlushAsync + * + * @since v1.3 + */ +#define CHRE_EVENT_SENSOR_FLUSH_COMPLETE \ + (CHRE_EVENT_SENSOR_OTHER_EVENTS_BASE + 4) + +/** + * nanoappHandleEvent argument: struct chreSensorThreeAxisData + * + * The data of this event is the same as that of + * CHRE_EVENT_SENSOR_GYROSCOPE_BIAS_INFO, except the sensorHandle field of + * chreSensorDataHeader contains the handle of the sensor of type + * CHRE_SENSOR_TYPE_UNCALIBRATED_GYROSCOPE. + * + * This event is only generated if the bias reporting is explicitly enabled + * for a nanoapp through chreSensorConfigureBiasEvents() for the sensor of type + * CHRE_SENSOR_TYPE_UNCALIBRATED_GYROSCOPE. + * + * @see CHRE_EVENT_SENSOR_GYROSCOPE_BIAS_INFO + * + * @since v1.3 + */ +#define CHRE_EVENT_SENSOR_UNCALIBRATED_GYROSCOPE_BIAS_INFO \ + (CHRE_EVENT_SENSOR_OTHER_EVENTS_BASE + 5) + +/** + * nanoappHandleEvent argument: struct chreSensorThreeAxisData + * + * The data of this event is the same as that of + * CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_BIAS_INFO, except the sensorHandle field + * of chreSensorDataHeader contains the handle of the sensor of type + * CHRE_SENSOR_TYPE_UNCALIBRATED_GEOMAGNETIC_FIELD. + * + * This event is only generated if the bias reporting is explicitly enabled + * for a nanoapp through chreSensorConfigureBiasEvents() for the sensor of type + * CHRE_SENSOR_TYPE_UNCALIBRATED_GEOMAGNETIC_FIELD. + * + * @see CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_BIAS_INFO + * + * @since v1.3 + */ +#define CHRE_EVENT_SENSOR_UNCALIBRATED_GEOMAGNETIC_FIELD_BIAS_INFO \ + (CHRE_EVENT_SENSOR_OTHER_EVENTS_BASE + 6) + +/** + * nanoappHandleEvent argument: struct chreSensorThreeAxisData + * + * The data of this event is the same as that of + * CHRE_EVENT_SENSOR_ACCELEROMETER_BIAS_INFO, except the sensorHandle field + * of chreSensorDataHeader contains the handle of the sensor of type + * CHRE_SENSOR_TYPE_UNCALIBRATED_ACCELEROMETER. + * + * This event is only generated if the bias reporting is explicitly enabled + * for a nanoapp through chreSensorConfigureBiasEvents for the sensor of type + * CHRE_SENSOR_TYPE_UNCALIBRATED_ACCELEROMETER. + * + * @see CHRE_EVENT_SENSOR_ACCELEROMETER_BIAS_INFO + * + * @since v1.3 + */ +#define CHRE_EVENT_SENSOR_UNCALIBRATED_ACCELEROMETER_BIAS_INFO \ + (CHRE_EVENT_SENSOR_OTHER_EVENTS_BASE + 7) + +#if CHRE_EVENT_SENSOR_UNCALIBRATED_ACCELEROMETER_BIAS_INFO > \ + CHRE_EVENT_SENSOR_LAST_EVENT +#error Too many sensor events. +#endif + +/** + * Value indicating we want the smallest possible latency for a sensor. + * + * This literally translates to 0 nanoseconds for the chreSensorConfigure() + * argument. While we won't get exactly 0 nanoseconds, the CHRE will + * queue up this event As Soon As Possible. + */ +#define CHRE_SENSOR_LATENCY_ASAP UINT64_C(0) + +/** + * Special value indicating non-importance, or non-applicability of the sampling + * interval. + * + * @see chreSensorConfigure + * @see chreSensorSamplingStatus + */ +#define CHRE_SENSOR_INTERVAL_DEFAULT UINT64_C(-1) + +/** + * Special value indicating non-importance of the latency. + * + * @see chreSensorConfigure + * @see chreSensorSamplingStatus + */ +#define CHRE_SENSOR_LATENCY_DEFAULT UINT64_C(-1) + +/** + * A sensor index value indicating that it is the default sensor. + * + * @see chreSensorFind + */ +#define CHRE_SENSOR_INDEX_DEFAULT UINT8_C(0) + +/** + * Special value indicating non-importance of the batch interval. + * + * @see chreSensorConfigureWithBatchInterval + */ +#define CHRE_SENSOR_BATCH_INTERVAL_DEFAULT UINT64_C(-1) + +// This is used to define elements of enum chreSensorConfigureMode. +#define CHRE_SENSOR_CONFIGURE_RAW_POWER_ON (1 << 0) + +// This is used to define elements of enum chreSensorConfigureMode. +#define CHRE_SENSOR_CONFIGURE_RAW_REPORT_CONTINUOUS (1 << 1) + +// This is used to define elements of enum chreSensorConfigureMode. +#define CHRE_SENSOR_CONFIGURE_RAW_REPORT_ONE_SHOT (2 << 1) + +/** + * The maximum amount of time allowed to elapse between the call to + * chreSensorFlushAsync() and when CHRE_EVENT_SENSOR_FLUSH_COMPLETE is delivered + * to the nanoapp on a successful flush. + */ +#define CHRE_SENSOR_FLUSH_COMPLETE_TIMEOUT_NS (5 * CHRE_NSEC_PER_SEC) + +/** + * Modes we can configure a sensor to use. + * + * Our mode will affect not only how/if we receive events, but + * also whether or not the sensor will be powered on our behalf. + * + * @see chreSensorConfigure + */ +enum chreSensorConfigureMode { + /** + * Get events from the sensor. + * + * Power: Turn on if not already on. + * Reporting: Continuous. Send each new event as it comes (subject to + * batching and latency). + */ + CHRE_SENSOR_CONFIGURE_MODE_CONTINUOUS = + (CHRE_SENSOR_CONFIGURE_RAW_POWER_ON | + CHRE_SENSOR_CONFIGURE_RAW_REPORT_CONTINUOUS), + + /** + * Get a single event from the sensor and then become DONE. + * + * Once the event is sent, the sensor automatically + * changes to CHRE_SENSOR_CONFIGURE_MODE_DONE mode. + * + * Power: Turn on if not already on. + * Reporting: One shot. Send the next event and then be DONE. + */ + CHRE_SENSOR_CONFIGURE_MODE_ONE_SHOT = + (CHRE_SENSOR_CONFIGURE_RAW_POWER_ON | + CHRE_SENSOR_CONFIGURE_RAW_REPORT_ONE_SHOT), + + /** + * Get events from a sensor that are generated for any client in the system. + * + * This is considered passive because the sensor will not be powered on for + * the sake of our nanoapp. If and only if another client in the system has + * requested this sensor power on will we get events. + * + * This can be useful for something which is interested in seeing data, but + * not interested enough to be responsible for powering on the sensor. + * + * Power: Do not power the sensor on our behalf. + * Reporting: Continuous. Send each event as it comes. + */ + CHRE_SENSOR_CONFIGURE_MODE_PASSIVE_CONTINUOUS = + CHRE_SENSOR_CONFIGURE_RAW_REPORT_CONTINUOUS, + + /** + * Get a single event from a sensor that is generated for any client in the + * system. + * + * See CHRE_SENSOR_CONFIGURE_MODE_PASSIVE_CONTINUOUS for more details on + * what the "passive" means. + * + * Power: Do not power the sensor on our behalf. + * Reporting: One shot. Send only the next event and then be DONE. + */ + CHRE_SENSOR_CONFIGURE_MODE_PASSIVE_ONE_SHOT = + CHRE_SENSOR_CONFIGURE_RAW_REPORT_ONE_SHOT, + + /** + * Indicate we are done using this sensor and no longer interested in it. + * + * See chreSensorConfigure for more details on expressing interest or + * lack of interest in a sensor. + * + * Power: Do not power the sensor on our behalf. + * Reporting: None. + */ + CHRE_SENSOR_CONFIGURE_MODE_DONE = 0, +}; + +/** + * A structure containing information about a Sensor. + * + * See documentation of individual fields below. + */ +struct chreSensorInfo { + /** + * The name of the sensor. + * + * A text name, useful for logging/debugging, describing the Sensor. This + * is not assured to be unique (i.e. there could be multiple sensors with + * the name "Temperature"). + * + * CHRE implementations may not set this as NULL. An empty + * string, while discouraged, is legal. + */ + const char *sensorName; + + /** + * One of the CHRE_SENSOR_TYPE_* defines above. + */ + uint8_t sensorType; + + /** + * Flag indicating if this sensor is on-change. + * + * An on-change sensor only generates events when underlying state + * changes. This has the same meaning as on-change does in the Android + * Sensors HAL. See sensors.h for much more details. + * + * A value of 1 indicates this is on-change. 0 indicates this is not + * on-change. + */ + uint8_t isOnChange : 1; + + /** + * Flag indicating if this sensor is one-shot. + * + * A one-shot sensor only triggers a single event, and then automatically + * disables itself. + * + * A value of 1 indicates this is one-shot. 0 indicates this is not + * on-change. + */ + uint8_t isOneShot : 1; + + /** + * Flag indicating if this sensor supports reporting bias info events. + * + * This field will be set to 0 when running on CHRE API versions prior to + * v1.3, but must be ignored (i.e. does not mean bias info event is not + * supported). + * + * @see chreSensorConfigureBiasEvents + * + * @since v1.3 + */ + uint8_t reportsBiasEvents : 1; + + /** + * Flag indicating if this sensor supports passive mode requests. + * + * This field will be set to 0 when running on CHRE API versions prior to + * v1.4, and must be ignored (i.e. does not mean passive mode requests are + * not supported). + * + * @see chreSensorConfigure + * + * @since v1.4 + */ + uint8_t supportsPassiveMode : 1; + + uint8_t unusedFlags : 4; + + /** + * The minimum sampling interval supported by this sensor, in nanoseconds. + * + * Requests to chreSensorConfigure with a lower interval than this will + * fail. If the sampling interval is not applicable to this sensor, this + * will be set to CHRE_SENSOR_INTERVAL_DEFAULT. + * + * This field will be set to 0 when running on CHRE API versions prior to + * v1.1, indicating that the minimum interval is not known. + * + * @since v1.1 + */ + uint64_t minInterval; + + /** + * Uniquely identifies the sensor for a given type. A value of 0 indicates + * that this is the "default" sensor, which is returned by + * chreSensorFindDefault(). + * + * The sensor index of a given type must be stable across boots (i.e. must + * not change), and a different sensor of the same type must have different + * sensor index values, and the set of sensorIndex values for a given sensor + * type must be continuguous. + * + * @since v1.5 + */ + uint8_t sensorIndex; +}; + +/** + * The status of a sensor's sampling configuration. + */ +struct chreSensorSamplingStatus { + /** + * The interval, in nanoseconds, at which sensor data is being sampled at. + * This should be used by nanoapps to determine the rate at which samples + * will be generated and not to indicate what the sensor is truly sampling + * at since resampling may occur to limit incoming data. + * + * If this is CHRE_SENSOR_INTERVAL_DEFAULT, then a sampling interval + * isn't meaningful for this sensor. + * + * Note that if 'enabled' is false, this value is not meaningful. + */ + uint64_t interval; + + /** + * The latency, in nanoseconds, at which the sensor is now reporting. + * + * If this is CHRE_SENSOR_LATENCY_DEFAULT, then a latency + * isn't meaningful for this sensor. + * + * The effective batch interval can be derived from this value by + * adding the current sampling interval. + * + * Note that if 'enabled' is false, this value is not meaningful. + */ + uint64_t latency; + + /** + * True if the sensor is actively powered and sampling; false otherwise. + */ + bool enabled; +}; + +/** + * The nanoappHandleEvent argument for CHRE_EVENT_SENSOR_SAMPLING_CHANGE. + * + * Note that only at least one of 'interval' or 'latency' must be + * different than it was prior to this event. Thus, one of these + * fields may be (but doesn't need to be) the same as before. + */ +struct chreSensorSamplingStatusEvent { + /** + * The handle of the sensor which has experienced a change in sampling. + */ + uint32_t sensorHandle; + + /** + * The new sampling status. + * + * At least one of the field in this struct will be different from + * the previous sampling status event. + */ + struct chreSensorSamplingStatus status; +}; + +/** + * The nanoappHandleEvent argument for CHRE_EVENT_SENSOR_FLUSH_COMPLETE. + * + * @see chreSensorFlushAsync + * + * @since v1.3 + */ +struct chreSensorFlushCompleteEvent { + /** + * The handle of the sensor which a flush was completed. + */ + uint32_t sensorHandle; + + /** + * Populated with a value from enum {@link #chreError}, indicating whether + * the flush failed, and if so, provides the cause of the failure. + */ + uint8_t errorCode; + + /** + * Reserved for future use. Set to 0. + */ + uint8_t reserved[3]; + + /** + * Set to the cookie parameter given to chreSensorFlushAsync. + */ + const void *cookie; +}; + +/** + * Find the default sensor for a given sensor type. + * + * @param sensorType One of the CHRE_SENSOR_TYPE_* constants. + * @param handle If a sensor is found, then the memory will be filled with + * the value for the sensor's handle. This argument must be non-NULL. + * @return true if a sensor was found, false otherwise. + */ +bool chreSensorFindDefault(uint8_t sensorType, uint32_t *handle); + +/** + * Finds a sensor of a given index and sensor type. + * + * For CHRE implementations that support multiple sensors of the same sensor + * type, this method can be used to get the non-default sensor(s). The default + * sensor, as defined in the chreSensorFindDefault(), will be returned if + * a sensor index of zero is specified. + * + * A simple example of iterating all available sensors of a given type is + * provided here: + * + * uint32_t handle; + * for (uint8_t i = 0; chreSensorFind(sensorType, i, &handle); i++) { + * chreLog(CHRE_LOG_INFO, + * "Found sensor index %" PRIu8 ", which has handle %" PRIu32, + * i, handle); + * } + * + * If this method is invoked for CHRE versions prior to v1.5, invocations with + * sensorIndex value of 0 will be equivalent to using chreSensorFindDefault, and + * if sensorIndex is non-zero will return false. + * + * In cases where multiple sensors are supported in both the Android sensors + * framework and CHRE, the sensorName of the chreSensorInfo struct for a given + * sensor instance must match exactly with that of the + * android.hardware.Sensor#getName() return value. This can be used to match a + * sensor instance between the Android and CHRE sensors APIs. + * + * @param sensorType One of the CHRE_SENSOR_TYPE_* constants. + * @param sensorIndex The index of the desired sensor. + * @param handle If a sensor is found, then the memory will be filled with + * the value for the sensor's handle. This argument must be non-NULL. + * @return true if a sensor was found, false otherwise. + * + * @since v1.5 + */ +bool chreSensorFind(uint8_t sensorType, uint8_t sensorIndex, uint32_t *handle); + +/** + * Get the chreSensorInfo struct for a given sensor. + * + * @param sensorHandle The sensor handle, as obtained from + * chreSensorFindDefault() or passed to nanoappHandleEvent(). + * @param info If the sensor is valid, then this memory will be filled with + * the SensorInfo contents for this sensor. This argument must be + * non-NULL. + * @return true if the senor handle is valid and 'info' was filled in; + * false otherwise. + */ +bool chreGetSensorInfo(uint32_t sensorHandle, struct chreSensorInfo *info); + +/** + * Get the chreSensorSamplingStatus struct for a given sensor. + * + * Note that this may be different from what was requested in + * chreSensorConfigure(), for multiple reasons. It's possible that the sensor + * does not exactly support the interval requested in chreSensorConfigure(), so + * a faster one was chosen. + * + * It's also possible that there is another user of this sensor who has + * requested a faster interval and/or lower latency. This latter scenario + * should be noted, because it means the sensor rate can change due to no + * interaction from this nanoapp. Note that the + * CHRE_EVENT_SENSOR_SAMPLING_CHANGE event will trigger in this case, so it's + * not necessary to poll for such a change. + * + * This function must return a valid status if the provided sensor is being + * actively sampled by a nanoapp and a CHRE_EVENT_SENSOR_SAMPLING_CHANGE has + * been delivered indicating their request has taken effect. It is not required + * to return a valid status if no nanoapp is actively sampling the sensor. + * + * @param sensorHandle The sensor handle, as obtained from + * chreSensorFindDefault() or passed to nanoappHandleEvent(). + * @param status If the sensor is actively enabled by a nanoapp, then this + * memory must be filled with the sampling status contents for this sensor. + * This argument must be non-NULL. + * @return true if the sensor handle is valid and 'status' was filled in; + * false otherwise. + */ +bool chreGetSensorSamplingStatus(uint32_t sensorHandle, + struct chreSensorSamplingStatus *status); + +/** + * Configures a given sensor at a specific interval and latency and mode. + * + * If this sensor's chreSensorInfo has isOneShot set to 1, + * then the mode must be one of the ONE_SHOT modes, or this method will fail. + * + * The CHRE wants to power as few sensors as possible, in keeping with its + * low power design. As such, it only turns on sensors when there are clients + * actively interested in that sensor data, and turns off sensors as soon as + * there are no clients interested in them. Calling this method generally + * indicates an interest, and using CHRE_SENSOR_CONFIGURE_MODE_DONE shows + * when we are no longer interested. + * + * Thus, each initial Configure of a sensor (per nanoapp) needs to eventually + * have a DONE call made, either directly or on its behalf. Subsequent calls + * to a Configure method within the same nanoapp, when there has been no DONE + * in between, still only require a single DONE call. + * + * For example, the following is valid usage: + * <code> + * chreSensorConfigure(myHandle, mode, interval0, latency0); + * [...] + * chreSensorConfigure(myHandle, mode, interval1, latency0); + * [...] + * chreSensorConfigure(myHandle, mode, interval1, latency1); + * [...] + * chreSensorConfigureModeOnly(myHandle, CHRE_SENSOR_CONFIGURE_MODE_DONE); + * </code> + * + * The first call to Configure is the one which creates the requirement + * to eventually call with DONE. The subsequent calls are just changing the + * interval/latency. They have not changed the fact that this nanoapp is + * still interested in output from the sensor 'myHandle'. Thus, only one + * single call for DONE is needed. + * + * There is a special case. One-shot sensors, sensors which + * just trigger a single event and never trigger again, implicitly go into + * DONE mode after that single event triggers. Thus, the + * following are legitimate usages: + * <code> + * chreSensorConfigure(myHandle, MODE_ONE_SHOT, interval, latency); + * [...] + * [myHandle triggers an event] + * [no need to configure to DONE]. + * </code> + * + * And: + * <code> + * chreSensorConfigure(myHandle, MODE_ONE_SHOT, interval, latency); + * [...] + * chreSensorConfigureModeOnly(myHandle, MODE_DONE); + * [we cancelled myHandle before it ever triggered an event] + * </code> + * + * Note that while PASSIVE modes, by definition, don't express an interest in + * powering the sensor, DONE is still necessary to silence the event reporting. + * Starting with CHRE API v1.4, for sensors that do not support passive mode, a + * request with mode set to CHRE_SENSOR_CONFIGURE_MODE_PASSIVE_CONTINUOUS or + * CHRE_SENSOR_CONFIGURE_MODE_PASSIVE_ONE_SHOT will be rejected. CHRE API + * versions 1.3 and older implicitly assume that passive mode is supported + * across all sensors, however this is not necessarily the case. Clients can + * call chreSensorInfo to identify whether a sensor supports passive mode. + * + * When a calibrated sensor (e.g. CHRE_SENSOR_TYPE_ACCELEROMETER) is + * successfully enabled through this method and if bias delivery is supported, + * by default CHRE will start delivering bias events for the sensor + * (e.g. CHRE_EVENT_SENSOR_ACCELEROMETER_BIAS_INFO) to the nanoapp. If the + * nanoapp does not wish to receive these events, they can be disabled through + * chreSensorConfigureBiasEvents after enabling the sensor. + * + * @param sensorHandle The handle to the sensor, as obtained from + * chreSensorFindDefault(). + * @param mode The mode to use. See descriptions within the + * chreSensorConfigureMode enum. + * @param interval The interval, in nanoseconds, at which we want events from + * the sensor. On success, the sensor will be set to 'interval', or a value + * less than 'interval'. There is a special value + * CHRE_SENSOR_INTERVAL_DEFAULT, in which we don't express a preference for + * the interval, and allow the sensor to choose what it wants. Note that + * due to batching, we may receive events less frequently than + * 'interval'. + * @param latency The maximum latency, in nanoseconds, allowed before the + * CHRE begins delivery of an event. This will control how many events + * can be queued by the sensor before requiring a delivery event. + * Latency is defined as the "timestamp when event is queued by the CHRE" + * minus "timestamp of oldest unsent data reading". + * There is a special value CHRE_SENSOR_LATENCY_DEFAULT, in which we don't + * express a preference for the latency, and allow the sensor to choose what + * it wants. + * Note that there is no assurance of how long it will take an event to + * get through a CHRE's queueing system, and thus there is no ability to + * request a minimum time from the occurrence of a phenomenon to when the + * nanoapp receives the information. The current CHRE API has no + * real-time elements, although future versions may introduce some to + * help with this issue. + * @return true if the configuration succeeded, false otherwise. + * + * @see chreSensorConfigureMode + * @see chreSensorFindDefault + * @see chreSensorInfo + * @see chreSensorConfigureBiasEvents + */ +bool chreSensorConfigure(uint32_t sensorHandle, + enum chreSensorConfigureMode mode, + uint64_t interval, uint64_t latency); + +/** + * Short cut for chreSensorConfigure where we only want to configure the mode + * and do not care about interval/latency. + * + * @see chreSensorConfigure + */ +static inline bool chreSensorConfigureModeOnly( + uint32_t sensorHandle, enum chreSensorConfigureMode mode) { + return chreSensorConfigure(sensorHandle, + mode, + CHRE_SENSOR_INTERVAL_DEFAULT, + CHRE_SENSOR_LATENCY_DEFAULT); +} + +/** + * Convenience function that wraps chreSensorConfigure but enables batching to + * be controlled by specifying the desired maximum batch interval rather + * than maximum sample latency. Users may find the batch interval to be a more + * intuitive method of expressing the desired batching behavior. + * + * Batch interval is different from latency as the batch interval time is + * counted starting when the prior event containing a batch of sensor samples is + * delivered, while latency starts counting when the first sample is deferred to + * start collecting a batch. In other words, latency ignores the time between + * the last sample in a batch to the first sample of the next batch, while it's + * included in the batch interval, as illustrated below. + * + * Time 0 1 2 3 4 5 6 7 8 + * Batch A B C + * Sample a1 a2 a3 b1 b2 b3 c1 c2 c3 + * Latency [ ] [ ] [ ] + * BatchInt | | | + * + * In the diagram, the effective sample interval is 1 time unit, latency is 2 + * time units, and batch interval is 3 time units. + * + * @param sensorHandle See chreSensorConfigure#sensorHandle + * @param mode See chreSensorConfigure#mode + * @param sampleInterval See chreSensorConfigure#interval, but note that + * CHRE_SENSOR_INTERVAL_DEFAULT is not a supported input to this method. + * @param batchInterval The desired maximum interval, in nanoseconds, between + * CHRE enqueuing each batch of sensor samples. + * @return Same as chreSensorConfigure + * + * @see chreSensorConfigure + * + * @since v1.1 + */ +static inline bool chreSensorConfigureWithBatchInterval( + uint32_t sensorHandle, enum chreSensorConfigureMode mode, + uint64_t sampleInterval, uint64_t batchInterval) { + bool result = false; + + if (sampleInterval != CHRE_SENSOR_INTERVAL_DEFAULT) { + uint64_t latency; + if (batchInterval == CHRE_SENSOR_BATCH_INTERVAL_DEFAULT) { + latency = CHRE_SENSOR_LATENCY_DEFAULT; + } else if (batchInterval > sampleInterval) { + latency = batchInterval - sampleInterval; + } else { + latency = CHRE_SENSOR_LATENCY_ASAP; + } + result = chreSensorConfigure(sensorHandle, mode, sampleInterval, + latency); + } + + return result; +} + +/** + * Configures the reception of bias events for a specific sensor. + * + * If bias event delivery is supported for a sensor, the sensor's chreSensorInfo + * has reportsBiasEvents set to 1. If supported, it must be supported for both + * calibrated and uncalibrated versions of the sensor. If supported, CHRE must + * provide bias events to the nanoapp by default when chreSensorConfigure is + * called to enable the calibrated version of the sensor (for backwards + * compatibility reasons, as this is the defined behavior for CHRE API v1.0). + * When configuring uncalibrated sensors, nanoapps must explicitly configure an + * enable request through this method to receive bias events. If bias event + * delivery is not supported for the sensor, this method will return false and + * no bias events will be generated. + * + * To enable bias event delivery (enable=true), the nanoapp must be registered + * to the sensor through chreSensorConfigure, and bias events will only be + * generated when the sensor is powered on. To disable the bias event delivery, + * this method can be invoked with enable=false. + * + * If an enable configuration is successful, the calling nanoapp will receive + * bias info events, e.g. CHRE_EVENT_SENSOR_ACCELEROMETER_BIAS_INFO, when the + * bias status changes (or first becomes available). Calibrated data + * (e.g. CHRE_SENSOR_TYPE_ACCELEROMETER) is generated by subracting bias from + * uncalibrated data (e.g. CHRE_SENSOR_TYPE_UNCALIBRATED_ACCELEROMETER). + * Calibrated sensor events are generated by applying the most recent bias + * available (i.e. timestamp of calibrated data are greater than or equal to the + * timestamp of the bias data that has been applied to it). The configuration of + * bias event delivery persists until the sensor is unregistered by the nanoapp + * through chreSensorConfigure or modified through this method. + * + * To get an initial bias before new bias events, the nanoapp should get the + * bias synchronously after this method is invoked, e.g.: + * + * if (chreSensorConfigure(handle, ...)) { + * chreSensorConfigureBiasEvents(handle, true); + * chreSensorGetThreeAxisBias(handle, &bias); + * } + * + * Note that chreSensorGetThreeAxisBias() should be called after + * chreSensorConfigureBiasEvents() to ensure that no bias events are lost. + * + * If called while running on a CHRE API version below v1.3, this function + * returns false and has no effect. The default behavior regarding bias events + * is unchanged, meaning that the implementation may still send bias events + * when a calibrated sensor is registered (if supported), and will not send bias + * events when an uncalibrated sensor is registered. + * + * @param sensorHandle The handle to the sensor, as obtained from + * chreSensorFindDefault(). + * @param enable true to receive bias events, false otherwise + * + * @return true if the configuration succeeded, false otherwise + * + * @since v1.3 + */ +bool chreSensorConfigureBiasEvents(uint32_t sensorHandle, bool enable); + +/** + * Synchronously provides the most recent bias info available for a sensor. The + * bias will only be provided for a sensor that supports bias event delivery + * using the chreSensorThreeAxisData type. If the bias is not yet available + * (but is supported), this method will store data with a bias of 0 and the + * accuracy field in chreSensorDataHeader set to CHRE_SENSOR_ACCURACY_UNKNOWN. + * + * If called while running on a CHRE API version below v1.3, this function + * returns false. + * + * @param sensorHandle The handle to the sensor, as obtained from + * chreSensorFindDefault(). + * @param bias A pointer to where the bias will be stored. + * + * @return true if the bias was successfully stored, false if sensorHandle was + * invalid or the sensor does not support three axis bias delivery + * + * @since v1.3 + * + * @see chreSensorConfigureBiasEvents + */ +bool chreSensorGetThreeAxisBias(uint32_t sensorHandle, + struct chreSensorThreeAxisData *bias); + +/** + * Makes a request to flush all samples stored for batching. The nanoapp must be + * registered to the sensor through chreSensorConfigure, and the sensor must be + * powered on. If the request is accepted, all batched samples of the sensor + * are sent to nanoapps registered to the sensor. During a flush, it is treated + * as though the latency as given in chreSensorConfigure has expired. When all + * batched samples have been flushed (or the flush fails), the nanoapp will + * receive a unicast CHRE_EVENT_SENSOR_FLUSH_COMPLETE event. The time to deliver + * this event must not exceed CHRE_SENSOR_FLUSH_COMPLETE_TIMEOUT_NS after this + * method is invoked. If there are no samples in the batch buffer (either in + * hardware FIFO or software), then this method will return true and a + * CHRE_EVENT_SENSOR_FLUSH_COMPLETE event is delivered immediately. + * + * If a flush request is invalid (e.g. the sensor refers to a one-shot sensor, + * or the sensor was not enabled), and this API will return false and no + * CHRE_EVENT_SENSOR_FLUSH_COMPLETE event will be delivered. + * + * If multiple flush requests are made for a sensor prior to flush completion, + * then the requesting nanoapp will receive all batched samples existing at the + * time of the latest flush request. In this case, the number of + * CHRE_EVENT_SENSOR_FLUSH_COMPLETE events received must equal the number of + * flush requests made. + * + * If a sensor request is disabled after a flush request is made through this + * method but before the flush operation is completed, the nanoapp will receive + * a CHRE_EVENT_SENSOR_FLUSH_COMPLETE with the error code + * CHRE_ERROR_FUNCTION_DISABLED for any pending flush requests. + * + * Starting with CHRE API v1.3, implementations must support this capability + * across all exposed sensor types. + * + * @param sensorHandle The handle to the sensor, as obtained from + * chreSensorFindDefault(). + * @param cookie An opaque value that will be included in the + * chreSensorFlushCompleteEvent sent in relation to this request. + * + * @return true if the request was accepted for processing, false otherwise + * + * @since v1.3 + */ +bool chreSensorFlushAsync(uint32_t sensorHandle, const void *cookie); + +#ifdef __cplusplus +} +#endif + +#endif /* _CHRE_SENSOR_H_ */
diff --git a/chre_api/legacy/v1_10/chre/sensor_types.h b/chre_api/legacy/v1_10/chre/sensor_types.h new file mode 100644 index 0000000..6b46a22 --- /dev/null +++ b/chre_api/legacy/v1_10/chre/sensor_types.h
@@ -0,0 +1,483 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// IWYU pragma: private, include "chre_api/chre.h" +// IWYU pragma: friend chre/.*\.h + +#ifndef _CHRE_SENSOR_TYPES_H_ +#define _CHRE_SENSOR_TYPES_H_ + +/** + * @file + * Standalone definition of sensor types, and the data structures of the sample + * events they emit. + */ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + * The CHRE_SENSOR_TYPE_* defines are the sensor types supported. + * + * Unless otherwise noted, each of these sensor types is based off of a + * corresponding sensor type in the Android API's sensors.h interface. + * For a given CHRE_SENSOR_TYPE_FOO, it corresponds to the SENSOR_TYPE_FOO in + * hardware/libhardware/include/hardware/sensors.h of the Android code base. + * + * Unless otherwise noted below, a CHRE_SENSOR_TYPE_FOO should be assumed + * to work the same as the Android SENSOR_TYPE_FOO, as documented in the + * sensors.h documentation and as detailed within the Android Compatibility + * Definition Document. + * + * Note that every sensor will generate CHRE_EVENT_SENSOR_SAMPLING_CHANGE + * events, so it is not listed with each individual sensor. + */ + +/** + * Start value for all of the vendor-defined private sensors. + * + * @since v1.2 + */ +#define CHRE_SENSOR_TYPE_VENDOR_START UINT8_C(0xC0) + +/** + * Accelerometer. + * + * Generates: CHRE_EVENT_SENSOR_ACCELEROMETER_DATA and + * optionally CHRE_EVENT_SENSOR_ACCELEROMETER_BIAS_INFO + * + * Note that the ACCELEROMETER_DATA is always the fully calibrated data, + * including factory calibration and runtime calibration if available. + * + * @see chreConfigureSensorBiasEvents + */ +#define CHRE_SENSOR_TYPE_ACCELEROMETER UINT8_C(0x01) + +/** + * Instantaneous motion detection. + * + * Generates: CHRE_EVENT_SENSOR_INSTANT_MOTION_DETECT_DATA + * + * This is a one-shot sensor. + * + * This does not have a direct analogy within sensors.h. This is similar + * to SENSOR_TYPE_MOTION_DETECT, but this triggers instantly upon any + * motion, instead of waiting for a period of continuous motion. + */ +#define CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT UINT8_C(0x02) + +/** + * Stationary detection. + * + * Generates: CHRE_EVENT_SENSOR_STATIONARY_DETECT_DATA + * + * This is a one-shot sensor. + */ +#define CHRE_SENSOR_TYPE_STATIONARY_DETECT UINT8_C(0x03) + +/** + * Gyroscope. + * + * Generates: CHRE_EVENT_SENSOR_GYROSCOPE_DATA and + * optionally CHRE_EVENT_SENSOR_GYROSCOPE_BIAS_INFO + * + * Note that the GYROSCOPE_DATA is always the fully calibrated data, including + * factory calibration and runtime calibration if available. + * + * @see chreConfigureSensorBiasEvents + */ +#define CHRE_SENSOR_TYPE_GYROSCOPE UINT8_C(0x06) + +/** + * Uncalibrated gyroscope. + * + * Generates: CHRE_EVENT_SENSOR_UNCALIBRATED_GYROSCOPE_DATA + * + * Note that the UNCALIBRATED_GYROSCOPE_DATA must be factory calibrated data, + * but not runtime calibrated. + */ +#define CHRE_SENSOR_TYPE_UNCALIBRATED_GYROSCOPE UINT8_C(0x07) + +/** + * Magnetometer. + * + * Generates: CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_DATA and + * optionally CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_BIAS_INFO + * + * Note that the GEOMAGNETIC_FIELD_DATA is always the fully calibrated data, + * including factory calibration and runtime calibration if available. + * + * @see chreConfigureSensorBiasEvents + */ +#define CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD UINT8_C(0x08) + +/** + * Uncalibrated magnetometer. + * + * Generates: CHRE_EVENT_SENSOR_UNCALIBRATED_GEOMAGNETIC_FIELD_DATA + * + * Note that the UNCALIBRATED_GEOMAGNETIC_FIELD_DATA must be factory calibrated + * data, but not runtime calibrated. + */ +#define CHRE_SENSOR_TYPE_UNCALIBRATED_GEOMAGNETIC_FIELD UINT8_C(0x09) + +/** + * Barometric pressure sensor. + * + * Generates: CHRE_EVENT_SENSOR_PRESSURE_DATA + */ +#define CHRE_SENSOR_TYPE_PRESSURE UINT8_C(0x0A) + +/** + * Ambient light sensor. + * + * Generates: CHRE_EVENT_SENSOR_LIGHT_DATA + * + * This is an on-change sensor. + */ +#define CHRE_SENSOR_TYPE_LIGHT UINT8_C(0x0C) + +/** + * Proximity detection. + * + * Generates: CHRE_EVENT_SENSOR_PROXIMITY_DATA + * + * This is an on-change sensor. + */ +#define CHRE_SENSOR_TYPE_PROXIMITY UINT8_C(0x0D) + +/** + * Step detection. + * + * Generates: CHRE_EVENT_SENSOR_STEP_DETECT_DATA + * + * @since v1.3 + */ +#define CHRE_SENSOR_TYPE_STEP_DETECT UINT8_C(0x17) + +/** + * Step counter. + * + * Generates: CHRE_EVENT_SENSOR_STEP_COUNTER_DATA + * + * This is an on-change sensor. Note that the data returned by this sensor must + * match the value that can be obtained via the Android sensors framework at the + * same point in time. This means, if CHRE reboots from the rest of the system, + * the counter must not reset to 0. + * + * @since v1.5 + */ +#define CHRE_SENSOR_TYPE_STEP_COUNTER UINT8_C(0x18) + +/** + * Significant motion detection. + * + * Generates: CHRE_EVENT_SENSOR_SIGNIFICANT_MOTION_DATA + * + * This is a one-shot sensor. + * + * @since v1.10 + */ +#define CHRE_SENSOR_TYPE_SIGNIFICANT_MOTION UINT8_C(0x1C) + +/** + * Hinge angle sensor. + * + * Generates: CHRE_EVENT_SENSOR_HINGE_ANGLE_DATA + * + * This is an on-change sensor. + * + * A sensor of this type measures the angle, in degrees, between two + * integral parts of the device. Movement of a hinge measured by this sensor + * type is expected to alter the ways in which the user may interact with + * the device, for example by unfolding or revealing a display. + * + * @since v1.5 + */ +#define CHRE_SENSOR_TYPE_HINGE_ANGLE UINT8_C(0x24) + +/** + * Uncalibrated accelerometer. + * + * Generates: CHRE_EVENT_SENSOR_UNCALIBRATED_ACCELEROMETER_DATA + * + * Note that the UNCALIBRATED_ACCELEROMETER_DATA must be factory calibrated + * data, but not runtime calibrated. + */ +#define CHRE_SENSOR_TYPE_UNCALIBRATED_ACCELEROMETER UINT8_C(0x37) + +/** + * Accelerometer temperature. + * + * Generates: CHRE_EVENT_SENSOR_ACCELEROMETER_TEMPERATURE_DATA + */ +#define CHRE_SENSOR_TYPE_ACCELEROMETER_TEMPERATURE UINT8_C(0x38) + +/** + * Gyroscope temperature. + * + * Generates: CHRE_EVENT_SENSOR_GYROSCOPE_TEMPERATURE_DATA + */ +#define CHRE_SENSOR_TYPE_GYROSCOPE_TEMPERATURE UINT8_C(0x39) + +/** + * Magnetometer temperature. + * + * Generates: CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_TEMPERATURE_DATA + */ +#define CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD_TEMPERATURE UINT8_C(0x3A) + +#if CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD_TEMPERATURE >= CHRE_SENSOR_TYPE_VENDOR_START +#error Too many sensor types +#endif + +/** + * Values that can be stored in the accuracy field of chreSensorDataHeader. + * If CHRE_SENSOR_ACCURACY_UNKNOWN is returned, then the driver did not provide + * accuracy information with the data. Values in the range + * [CHRE_SENSOR_ACCURACY_VENDOR_START, CHRE_SENSOR_ACCURACY_VENDOR_END] are + * reserved for vendor-specific values for vendor sensor types, and are not used + * by CHRE for standard sensor types. + * + * Otherwise, the values have the same meaning as defined in the Android + * Sensors definition: + * https://developer.android.com/reference/android/hardware/SensorManager + * + * @since v1.3 + * + * @defgroup CHRE_SENSOR_ACCURACY + * @{ + */ + +#define CHRE_SENSOR_ACCURACY_UNKNOWN UINT8_C(0x00) +#define CHRE_SENSOR_ACCURACY_UNRELIABLE UINT8_C(0x01) +#define CHRE_SENSOR_ACCURACY_LOW UINT8_C(0x02) +#define CHRE_SENSOR_ACCURACY_MEDIUM UINT8_C(0x03) +#define CHRE_SENSOR_ACCURACY_HIGH UINT8_C(0x04) +#define CHRE_SENSOR_ACCURACY_VENDOR_START UINT8_C(0xC0) +#define CHRE_SENSOR_ACCURACY_VENDOR_END UINT8_MAX + +/** @} */ + +/** + * Header used in every structure containing batchable data from a sensor. + * + * The typical structure for sensor data looks like: + * + * struct chreSensorTypeData { + * struct chreSensorDataHeader header; + * struct chreSensorTypeSampleData { + * uint32_t timestampDelta; + * union { + * <type> value; + * <type> interpretation0; + * <type> interpretation1; + * }; + * } readings[1]; + * }; + * + * Despite 'readings' being declared as an array of 1 element, + * an instance of the struct will actually have 'readings' as + * an array of header.readingCount elements (which may be 1). + * The 'timestampDelta' is in relation to the previous 'readings' (or + * the baseTimestamp for readings[0]. So, + * Timestamp for readings[0] == header.baseTimestamp + + * readings[0].timestampDelta. + * Timestamp for readings[1] == timestamp for readings[0] + + * readings[1].timestampDelta. + * And thus, in order to determine the timestamp for readings[N], it's + * necessary to process through all of the N-1 readings. The advantage, + * though, is that our entire readings can span an arbitrary length of time, + * just as long as any two consecutive readings differ by no more than + * 4.295 seconds (timestampDelta, like all time in the CHRE, is in + * nanoseconds). + * + * If a sensor has batched readings where two consecutive readings differ by + * more than 4.295 seconds, the CHRE will split them across multiple + * instances of the struct, and send multiple events. + * + * The value from the sensor is typically expressed in a union, + * allowing a generic access to the data ('value'), along with + * differently named access giving a more natural interpretation + * of the data for the specific sensor types which use this + * structure. This allows, for example, barometer code to + * reference readings[N].pressure, and an ambient light sensor + * to reference readings[N].light, while both use the same + * structure. + */ +struct chreSensorDataHeader { + /** + * The base timestamp, in nanoseconds; must be in the same time base as + * chreGetTime(). + */ + uint64_t baseTimestamp; + + /** + * The handle of the sensor producing this event. + */ + uint32_t sensorHandle; + + /** + * The number elements in the 'readings' array. + * + * This must be at least 1. + */ + uint16_t readingCount; + + /** + * The accuracy of the sensor data. + * + * @ref CHRE_SENSOR_ACCURACY + * + * @since v1.3 + */ + uint8_t accuracy; + + /** + * Reserved bytes. + * + * This must be 0. + */ + uint8_t reserved; +}; + +/** + * Data for a sensor which reports on three axes. + * + * This is used by CHRE_EVENT_SENSOR_ACCELEROMETER_DATA, + * CHRE_EVENT_SENSOR_ACCELEROMETER_BIAS_INFO, + * CHRE_EVENT_SENSOR_UNCALIBRATED_ACCELEROMETER_DATA, + * CHRE_EVENT_SENSOR_GYROSCOPE_DATA, + * CHRE_EVENT_SENSOR_GYROSCOPE_BIAS_INFO, + * CHRE_EVENT_SENSOR_UNCALIBRATED_GYROSCOPE_DATA, + * CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_DATA, + * CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_BIAS_INFO, and + * CHRE_EVENT_SENSOR_UNCALIBRATED_GEOMAGNETIC_FIELD_DATA. + */ +struct chreSensorThreeAxisData { + /** + * @see chreSensorDataHeader + */ + struct chreSensorDataHeader header; + struct chreSensorThreeAxisSampleData { + /** + * @see chreSensorDataHeader + */ + uint32_t timestampDelta; + union { + float values[3]; + float v[3]; + struct { + float x; + float y; + float z; + }; + float bias[3]; + struct { + float x_bias; + float y_bias; + float z_bias; + }; + }; + } readings[1]; +}; + +/** + * Data from a sensor where we only care about a event occurring. + * + * This is a bit unusual in that our readings have no data in addition + * to the timestamp. But since we only care about the occurrence, we + * don't need to know anything else. + * + * Used by: CHRE_EVENT_SENSOR_INSTANT_MOTION_DETECT_DATA, + * CHRE_EVENT_SENSOR_STATIONARY_DETECT_DATA, + * CHRE_EVENT_SENSOR_STEP_DETECT_DATA, and + * CHRE_EVENT_SENSOR_SIGNIFICANT_MOTION_DATA. + */ +struct chreSensorOccurrenceData { + struct chreSensorDataHeader header; + struct chreSensorOccurrenceSampleData { + uint32_t timestampDelta; + // This space intentionally left blank. + // Only the timestamp is meaningful here, there + // is no additional data. + } readings[1]; +}; + +/** + * This is used by CHRE_EVENT_SENSOR_LIGHT_DATA, + * CHRE_EVENT_SENSOR_PRESSURE_DATA, + * CHRE_EVENT_SENSOR_ACCELEROMETER_TEMPERATURE_DATA, + * CHRE_EVENT_SENSOR_GYROSCOPE_TEMPERATURE_DATA, + * CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_TEMPERATURE_DATA, and + * CHRE_EVENT_SENSOR_HINGE_ANGLE_DATA. + */ +struct chreSensorFloatData { + struct chreSensorDataHeader header; + struct chreSensorFloatSampleData { + uint32_t timestampDelta; + union { + float value; + float light; //!< Unit: lux + float pressure; //!< Unit: hectopascals (hPa) + float temperature; //!< Unit: degrees Celsius + float angle; //!< Unit: angular degrees + }; + } readings[1]; +}; + +/** + * CHRE_EVENT_SENSOR_PROXIMITY_DATA. + */ +struct chreSensorByteData { + struct chreSensorDataHeader header; + struct chreSensorByteSampleData { + uint32_t timestampDelta; + union { + uint8_t value; + struct { + uint8_t isNear : 1; + //! @deprecated As of v1.2, this field is deprecated and must + //! always be set to 0 + uint8_t invalid : 1; + uint8_t padding0 : 6; + }; + }; + } readings[1]; +}; + +/** + * Data for a sensor which reports a single uint64 value. + * + * This is used by CHRE_EVENT_SENSOR_STEP_COUNTER_DATA. + */ +struct chreSensorUint64Data { + struct chreSensorDataHeader header; + struct chreSensorUint64SampleData { + uint32_t timestampDelta; + uint64_t value; + } readings[1]; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _CHRE_SENSOR_TYPES_H_ */
diff --git a/chre_api/legacy/v1_10/chre/toolchain.h b/chre_api/legacy/v1_10/chre/toolchain.h new file mode 100644 index 0000000..7c93bb1 --- /dev/null +++ b/chre_api/legacy/v1_10/chre/toolchain.h
@@ -0,0 +1,87 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// IWYU pragma: private, include "chre_api/chre.h" +// IWYU pragma: friend chre/.*\.h + +#ifndef CHRE_TOOLCHAIN_H_ +#define CHRE_TOOLCHAIN_H_ + +/** + * @file + * Compiler/build toolchain-specific macros used by the CHRE API + */ + +#if defined(__GNUC__) || defined(__clang__) +// For GCC and clang + +#define CHRE_DEPRECATED(message) \ + __attribute__((deprecated(message))) + +// Indicates that the function does not return (i.e. abort). +#define CHRE_NO_RETURN __attribute__((noreturn)) + +// Enable printf-style compiler warnings for mismatched format string and args +#define CHRE_PRINTF_ATTR(formatPos, argStart) \ + __attribute__((format(printf, formatPos, argStart))) + +#define CHRE_BUILD_ERROR(message) CHRE_DO_PRAGMA(GCC error message) +#define CHRE_DO_PRAGMA(message) _Pragma(#message) + +// Marks a function as malloc-like, for optimizations with the return pointer +#define CHRE_MALLOC_ATTR __attribute__((__malloc__)) + +#elif defined(__ICCARM__) || defined(__CC_ARM) +// For IAR ARM and Keil MDK-ARM compilers + +#define CHRE_PRINTF_ATTR(formatPos, argStart) + +#define CHRE_DEPRECATED(message) + +#define CHRE_NO_RETURN + +#define CHRE_MALLOC_ATTR + +#elif defined(_MSC_VER) +// For Microsoft Visual Studio + +#define CHRE_PRINTF_ATTR(formatPos, argStart) + +#define CHRE_DEPRECATED(message) + +#define CHRE_NO_RETURN + +#define CHRE_MALLOC_ATTR + +#else // if !defined(__GNUC__) && !defined(__clang__) + +#error Need to add support for new compiler + +#endif + +// For platforms that don't support error pragmas, utilize the best method of +// showing an error depending on the platform support. +#ifndef CHRE_BUILD_ERROR +#ifdef __cplusplus // C++17 or greater assumed +#define CHRE_BUILD_ERROR(message) static_assert(0, message) +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +#define CHRE_BUILD_ERROR(message) _Static_assert(0, message) +#else +#define CHRE_BUILD_ERROR(message) char buildError[-1] = message +#endif +#endif + +#endif // CHRE_TOOLCHAIN_H_
diff --git a/chre_api/legacy/v1_10/chre/user_settings.h b/chre_api/legacy/v1_10/chre/user_settings.h new file mode 100644 index 0000000..a13290d --- /dev/null +++ b/chre_api/legacy/v1_10/chre/user_settings.h
@@ -0,0 +1,148 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// IWYU pragma: private, include "chre_api/chre.h" +// IWYU pragma: friend chre/.*\.h + +#ifndef _CHRE_USER_SETTINGS_H_ +#define _CHRE_USER_SETTINGS_H_ + +/** + * @file + * The API for requesting notifications on changes in the settings of the + * active user. If the device is set up with one or more secondary users + * (see https://source.android.com/devices/tech/admin/multi-user), the user + * settings in CHRE reflect that of the currently active user. + */ + +#include <stdbool.h> +#include <stdint.h> + +#include <chre/event.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The user settings that nanoapps can request notifications for on a status + * change. + * + * NOTE: The WIFI available setting indicates the overall availability + * of WIFI related functionality. For example, if wifi is disabled for + * connectivity but enabled for location, the WIFI available setting is + * enabled. + * + * NOTE: The BLE available setting is the logical OR of the main Bluetooth + * setting and the Bluetooth scanning setting found under Location settings. + * Note that this indicates whether the user is allowing Bluetooth to be used, + * however the system may still fully power down the BLE chip in some scenarios + * if no request for it exists on the Android host side. See the + * chreBleStartScanAsync() API documentation for more information. + * + * @defgroup CHRE_USER_SETTINGS + * @{ + */ +#define CHRE_USER_SETTING_LOCATION UINT8_C(0) +#define CHRE_USER_SETTING_WIFI_AVAILABLE UINT8_C(1) +#define CHRE_USER_SETTING_AIRPLANE_MODE UINT8_C(2) +#define CHRE_USER_SETTING_MICROPHONE UINT8_C(3) +#define CHRE_USER_SETTING_BLE_AVAILABLE UINT8_C(4) + +/** @} */ + +/** + * Produce an event ID in the block of IDs reserved for settings notifications. + * + * @param offset Index into the event ID block, valid in the range [0,15] + */ +#define CHRE_SETTING_EVENT_ID(offset) (CHRE_EVENT_SETTING_CHANGED_FIRST_EVENT + (offset)) + +/** + * nanoappHandleEvent argument: struct chreUserSettingChangedEvent + * + * Notify nanoapps of a change in the associated setting. Nanoapps must first + * register (via chreUserSettingConfigureEvents) for events before they are + * sent out. + */ +#define CHRE_EVENT_SETTING_CHANGED_LOCATION CHRE_SETTING_EVENT_ID(0) +#define CHRE_EVENT_SETTING_CHANGED_WIFI_AVAILABLE CHRE_SETTING_EVENT_ID(1) +#define CHRE_EVENT_SETTING_CHANGED_AIRPLANE_MODE CHRE_SETTING_EVENT_ID(2) +#define CHRE_EVENT_SETTING_CHANGED_MICROPHONE CHRE_SETTING_EVENT_ID(3) +#define CHRE_EVENT_SETTING_CHANGED_BLE_AVAILABLE CHRE_SETTING_EVENT_ID(4) + +#if CHRE_EVENT_SETTING_CHANGED_BLE_AVAILABLE > CHRE_EVENT_SETTING_CHANGED_LAST_EVENT +#error Too many setting changed events. +#endif + +/** + * Indicates the current state of a setting. + * The setting state is 'unknown' only in the following scenarios: + * - CHRE hasn't received the initial state yet on a restart. + * - The nanoapp is running on CHRE v1.4 or older + * - Nanoapp provided in invalid setting ID to chreUserSettingGetStatus. + */ +enum chreUserSettingState { + CHRE_USER_SETTING_STATE_UNKNOWN = -1, + CHRE_USER_SETTING_STATE_DISABLED = 0, + CHRE_USER_SETTING_STATE_ENABLED = 1 +}; + +/** + * The nanoappHandleEvent argument for CHRE settings changed notifications. + */ +struct chreUserSettingChangedEvent { + //! Indicates the setting whose state has changed. + uint8_t setting; + + //! A value that corresponds to a member in enum chreUserSettingState, + // indicating the latest value of the setting. + int8_t settingState; +}; + +/** + * Get the current state of a given setting. + * + * @param setting The setting to get the current status of. + * + * @return The current state of the requested setting. The state is returned + * as an int8_t to be consistent with the associated event data, but is + * guaranteed to be a valid enum chreUserSettingState member. + * + * @since v1.5 + */ +int8_t chreUserSettingGetState(uint8_t setting); + +/** + * Register or deregister for a notification on a status change for a given + * setting. Note that registration does not produce an event with the initial + * (or current) state, though nanoapps can use chreUserSettingGetState() for + * this purpose. + * + * @param setting The setting on whose change a notification is desired. + * @param enable The nanoapp is registered to receive notifications on a + * change in the user settings if this parameter is true, otherwise the + * nanoapp receives no further notifications for this setting. + * + * @since v1.5 + */ +void chreUserSettingConfigureEvents(uint8_t setting, bool enable); + +#ifdef __cplusplus +} +#endif + +#endif /* _CHRE_USER_SETTINGS_H_ */
diff --git a/chre_api/legacy/v1_10/chre/version.h b/chre_api/legacy/v1_10/chre/version.h new file mode 100644 index 0000000..8f4e3d6 --- /dev/null +++ b/chre_api/legacy/v1_10/chre/version.h
@@ -0,0 +1,284 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// IWYU pragma: private, include "chre_api/chre.h" +// IWYU pragma: friend chre/.*\.h + +#ifndef _CHRE_VERSION_H_ +#define _CHRE_VERSION_H_ + +/** + * @file + * Definitions and methods for the versioning of the Context Hub Runtime + * Environment. + * + * The CHRE API versioning pertains to all header files in the CHRE API. + */ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Value for version 0.1 of the Context Hub Runtime Environment API interface. + * + * This is a legacy version of the CHRE API. Version 1.0 is considered the first + * official CHRE API version. + * + * @see CHRE_API_VERSION + */ +#define CHRE_API_VERSION_0_1 UINT32_C(0x00010000) + +/** + * Value for version 1.0 of the Context Hub Runtime Environment API interface. + * + * This version of the CHRE API shipped with the Android Nougat release. + * + * @see CHRE_API_VERSION + */ +#define CHRE_API_VERSION_1_0 UINT32_C(0x01000000) + +/** + * Value for version 1.1 of the Context Hub Runtime Environment API interface. + * + * This version of the CHRE API shipped with the Android O release. It adds + * initial support for new GNSS, WiFi, and WWAN modules. + * + * @see CHRE_API_VERSION + */ +#define CHRE_API_VERSION_1_1 UINT32_C(0x01010000) + +/** + * Value for version 1.2 of the Context Hub Runtime Environment API interface. + * + * This version of the CHRE API shipped with the Android P release. It adds + * initial support for the new audio module. + * + * @see CHRE_API_VERSION + */ +#define CHRE_API_VERSION_1_2 UINT32_C(0x01020000) + +/** + * Value for version 1.3 of the Context Hub Runtime Environment API interface. + * + * This version of the CHRE API shipped with the Android Q release. It adds + * support for GNSS location altitude/speed/bearing accuracy. It also adds step + * detect as a standard CHRE sensor and supports bias event delivery and sensor + * data flushing. + * + * @see CHRE_API_VERSION + */ +#define CHRE_API_VERSION_1_3 UINT32_C(0x01030000) + +/** + * Value for version 1.4 of the Context Hub Runtime Environment API interface. + * + * This version of the CHRE API shipped with the Android R release. It adds + * support for collecting debug dump information from nanoapps, receiving L5 + * GNSS measurements, determining if a sensor supports passive requests, + * receiving 5G cell info, and deprecates chreSendMessageToHost. + * + * @see CHRE_API_VERSION + */ +#define CHRE_API_VERSION_1_4 UINT32_C(0x01040000) + +/** + * Value for version 1.5 of the Context Hub Runtime Environment API interface. + * + * This version of the CHRE API shipped with the Android S release. It adds + * support for multiple sensors of the same type, permissions for sensitive CHRE + * APIs / data usage, ability to receive user settings updates, step counter and + * hinge angle sensors, improved WiFi scan preferences to support power + * optimization, new WiFi security types, increased the lower bound for the + * maximum CHRE to host message size, and increased GNSS measurements in + * chreGnssDataEvent. + * + * @see CHRE_API_VERSION + */ +#define CHRE_API_VERSION_1_5 UINT32_C(0x01050000) + +/** + * Value for version 1.6 of the Context Hub Runtime Environment API interface. + * + * This version of the CHRE API is shipped with the Android T release. It adds + * support for BLE scanning, subscribing to the WiFi NAN discovery engine, + * subscribing to host endpoint notifications, requesting metadata for a host + * endpoint ID, nanoapps publishing RPC services they support, and limits the + * nanoapp instance ID size to INT16_MAX. + * + * @see CHRE_API_VERSION + */ +#define CHRE_API_VERSION_1_6 UINT32_C(0x01060000) + +/** + * Value for version 1.7 of the Context Hub Runtime Environment API interface. + * + * This version of the CHRE API is shipped with a post-launch update to the + * Android T release. It adds the BLE flush API. + * + * @see CHRE_API_VERSION + */ +#define CHRE_API_VERSION_1_7 UINT32_C(0x01070000) + +/** + * Value for version 1.8 of the Context Hub Runtime Environment API interface. + * + * This version of the CHRE API is shipped with the Android U release. It adds + * support for filtering by manufacturer data in BLE scans, reading the RSSI + * value of a BLE connection, allowing the nanoapp to check BLE scan status, + * allowing the nanoapp to specify which RPC services it supports, and + * delivering batch complete events for batched BLE scans. + * + * @see CHRE_API_VERSION + */ +#define CHRE_API_VERSION_1_8 UINT32_C(0x01080000) + +/** + * Value for version 1.9 of the Context Hub Runtime Environment API interface. + * + * This version of the CHRE API is shipped with a post-launch update to the + * Android U release. It adds the BLE Broadcaster Address filter. + * + * @see CHRE_API_VERSION + */ +#define CHRE_API_VERSION_1_9 UINT32_C(0x01090000) + +/** + * Value for version 1.10 of the Context Hub Runtime Environment API interface. + * + * This version of the CHRE API is shipped with Android V. It adds support for + * reliable messaging. + * + * @note This version of the CHRE API has not been finalized yet, and is + * currently considered a preview that is subject to change. + * + * @see CHRE_API_VERSION + */ +#define CHRE_API_VERSION_1_10 UINT32_C(0x010a0000) + +/** + * Major and Minor Version of this Context Hub Runtime Environment API. + * + * The major version changes when there is an incompatible API change. + * + * The minor version changes when there is an addition in functionality + * in a backwards-compatible manner. + * + * We define the version number as an unsigned 32-bit value. The most + * significant byte is the Major Version. The second-most significant byte + * is the Minor Version. The two least significant bytes are the Patch + * Version. The Patch Version is not defined by this header API, but + * is provided by a specific CHRE implementation (see chreGetVersion()). + * + * Note that version numbers can always be numerically compared with + * expected results, so 1.0.0 < 1.0.4 < 1.1.0 < 2.0.300 < 3.5.0. + */ +#define CHRE_API_VERSION CHRE_API_VERSION_1_10 + +/** + * Utility macro to extract only the API major version of a composite CHRE + * version. + * + * @param version A uint32_t version, e.g. the value returned by + * chreGetApiVersion() + * + * @return The API major version in the least significant byte, e.g. 0x01 + */ +#define CHRE_EXTRACT_MAJOR_VERSION(version) \ + (uint32_t)(((version) & UINT32_C(0xFF000000)) >> 24) + +/** + * Utility macro to extract only the API minor version of a composite CHRE + * version. + * + * @param version A uint32_t version, e.g. the CHRE_API_VERSION constant + * + * @return The API minor version in the least significant byte, e.g. 0x01 + */ +#define CHRE_EXTRACT_MINOR_VERSION(version) \ + (uint32_t)(((version) & UINT32_C(0x00FF0000)) >> 16) + +/** + * Utility macro to extract only the API minor version of a composite CHRE + * version. + * + * @param version A complete uint32_t version, e.g. the value returned by + * chreGetVersion() + * + * @return The implementation patch version in the least significant two bytes, + * e.g. 0x0123, with all other bytes set to 0 + */ +#define CHRE_EXTRACT_PATCH_VERSION(version) (uint32_t)((version) & UINT32_C(0xFFFF)) + +/** + * Get the API version the CHRE implementation was compiled against. + * + * This is not necessarily the CHRE_API_VERSION in the header the nanoapp was + * built against, and indeed may not have even appeared in the context_hub_os.h + * header which this nanoapp was built against. + * + * By definition, this will have the two least significant bytes set to 0, + * and only contain the major and minor version number. + * + * @return The API version. + */ +uint32_t chreGetApiVersion(void); + +/** + * Get the version of this CHRE implementation. + * + * By definition, ((chreGetApiVersion() & UINT32_C(0xFFFF0000)) == + * (chreGetVersion() & UINT32_C(0xFFFF0000))). + * + * The Patch Version, in the lower two bytes, only have meaning in context + * of this specific platform ID. It is increased by the platform every time + * a backwards-compatible bug fix is released. + * + * @return The version. + * + * @see chreGetPlatformId() + */ +uint32_t chreGetVersion(void); + +/** + * Get the Platform ID of this CHRE. + * + * The most significant five bytes are the vendor ID as set out by the + * NANOAPP_VENDOR convention in the original context hub HAL header file + * (context_hub.h), also used by nanoapp IDs. + * + * The least significant three bytes are set by the vendor, but must be + * unique for each different CHRE implementation/hardware that the vendor + * supplies. + * + * The idea is that in the case of known bugs in the field, a new nanoapp could + * be shipped with a workaround that would use this value, and chreGetVersion(), + * to have code that can conditionally work around the bug on a buggy version. + * Thus, we require this uniqueness to allow such a setup to work. + * + * @return The platform ID. + * + * @see CHRE_EXTRACT_VENDOR_ID + */ +uint64_t chreGetPlatformId(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _CHRE_VERSION_H_ */
diff --git a/chre_api/legacy/v1_10/chre/wifi.h b/chre_api/legacy/v1_10/chre/wifi.h new file mode 100644 index 0000000..44d3d41 --- /dev/null +++ b/chre_api/legacy/v1_10/chre/wifi.h
@@ -0,0 +1,1318 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// IWYU pragma: private, include "chre_api/chre.h" +// IWYU pragma: friend chre/.*\.h + +#ifndef _CHRE_WIFI_H_ +#define _CHRE_WIFI_H_ + +/** + * @file + * WiFi (IEEE 802.11) API, currently covering scanning features useful for + * determining location and offloading certain connectivity scans. + * + * In this file, specification references use the following shorthand: + * + * Shorthand | Full specification name + * ---------- | ------------------------ + * "802.11" | IEEE Std 802.11-2007 + * "HT" | IEEE Std 802.11n-2009 + * "VHT" | IEEE Std 802.11ac-2013 + * "WiFi 6" | IEEE Std 802.11ax draft + * "NAN" | Wi-Fi Neighbor Awareness Networking (NAN) Technical + * Specification (v3.2) + * + * In the current version of CHRE API, the 6GHz band introduced in WiFi 6 is + * not supported. A scan request from CHRE should not result in scanning 6GHz + * channels. In particular, if a 6GHz channel is specified in scanning or + * ranging request parameter, CHRE should return an error code of + * CHRE_ERROR_NOT_SUPPORTED. Additionally, CHRE implementations must not include + * observations of access points on 6GHz channels in scan results, especially + * those produced due to scan monitoring. + */ + +#include "common.h" +#include <chre/common.h> + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The set of flags returned by chreWifiGetCapabilities(). + * @defgroup CHRE_WIFI_CAPABILITIES + * @{ + */ + +//! No WiFi APIs are supported +#define CHRE_WIFI_CAPABILITIES_NONE UINT32_C(0) + +//! Listening to scan results is supported, as enabled via +//! chreWifiConfigureScanMonitorAsync() +#define CHRE_WIFI_CAPABILITIES_SCAN_MONITORING UINT32_C(1 << 0) + +//! Requesting WiFi scans on-demand is supported via chreWifiRequestScanAsync() +#define CHRE_WIFI_CAPABILITIES_ON_DEMAND_SCAN UINT32_C(1 << 1) + +//! Specifying the radio chain preference in on-demand scan requests, and +//! reporting it in scan events is supported +//! @since v1.2 +#define CHRE_WIFI_CAPABILITIES_RADIO_CHAIN_PREF UINT32_C(1 << 2) + +//! Requesting RTT ranging is supported via chreWifiRequestRangingAsync() +//! @since v1.2 +#define CHRE_WIFI_CAPABILITIES_RTT_RANGING UINT32_C(1 << 3) + +//! Specifies if WiFi NAN service subscription is supported. If a platform +//! supports subscriptions, then it must also support RTT ranging for NAN +//! services via chreWifiNanRequestRangingAsync() +//! @since v1.6 +#define CHRE_WIFI_CAPABILITIES_NAN_SUB UINT32_C(1 << 4) + +/** @} */ + +/** + * Produce an event ID in the block of IDs reserved for WiFi + * @param offset Index into WiFi event ID block; valid range [0,15] + */ +#define CHRE_WIFI_EVENT_ID(offset) (CHRE_EVENT_WIFI_FIRST_EVENT + (offset)) + +/** + * nanoappHandleEvent argument: struct chreAsyncResult + * + * Communicates the asynchronous result of a request to the WiFi API. The + * requestType field in {@link #chreAsyncResult} is set to a value from enum + * chreWifiRequestType. + */ +#define CHRE_EVENT_WIFI_ASYNC_RESULT CHRE_WIFI_EVENT_ID(0) + +/** + * nanoappHandleEvent argument: struct chreWifiScanEvent + * + * Provides results of a WiFi scan. + */ +#define CHRE_EVENT_WIFI_SCAN_RESULT CHRE_WIFI_EVENT_ID(1) + +/** + * nanoappHandleEvent argument: struct chreWifiRangingEvent + * + * Provides results of an RTT ranging request. + */ +#define CHRE_EVENT_WIFI_RANGING_RESULT CHRE_WIFI_EVENT_ID(2) + +/** + * nanoappHandleEvent argument: struct chreWifiNanIdentifierEvent + * + * Lets the client know if the NAN engine was able to successfully assign + * an identifier to the subscribe call. The 'cookie' field in the event + * argument struct can be used to track which subscribe request this identifier + * maps to. + */ +#define CHRE_EVENT_WIFI_NAN_IDENTIFIER_RESULT CHRE_WIFI_EVENT_ID(3) + +/** + * nanoappHandleEvent argument: struct chreWifiNanDiscoveryEvent + * + * Event that is sent whenever a NAN service matches the criteria specified + * in a subscription request. + */ +#define CHRE_EVENT_WIFI_NAN_DISCOVERY_RESULT CHRE_WIFI_EVENT_ID(4) + +/** + * nanoappHandleEvent argument: struct chreWifiNanSessionLostEvent + * + * Informs the client that a discovered service is no longer available or + * visible. + * The ID of the service on the client that was communicating with the extinct + * service is indicated by the event argument. + */ +#define CHRE_EVENT_WIFI_NAN_SESSION_LOST CHRE_WIFI_EVENT_ID(5) + +/** + * nanoappHandleEvent argument: struct chreWifiNanSessionTerminatedEvent + * + * Signals the end of a NAN subscription session. The termination can be due to + * the user turning the WiFi off, or other platform reasons like not being able + * to support NAN concurrency with the host. The terminated event will have a + * reason code appropriately populated to denote why the event was sent. + */ +#define CHRE_EVENT_WIFI_NAN_SESSION_TERMINATED CHRE_WIFI_EVENT_ID(6) + +// NOTE: Do not add new events with ID > 15; only values 0-15 are reserved +// (see chre/event.h) + +/** + * The maximum amount of time that is allowed to elapse between a call to + * chreWifiRequestScanAsync() that returns true, and the associated + * CHRE_EVENT_WIFI_ASYNC_RESULT used to indicate whether the scan completed + * successfully or not. + */ +#define CHRE_WIFI_SCAN_RESULT_TIMEOUT_NS (30 * CHRE_NSEC_PER_SEC) + +/** + * The maximum amount of time that is allowed to elapse between a call to + * chreWifiRequestRangingAsync() that returns true, and the associated + * CHRE_EVENT_WIFI_RANGING_RESULT used to indicate whether the ranging operation + * completed successfully or not. + */ +#define CHRE_WIFI_RANGING_RESULT_TIMEOUT_NS (30 * CHRE_NSEC_PER_SEC) + +/** + * The current compatibility version of the chreWifiScanEvent structure, + * including nested structures. + */ +#define CHRE_WIFI_SCAN_EVENT_VERSION UINT8_C(1) + +/** + * The current compatibility version of the chreWifiRangingEvent structure, + * including nested structures. + */ +#define CHRE_WIFI_RANGING_EVENT_VERSION UINT8_C(0) + +/** + * Maximum number of frequencies that can be explicitly specified when + * requesting a scan + * @see #chreWifiScanParams + */ +#define CHRE_WIFI_FREQUENCY_LIST_MAX_LEN (20) + +/** + * Maximum number of SSIDs that can be explicitly specified when requesting a + * scan + * @see #chreWifiScanParams + */ +#define CHRE_WIFI_SSID_LIST_MAX_LEN (20) + +/** + * The maximum number of devices that can be specified in a single RTT ranging + * request. + * @see #chreWifiRangingParams + */ +#define CHRE_WIFI_RANGING_LIST_MAX_LEN (10) + +/** + * The maximum number of octets in an SSID (see 802.11 7.3.2.1) + */ +#define CHRE_WIFI_SSID_MAX_LEN (32) + +/** + * The number of octets in a BSSID (see 802.11 7.1.3.3.3) + */ +#define CHRE_WIFI_BSSID_LEN (6) + +/** + * Set of flags which can either indicate a frequency band. Specified as a bit + * mask to allow for combinations in future API versions. + * @defgroup CHRE_WIFI_BAND_MASK + * @{ + */ + +#define CHRE_WIFI_BAND_MASK_2_4_GHZ UINT8_C(1 << 0) //!< 2.4 GHz +#define CHRE_WIFI_BAND_MASK_5_GHZ UINT8_C(1 << 1) //!< 5 GHz + +/** @} */ + +/** + * Characteristics of a scanned device given in struct chreWifiScanResult.flags + * @defgroup CHRE_WIFI_SCAN_RESULT_FLAGS + * @{ + */ + +#define CHRE_WIFI_SCAN_RESULT_FLAGS_NONE UINT8_C(0) + +//! Element ID 61 (HT Operation) is present (see HT 7.3.2) +#define CHRE_WIFI_SCAN_RESULT_FLAGS_HT_OPS_PRESENT UINT8_C(1 << 0) + +//! Element ID 192 (VHT Operation) is present (see VHT 8.4.2) +#define CHRE_WIFI_SCAN_RESULT_FLAGS_VHT_OPS_PRESENT UINT8_C(1 << 1) + +//! Element ID 127 (Extended Capabilities) is present, and bit 70 (Fine Timing +//! Measurement Responder) is set to 1 (see IEEE Std 802.11-2016 9.4.2.27) +#define CHRE_WIFI_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER UINT8_C(1 << 2) + +//! Retained for backwards compatibility +//! @see CHRE_WIFI_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER +#define CHRE_WIFI_SCAN_RESULT_FLAGS_IS_80211MC_RTT_RESPONDER \ + CHRE_WIFI_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER + +//! HT Operation element indicates that a secondary channel is present +//! (see HT 7.3.2.57) +#define CHRE_WIFI_SCAN_RESULT_FLAGS_HAS_SECONDARY_CHANNEL_OFFSET UINT8_C(1 << 3) + +//! HT Operation element indicates that the secondary channel is below the +//! primary channel (see HT 7.3.2.57) +#define CHRE_WIFI_SCAN_RESULT_FLAGS_SECONDARY_CHANNEL_OFFSET_IS_BELOW \ + UINT8_C(1 << 4) + +/** @} */ + +/** + * Identifies the authentication methods supported by an AP. Note that not every + * combination of flags may be possible. Based on WIFI_PNO_AUTH_CODE_* from + * hardware/libhardware_legacy/include/hardware_legacy/gscan.h in Android. + * @defgroup CHRE_WIFI_SECURITY_MODE_FLAGS + * @{ + */ + +#define CHRE_WIFI_SECURITY_MODE_UNKNOWN UINT8_C(0) +//! @deprecated since v1.10. Use CHRE_WIFI_SECURITY_MODE_UNKNOWN instead. +#define CHRE_WIFI_SECURITY_MODE_UNKONWN CHRE_WIFI_SECURITY_MODE_UNKNOWN + +#define CHRE_WIFI_SECURITY_MODE_OPEN UINT8_C(1 << 0) //!< No auth/security +#define CHRE_WIFI_SECURITY_MODE_WEP UINT8_C(1 << 1) +#define CHRE_WIFI_SECURITY_MODE_PSK UINT8_C(1 << 2) //!< WPA-PSK or WPA2-PSK +#define CHRE_WIFI_SECURITY_MODE_EAP UINT8_C(1 << 3) //!< WPA-EAP or WPA2-EAP + +//! @since v1.5 +#define CHRE_WIFI_SECURITY_MODE_SAE UINT8_C(1 << 4) + +//! @since v1.5 +#define CHRE_WIFI_SECURITY_MODE_EAP_SUITE_B UINT8_C(1 << 5) + +//! @since v1.5 +#define CHRE_WIFI_SECURITY_MODE_OWE UINT8_C(1 << 6) + +/** @} */ + +/** + * Identifies which radio chain was used to discover an AP. The underlying + * hardware does not necessarily support more than one radio chain. + * @defgroup CHRE_WIFI_RADIO_CHAIN_FLAGS + * @{ + */ + +#define CHRE_WIFI_RADIO_CHAIN_UNKNOWN UINT8_C(0) +#define CHRE_WIFI_RADIO_CHAIN_0 UINT8_C(1 << 0) +#define CHRE_WIFI_RADIO_CHAIN_1 UINT8_C(1 << 1) + +/** @} */ + +//! Special value indicating that an LCI uncertainty fields is not provided +//! Ref: RFC 6225 +#define CHRE_WIFI_LCI_UNCERTAINTY_UNKNOWN UINT8_C(0) + +/** + * Defines the flags that may be returned in + * {@link #chreWifiRangingResult.flags}. Undefined bits are reserved for future + * use and must be ignored by nanoapps. + * @defgroup CHRE_WIFI_RTT_RESULT_FLAGS + * @{ + */ + +//! If set, the nested chreWifiLci structure is populated; otherwise it is +//! invalid and must be ignored +#define CHRE_WIFI_RTT_RESULT_HAS_LCI UINT8_C(1 << 0) + +/** @} */ + +/** + * Identifies a WiFi frequency band + */ +enum chreWifiBand { + CHRE_WIFI_BAND_2_4_GHZ = CHRE_WIFI_BAND_MASK_2_4_GHZ, + CHRE_WIFI_BAND_5_GHZ = CHRE_WIFI_BAND_MASK_5_GHZ, +}; + +/** + * Indicates the BSS operating channel width determined from the VHT and/or HT + * Operation elements. Refer to VHT 8.4.2.161 and HT 7.3.2.57. + */ +enum chreWifiChannelWidth { + CHRE_WIFI_CHANNEL_WIDTH_20_MHZ = 0, + CHRE_WIFI_CHANNEL_WIDTH_40_MHZ = 1, + CHRE_WIFI_CHANNEL_WIDTH_80_MHZ = 2, + CHRE_WIFI_CHANNEL_WIDTH_160_MHZ = 3, + CHRE_WIFI_CHANNEL_WIDTH_80_PLUS_80_MHZ = 4, +}; + +/** + * Indicates the type of scan requested or performed + */ +enum chreWifiScanType { + //! Perform a purely active scan using probe requests. Do not scan channels + //! restricted to use via Dynamic Frequency Selection (DFS) only. + CHRE_WIFI_SCAN_TYPE_ACTIVE = 0, + + //! Perform an active scan on unrestricted channels, and also perform a + //! passive scan on channels that are restricted to use via Dynamic + //! Frequency Selection (DFS), e.g. the U-NII bands 5250-5350MHz and + //! 5470-5725MHz in the USA as mandated by FCC regulation. + CHRE_WIFI_SCAN_TYPE_ACTIVE_PLUS_PASSIVE_DFS = 1, + + //! Perform a passive scan, only listening for beacons. + CHRE_WIFI_SCAN_TYPE_PASSIVE = 2, + + //! Client has no preference for a particular scan type. + //! Only valid in a {@link #chreWifiScanParams}. + //! + //! On a v1.4 or earlier platform, this will fall back to + //! CHRE_WIFI_SCAN_TYPE_ACTIVE if {@link #chreWifiScanParams.channelSet} is + //! set to CHRE_WIFI_CHANNEL_SET_NON_DFS, and to + //! CHRE_WIFI_SCAN_TYPE_ACTIVE_PLUS_PASSIVE_DFS otherwise. + //! + //! If CHRE_WIFI_CAPABILITIES_RADIO_CHAIN_PREF is supported, a v1.5 or + //! later platform shall perform a type of scan optimized for {@link + //! #chreWifiScanParams.radioChainPref}. + //! + //! Clients are strongly encouraged to set this value in {@link + //! #chreWifiScanParams.scanType} and instead express their preferences + //! through {@link #chreWifiRadioChainPref} and {@link #chreWifiChannelSet} + //! so the platform can best optimize power and performance. + //! + //! @since v1.5 + CHRE_WIFI_SCAN_TYPE_NO_PREFERENCE = 3, +}; + +/** + * Indicates whether RTT ranging with a specific device succeeded + */ +enum chreWifiRangingStatus { + //! Ranging completed successfully + CHRE_WIFI_RANGING_STATUS_SUCCESS = 0, + + //! Ranging failed due to an unspecified error + CHRE_WIFI_RANGING_STATUS_ERROR = 1, +}; + +/** + * Possible values for {@link #chreWifiLci.altitudeType}. Ref: RFC 6225 2.4 + */ +enum chreWifiLciAltitudeType { + CHRE_WIFI_LCI_ALTITUDE_TYPE_UNKNOWN = 0, + CHRE_WIFI_LCI_ALTITUDE_TYPE_METERS = 1, + CHRE_WIFI_LCI_ALTITUDE_TYPE_FLOORS = 2, +}; + +/** + * Indicates a type of request made in this API. Used to populate the resultType + * field of struct chreAsyncResult sent with CHRE_EVENT_WIFI_ASYNC_RESULT. + */ +enum chreWifiRequestType { + CHRE_WIFI_REQUEST_TYPE_CONFIGURE_SCAN_MONITOR = 1, + CHRE_WIFI_REQUEST_TYPE_REQUEST_SCAN = 2, + CHRE_WIFI_REQUEST_TYPE_RANGING = 3, + CHRE_WIFI_REQUEST_TYPE_NAN_SUBSCRIBE = 4, +}; + +/** + * Allows a nanoapp to express its preference for how multiple available + * radio chains should be used when performing an on-demand scan. This is only a + * preference from the nanoapp and is not guaranteed to be honored by the WiFi + * firmware. + */ +enum chreWifiRadioChainPref { + //! No preference for radio chain usage + CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT = 0, + + //! In a scan result, indicates that the radio chain preference used for the + //! scan is not known + CHRE_WIFI_RADIO_CHAIN_PREF_UNKNOWN = CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT, + + //! Prefer to use available radio chains in a way that minimizes time to + //! complete the scan + CHRE_WIFI_RADIO_CHAIN_PREF_LOW_LATENCY = 1, + + //! Prefer to use available radio chains in a way that minimizes total power + //! consumed for the scan + CHRE_WIFI_RADIO_CHAIN_PREF_LOW_POWER = 2, + + //! Prefer to use available radio chains in a way that maximizes accuracy of + //! the scan result, e.g. RSSI measurements + CHRE_WIFI_RADIO_CHAIN_PREF_HIGH_ACCURACY = 3, +}; + +/** + * WiFi NAN subscription type. + */ +enum chreWifiNanSubscribeType { + //! In the active mode, explicit transmission of a subscribe message is + //! requested, and publish messages are processed. + CHRE_WIFI_NAN_SUBSCRIBE_TYPE_ACTIVE = 0, + + //! In the passive mode, no transmission of a subscribe message is + //! requested, but received publish messages are checked for matches. + CHRE_WIFI_NAN_SUBSCRIBE_TYPE_PASSIVE = 1, +}; + +/** + * Indicates the reason for a subscribe session termination. + */ +enum chreWifiNanTerminatedReason { + CHRE_WIFI_NAN_TERMINATED_BY_USER_REQUEST = 0, + CHRE_WIFI_NAN_TERMINATED_BY_TIMEOUT = 1, + CHRE_WIFI_NAN_TERMINATED_BY_FAILURE = 2, +}; + +/** + * SSID with an explicit length field, used when an array of SSIDs is supplied. + */ +struct chreWifiSsidListItem { + //! Number of valid bytes in ssid. Valid range [0, CHRE_WIFI_SSID_MAX_LEN] + uint8_t ssidLen; + + //! Service Set Identifier (SSID) + uint8_t ssid[CHRE_WIFI_SSID_MAX_LEN]; +}; + +/** + * Indicates the set of channels to be scanned. + * + * @since v1.5 + */ +enum chreWifiChannelSet { + //! The set of channels that allows active scan using probe request. + CHRE_WIFI_CHANNEL_SET_NON_DFS = 0, + + //! The set of all channels supported. + CHRE_WIFI_CHANNEL_SET_ALL = 1, +}; + +/** + * Data structure passed to chreWifiRequestScanAsync + */ +struct chreWifiScanParams { + //! Set to a value from @ref enum chreWifiScanType + uint8_t scanType; + + //! Indicates whether the client is willing to tolerate receiving cached + //! results of a previous scan, and if so, the maximum age of the scan that + //! the client will accept. "Age" in this case is defined as the elapsed + //! time between when the most recent scan was completed and the request is + //! received, in milliseconds. If set to 0, no cached results may be + //! provided, and all scan results must come from a "fresh" WiFi scan, i.e. + //! one that completes strictly after this request is received. If more than + //! one scan is cached and meets this age threshold, only the newest scan is + //! provided. + uint32_t maxScanAgeMs; + + //! If set to 0, scan all frequencies. Otherwise, this indicates the number + //! of frequencies to scan, as specified in the frequencyList array. Valid + //! range [0, CHRE_WIFI_FREQUENCY_LIST_MAX_LEN]. + uint16_t frequencyListLen; + + //! Pointer to an array of frequencies to scan, given as channel center + //! frequencies in MHz. This field may be NULL if frequencyListLen is 0. + const uint32_t *frequencyList; + + //! If set to 0, do not restrict scan to any SSIDs. Otherwise, this + //! indicates the number of SSIDs in the ssidList array to be used for + //! directed probe requests. Not applicable and ignore when scanType is + //! CHRE_WIFI_SCAN_TYPE_PASSIVE. + uint8_t ssidListLen; + + //! Pointer to an array of SSIDs to use for directed probe requests. May be + //! NULL if ssidListLen is 0. + const struct chreWifiSsidListItem *ssidList; + + //! Set to a value from enum chreWifiRadioChainPref to specify the desired + //! trade-off between power consumption, accuracy, etc. If + //! chreWifiGetCapabilities() does not have the applicable bit set, this + //! parameter is ignored. + //! @since v1.2 + uint8_t radioChainPref; + + //! Set to a value from enum chreWifiChannelSet to specify the set of + //! channels to be scanned. This field is considered by the platform only + //! if scanType is CHRE_WIFI_SCAN_TYPE_NO_PREFERENCE and frequencyListLen + //! is equal to zero. + //! + //! @since v1.5 + uint8_t channelSet; +}; + +/** + * Provides information about a single access point (AP) detected in a scan. + */ +struct chreWifiScanResult { + //! Number of milliseconds prior to referenceTime in the enclosing + //! chreWifiScanEvent struct when the probe response or beacon frame that + //! was used to populate this structure was received. + uint32_t ageMs; + + //! Capability Information field sent by the AP (see 802.11 7.3.1.4). This + //! field must reflect native byte order and bit ordering, such that + //! (capabilityInfo & 1) gives the bit for the ESS subfield. + uint16_t capabilityInfo; + + //! Number of valid bytes in ssid. Valid range [0, CHRE_WIFI_SSID_MAX_LEN] + uint8_t ssidLen; + + //! Service Set Identifier (SSID), a series of 0 to 32 octets identifying + //! the access point. Note that this is commonly a human-readable ASCII + //! string, but this is not the required encoding per the standard. + uint8_t ssid[CHRE_WIFI_SSID_MAX_LEN]; + + //! Basic Service Set Identifier (BSSID), represented in big-endian byte + //! order, such that the first octet of the OUI is accessed in byte index 0. + uint8_t bssid[CHRE_WIFI_BSSID_LEN]; + + //! A set of flags from CHRE_WIFI_SCAN_RESULT_FLAGS_* + uint8_t flags; + + //! RSSI (Received Signal Strength Indicator), in dBm. Typically negative. + //! If multiple radio chains were used to scan this AP, this is a "best + //! available" measure that may be a composite of measurements taken across + //! the radio chains. + int8_t rssi; + + //! Operating band, set to a value from enum chreWifiBand + uint8_t band; + + /** + * Indicates the center frequency of the primary 20MHz channel, given in + * MHz. This value is derived from the channel number via the formula: + * + * primaryChannel (MHz) = CSF + 5 * primaryChannelNumber + * + * Where CSF is the channel starting frequency (in MHz) given by the + * operating class/band (i.e. 2407 or 5000), and primaryChannelNumber is the + * channel number in the range [1, 200]. + * + * Refer to VHT 22.3.14. + */ + uint32_t primaryChannel; + + /** + * If the channel width is 20 MHz, this field is not relevant and set to 0. + * If the channel width is 40, 80, or 160 MHz, then this denotes the channel + * center frequency (in MHz). If the channel is 80+80 MHz, then this denotes + * the center frequency of segment 0, which contains the primary channel. + * This value is derived from the frequency index using the same formula as + * for primaryChannel. + * + * Refer to VHT 8.4.2.161, and VHT 22.3.14. + * + * @see #primaryChannel + */ + uint32_t centerFreqPrimary; + + /** + * If the channel width is 80+80MHz, then this denotes the center frequency + * of segment 1, which does not contain the primary channel. Otherwise, this + * field is not relevant and set to 0. + * + * @see #centerFreqPrimary + */ + uint32_t centerFreqSecondary; + + //! @see #chreWifiChannelWidth + uint8_t channelWidth; + + //! Flags from CHRE_WIFI_SECURITY_MODE_* indicating supported authentication + //! and associated security modes + //! @see CHRE_WIFI_SECURITY_MODE_FLAGS + uint8_t securityMode; + + //! Identifies the radio chain(s) used to discover this AP + //! @see CHRE_WIFI_RADIO_CHAIN_FLAGS + //! @since v1.2 + uint8_t radioChain; + + //! If the CHRE_WIFI_RADIO_CHAIN_0 bit is set in radioChain, gives the RSSI + //! measured on radio chain 0 in dBm; otherwise invalid and set to 0. This + //! field, along with its relative rssiChain1, can be used to determine RSSI + //! measurements from each radio chain when multiple chains were used to + //! discover this AP. + //! @see #radioChain + //! @since v1.2 + int8_t rssiChain0; + int8_t rssiChain1; //!< @see #rssiChain0 + + //! Reserved; set to 0 + uint8_t reserved[7]; +}; + +/** + * Data structure sent with events of type CHRE_EVENT_WIFI_SCAN_RESULT. + */ +struct chreWifiScanEvent { + //! Indicates the version of the structure, for compatibility purposes. + //! Clients do not normally need to worry about this field; the CHRE + //! implementation guarantees that the client only receives the structure + //! version it expects. + uint8_t version; + + //! The number of entries in the results array in this event. The CHRE + //! implementation may split scan results across multiple events for memory + //! concerns, etc. + uint8_t resultCount; + + //! The total number of results returned by the scan. Allows an event + //! consumer to identify when it has received all events associated with a + //! scan. + uint8_t resultTotal; + + //! Sequence number for this event within the series of events comprising a + //! complete scan result. Scan events are delivered strictly in order, i.e. + //! this is monotonically increasing for the results of a single scan. Valid + //! range [0, <number of events for scan> - 1]. The number of events for a + //! scan is typically given by + //! ceil(resultTotal / <max results per event supported by platform>). + uint8_t eventIndex; + + //! A value from enum chreWifiScanType indicating the type of scan performed + uint8_t scanType; + + //! If a directed scan was performed to a limited set of SSIDs, then this + //! identifies the number of unique SSIDs included in the probe requests. + //! Otherwise, this is set to 0, indicating that the scan was not limited by + //! SSID. Note that if this is non-zero, the list of SSIDs used is not + //! included in the scan event. + uint8_t ssidSetSize; + + //! If 0, indicates that all frequencies applicable for the scanType were + //! scanned. Otherwise, indicates the number of frequencies scanned, as + //! specified in scannedFreqList. + uint16_t scannedFreqListLen; + + //! Timestamp when the scan was completed, from the same time base as + //! chreGetTime() (in nanoseconds) + uint64_t referenceTime; + + //! Pointer to an array containing scannedFreqListLen values comprising the + //! set of frequencies that were scanned. Frequencies are specified as + //! channel center frequencies in MHz. May be NULL if scannedFreqListLen is + //! 0. + const uint32_t *scannedFreqList; + + //! Pointer to an array containing resultCount entries. May be NULL if + //! resultCount is 0. + const struct chreWifiScanResult *results; + + //! Set to a value from enum chreWifiRadioChainPref indicating the radio + //! chain preference used for the scan. If the applicable bit is not set in + //! chreWifiGetCapabilities(), this will always be set to + //! CHRE_WIFI_RADIO_CHAIN_PREF_UNKNOWN. + //! @since v1.2 + uint8_t radioChainPref; +}; + +/** + * Identifies a device to perform RTT ranging against. These values are normally + * populated based on the contents of a scan result. + * @see #chreWifiScanResult + * @see chreWifiRangingTargetFromScanResult() + */ +struct chreWifiRangingTarget { + //! Device MAC address, specified in the same byte order as + //! {@link #chreWifiScanResult.bssid} + uint8_t macAddress[CHRE_WIFI_BSSID_LEN]; + + //! Center frequency of the primary 20MHz channel, in MHz + //! @see #chreWifiScanResult.primaryChannel + uint32_t primaryChannel; + + //! Channel center frequency, in MHz, or 0 if not relevant + //! @see #chreWifiScanResult.centerFreqPrimary + uint32_t centerFreqPrimary; + + //! Channel center frequency of segment 1 if channel width is 80+80MHz, + //! otherwise 0 + //! @see #chreWifiScanResult.centerFreqSecondary + uint32_t centerFreqSecondary; + + //! @see #chreWifiChannelWidth + uint8_t channelWidth; + + //! Reserved for future use and ignored by CHRE + uint8_t reserved[3]; +}; + +/** + * Parameters for an RTT ("Fine Timing Measurement" in terms of 802.11-2016) + * ranging request, supplied to chreWifiRequestRangingAsync(). + */ +struct chreWifiRangingParams { + //! Number of devices to perform ranging against and the length of + //! targetList, in range [1, CHRE_WIFI_RANGING_LIST_MAX_LEN]. + uint8_t targetListLen; + + //! Array of macAddressListLen MAC addresses (e.g. BSSIDs) with which to + //! attempt RTT ranging. + const struct chreWifiRangingTarget *targetList; +}; + +/** + * Provides the result of RTT ranging with a single device. + */ +struct chreWifiRangingResult { + //! Time when the ranging operation on this device was performed, in the + //! same time base as chreGetTime() (in nanoseconds) + uint64_t timestamp; + + //! MAC address of the device for which ranging was requested + uint8_t macAddress[CHRE_WIFI_BSSID_LEN]; + + //! Gives the result of ranging to this device. If not set to + //! CHRE_WIFI_RANGING_STATUS_SUCCESS, the ranging attempt to this device + //! failed, and other fields in this structure may be invalid. + //! @see #chreWifiRangingStatus + uint8_t status; + + //! The mean RSSI measured during the RTT burst, in dBm. Typically negative. + //! If status is not CHRE_WIFI_RANGING_STATUS_SUCCESS, will be set to 0. + int8_t rssi; + + //! Estimated distance to the device with the given BSSID, in millimeters. + //! Generally the mean of multiple measurements performed in a single burst. + //! If status is not CHRE_WIFI_RANGING_STATUS_SUCCESS, will be set to 0. + uint32_t distance; + + //! Standard deviation of estimated distance across multiple measurements + //! performed in a single RTT burst, in millimeters. If status is not + //! CHRE_WIFI_RANGING_STATUS_SUCCESS, will be set to 0. + uint32_t distanceStdDev; + + //! Location Configuration Information (LCI) information optionally returned + //! during the ranging procedure. Only valid if {@link #flags} has the + //! CHRE_WIFI_RTT_RESULT_HAS_LCI bit set. Refer to IEEE 802.11-2016 + //! 9.4.2.22.10, 11.24.6.7, and RFC 6225 (July 2011) for more information. + //! Coordinates are to be interpreted according to the WGS84 datum. + struct chreWifiLci { + //! Latitude in degrees as 2's complement fixed-point with 25 fractional + //! bits, i.e. degrees * 2^25. Ref: RFC 6225 2.3 + int64_t latitude; + + //! Longitude, same format as {@link #latitude} + int64_t longitude; + + //! Altitude represented as a 2's complement fixed-point value with 8 + //! fractional bits. Interpretation depends on {@link #altitudeType}. If + //! UNKNOWN, this field must be ignored. If *METERS, distance relative + //! to the zero point in the vertical datum. If *FLOORS, a floor value + //! relative to the ground floor, potentially fractional, e.g. to + //! indicate mezzanine levels. Ref: RFC 6225 2.4 + int32_t altitude; + + //! Maximum extent of latitude uncertainty in degrees, decoded via this + //! formula: 2 ^ (8 - x) where "x" is the encoded value passed in this + //! field. Unknown if set to CHRE_WIFI_LCI_UNCERTAINTY_UNKNOWN. + //! Ref: RFC 6225 2.3.2 + uint8_t latitudeUncertainty; + + //! @see #latitudeUncertainty + uint8_t longitudeUncertainty; + + //! Defines how to interpret altitude, set to a value from enum + //! chreWifiLciAltitudeType + uint8_t altitudeType; + + //! Uncertainty in altitude, decoded via this formula: 2 ^ (21 - x) + //! where "x" is the encoded value passed in this field. Unknown if set + //! to CHRE_WIFI_LCI_UNCERTAINTY_UNKNOWN. Only applies when altitudeType + //! is CHRE_WIFI_LCI_ALTITUDE_TYPE_METERS. Ref: RFC 6225 2.4.5 + uint8_t altitudeUncertainty; + } lci; + + //! Refer to CHRE_WIFI_RTT_RESULT_FLAGS + uint8_t flags; + + //! Reserved; set to 0 + uint8_t reserved[7]; +}; + +/** + * Data structure sent with events of type CHRE_EVENT_WIFI_RANGING_RESULT. + */ +struct chreWifiRangingEvent { + //! Indicates the version of the structure, for compatibility purposes. + //! Clients do not normally need to worry about this field; the CHRE + //! implementation guarantees that the client only receives the structure + //! version it expects. + uint8_t version; + + //! The number of ranging results included in the results array; matches the + //! number of MAC addresses specified in the request + uint8_t resultCount; + + //! Reserved; set to 0 + uint8_t reserved[2]; + + //! Pointer to an array containing resultCount entries + const struct chreWifiRangingResult *results; +}; + +/** + * Indicates the WiFi NAN capabilities of the device. Must contain non-zero + * values if WiFi NAN is supported. + */ +struct chreWifiNanCapabilities { + //! Maximum length of the match filter arrays (applies to both tx and rx + //! match filters). + uint32_t maxMatchFilterLength; + + //! Maximum length of the service specific information byte array. + uint32_t maxServiceSpecificInfoLength; + + //! Maximum length of the service name. Includes the NULL terminator. + uint8_t maxServiceNameLength; + + //! Reserved for future use. + uint8_t reserved[3]; +}; + +/** + * Data structure sent with events of type + * CHRE_EVENT_WIFI_NAN_IDENTIFIER_RESULT + */ +struct chreWifiNanIdentifierEvent { + //! A unique ID assigned by the NAN engine for the subscribe request + //! associated with the cookie encapsulated in the async result below. The + //! ID is set to 0 if there was a request failure in which case the async + //! result below contains the appropriate error code indicating the failure + //! reason. + uint32_t id; + + //! Structure which contains the cookie associated with the publish/ + //! subscribe request, along with an error code that indicates request + //! success or failure. + struct chreAsyncResult result; +}; + +/** + * Indicates the desired configuration for a WiFi NAN ranging request. + */ +struct chreWifiNanRangingParams { + //! MAC address of the NAN device for which range is to be determined. + uint8_t macAddress[CHRE_WIFI_BSSID_LEN]; +}; + +/** + * Configuration parameters specific to the Subscribe Function (Spec 4.1.1.1) + */ +struct chreWifiNanSubscribeConfig { + //! Indicates the subscribe type, set to a value from @ref + //! chreWifiNanSubscribeType. + uint8_t subscribeType; + + //! UTF-8 name string that identifies the service/application. Must be NULL + //! terminated. Note that the string length cannot be greater than the + //! maximum length specified by @ref chreWifiNanCapabilities. No + //! restriction is placed on the string case, since the service name + //! matching is expected to be case insensitive. + const char *service; + + //! An array of bytes (and the associated array length) of service-specific + //! information. Note that the array length must be less than the + //! maxServiceSpecificInfoLength parameter obtained from the NAN + //! capabilities (@see struct chreWifiNanCapabilities). + const uint8_t *serviceSpecificInfo; + uint32_t serviceSpecificInfoSize; + + //! Ordered sequence of {length | value} pairs that specify match criteria + //! beyond the service name. 'length' uses 1 byte, and its value indicates + //! the number of bytes of the match criteria that follow. The length of + //! the match filter array should not exceed the maximum match filter + //! length obtained from @ref chreWifiNanGetCapabilities. When a service + //! publish message discovery frame containing the Service ID being + //! subscribed to is received, the matching is done as follows: + //! Each {length | value} pair in the kth position (1 <= k <= #length-value + //! pairs) is compared against the kth {length | value} pair in the + //! matching filter field of the publish message. + //! - For a kth position {length | value} pair in the rx match filter with + //! a length of 0, a match is declared regardless of the tx match filter + //! contents. + //! - For a kth position {length | value} pair in the rx match with a non- + //! zero length, there must be an exact match with the kth position pair + //! in the match filter field of the received service descriptor for a + //! match to be found. + //! Please refer to Appendix H of the NAN spec for examples on matching. + //! The match filter length should not exceed the maxMatchFilterLength + //! obtained from @ref chreWifiNanCapabilities. + const uint8_t *matchFilter; + uint32_t matchFilterLength; +}; + +/** + * Data structure sent with events of type + * CHRE_EVENT_WIFI_NAN_DISCOVERY_RESULT. + */ +struct chreWifiNanDiscoveryEvent { + //! Identifier of the subscribe function instance that requested a + //! discovery. + uint32_t subscribeId; + + //! Identifier of the publisher on the remote NAN device. + uint32_t publishId; + + //! NAN interface address of the publisher + uint8_t publisherAddress[CHRE_WIFI_BSSID_LEN]; + + //! An array of bytes (and the associated array length) of service-specific + //! information. Note that the array length must be less than the + //! maxServiceSpecificInfoLength parameter obtained from the NAN + //! capabilities (@see struct chreWifiNanCapabilities). + const uint8_t *serviceSpecificInfo; + uint32_t serviceSpecificInfoSize; +}; + +/** + * Data structure sent with events of type CHRE_EVENT_WIFI_NAN_SESSION_LOST. + */ +struct chreWifiNanSessionLostEvent { + //! The original ID (returned by the NAN discovery engine) of the subscriber + //! instance. + uint32_t id; + + //! The ID of the previously discovered publisher on a peer NAN device that + //! is no longer connected. + uint32_t peerId; +}; + +/** + * Data structure sent with events of type + * CHRE_EVENT_WIFI_NAN_SESSION_TERMINATED. + */ +struct chreWifiNanSessionTerminatedEvent { + //! The original ID (returned by the NAN discovery engine) of the subscriber + //! instance that was terminated. + uint32_t id; + + //! A value that maps to one of the termination reasons in @ref enum + //! chreWifiNanTerminatedReason. + uint8_t reason; + + //! Reserved for future use. + uint8_t reserved[3]; +}; + +/** + * Retrieves a set of flags indicating the WiFi features supported by the + * current CHRE implementation. The value returned by this function must be + * consistent for the entire duration of the Nanoapp's execution. + * + * The client must allow for more flags to be set in this response than it knows + * about, for example if the implementation supports a newer version of the API + * than the client was compiled against. + * + * @return A bitmask with zero or more CHRE_WIFI_CAPABILITIES_* flags set + * + * @since v1.1 + */ +uint32_t chreWifiGetCapabilities(void); + +/** + * Retrieves device-specific WiFi NAN capabilities, and populates them in + * the @ref chreWifiNanCapabilities structure. + * + * @param capabilities Structure into which the WiFi NAN capabilities of + * the device are populated into. Must not be NULL. + * @return true if WiFi NAN is supported, false otherwise. + * + * @since v1.6 + */ +bool chreWifiNanGetCapabilities(struct chreWifiNanCapabilities *capabilities); + +/** + * Nanoapps must define CHRE_NANOAPP_USES_WIFI somewhere in their build + * system (e.g. Makefile) if the nanoapp needs to use the following WiFi APIs. + * In addition to allowing access to these APIs, defining this macro will also + * ensure CHRE enforces that all host clients this nanoapp talks to have the + * required Android permissions needed to listen to WiFi data by adding metadata + * to the nanoapp. + */ +#if defined(CHRE_NANOAPP_USES_WIFI) || !defined(CHRE_IS_NANOAPP_BUILD) + +/** + * Manages a client's request to receive the results of WiFi scans performed for + * other purposes, for example scans done to maintain connectivity and scans + * requested by other clients. The presence of this request has no effect on the + * frequency or configuration of the WiFi scans performed - it is purely a + * registration by the client to receive the results of scans that would + * otherwise occur normally. This should include all available scan results, + * including those that are not normally sent to the applications processor, + * such as Preferred Network Offload (PNO) scans. Scan results provided because + * of this registration must not contain cached results - they are always + * expected to contain the fresh results from a recent scan. + * + * An active scan monitor subscription must persist across temporary conditions + * under which no WiFi scans will be performed, for example if WiFi is + * completely disabled via user-controlled settings, or if the WiFi system + * restarts independently of CHRE. Likewise, a request to enable a scan monitor + * subscription must succeed under normal conditions, even in circumstances + * where no WiFi scans will be performed. In these cases, the scan monitor + * implementation must produce scan results once the temporary condition is + * cleared, for example after WiFi is enabled by the user. + * + * These scan results are delivered to the Nanoapp's handle event callback using + * CHRE_EVENT_WIFI_SCAN_RESULT. + * + * An active scan monitor subscription is not necessary to receive the results + * of an on-demand scan request sent via chreWifiRequestScanAsync(), and it does + * not result in duplicate delivery of scan results generated from + * chreWifiRequestScanAsync(). + * + * If no monitor subscription is active at the time of a request with + * enable=false, it is treated as if an active subscription was successfully + * ended. + * + * The result of this request is delivered asynchronously via an event of type + * CHRE_EVENT_WIFI_ASYNC_RESULT. Refer to the note in {@link #chreAsyncResult} + * for more details. + * + * @param enable Set to true to enable monitoring scan results, false to + * disable + * @param cookie An opaque value that will be included in the chreAsyncResult + * sent in relation to this request. + * @return true if the request was accepted for processing, false otherwise + * + * @since v1.1 + * @note Requires WiFi permission + */ +bool chreWifiConfigureScanMonitorAsync(bool enable, const void *cookie); + +/** + * Sends an on-demand request for WiFi scan results. This may trigger a new + * scan, or be entirely serviced from cache, depending on the maxScanAgeMs + * parameter. + * + * This resulting status of this request is delivered asynchronously via an + * event of type CHRE_EVENT_WIFI_ASYNC_RESULT. The result must be delivered + * within CHRE_WIFI_SCAN_RESULT_TIMEOUT_NS of the this request. Refer to the + * note in {@link #chreAsyncResult} for more details. + * + * A successful result provided in CHRE_EVENT_WIFI_ASYNC_RESULT indicates that + * the scan results are ready to be delivered in a subsequent event (or events, + * which arrive consecutively without any other scan results in between) + * of type CHRE_EVENT_WIFI_SCAN_RESULT. + * + * WiFi scanning must be disabled if both "WiFi scanning" and "WiFi" settings + * are disabled at the Android level. In this case, the CHRE implementation is + * expected to return a result with CHRE_ERROR_FUNCTION_DISABLED. + * + * It is not valid for a client to request a new scan while a result is pending + * based on a previous scan request from the same client. In this situation, the + * CHRE implementation is expected to return a result with CHRE_ERROR_BUSY. + * However, if a scan is currently pending or in progress due to a request from + * another client, whether within the CHRE or otherwise, the implementation must + * not fail the request for this reason. If the pending scan satisfies the + * client's request parameters, then the implementation should use its results + * to satisfy the request rather than scheduling a new scan. + * + * @param params A set of parameters for the scan request. Must not be NULL. + * @param cookie An opaque value that will be included in the chreAsyncResult + * sent in relation to this request. + * @return true if the request was accepted for processing, false otherwise + * + * @since v1.1 + * @note Requires WiFi permission + */ +bool chreWifiRequestScanAsync(const struct chreWifiScanParams *params, + const void *cookie); + +/** + * Convenience function which calls chreWifiRequestScanAsync() with a default + * set of scan parameters. + * + * @param cookie An opaque value that will be included in the chreAsyncResult + * sent in relation to this request. + * @return true if the request was accepted for processing, false otherwise + * + * @since v1.1 + * @note Requires WiFi permission + */ +static inline bool chreWifiRequestScanAsyncDefault(const void *cookie) { + static const struct chreWifiScanParams params = { + /*.scanType=*/ CHRE_WIFI_SCAN_TYPE_NO_PREFERENCE, + /*.maxScanAgeMs=*/ 5000, // 5 seconds + /*.frequencyListLen=*/ 0, + /*.frequencyList=*/ NULL, + /*.ssidListLen=*/ 0, + /*.ssidList=*/ NULL, + /*.radioChainPref=*/ CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT, + /*.channelSet=*/ CHRE_WIFI_CHANNEL_SET_NON_DFS + }; + return chreWifiRequestScanAsync(¶ms, cookie); +} + +/** + * Issues a request to initiate distance measurements using round-trip time + * (RTT), aka Fine Timing Measurement (FTM), to one or more devices identified + * by MAC address. Within CHRE, MACs are typically the BSSIDs of scanned APs + * that have the CHRE_WIFI_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER flag set. + * + * This resulting status of this request is delivered asynchronously via an + * event of type CHRE_EVENT_WIFI_ASYNC_RESULT. The result must be delivered + * within CHRE_WIFI_RANGING_RESULT_TIMEOUT_NS of the this request. Refer to the + * note in {@link #chreAsyncResult} for more details. + * + * WiFi RTT ranging must be disabled if any of the following is true: + * - Both "WiFi" and "WiFi Scanning" settings are disabled at the Android level. + * - The "Location" setting is disabled at the Android level. + * In this case, the CHRE implementation is expected to return a result with + * CHRE_ERROR_FUNCTION_DISABLED. + * + * A successful result provided in CHRE_EVENT_WIFI_ASYNC_RESULT indicates that + * the results of ranging will be delivered in a subsequent event of type + * CHRE_EVENT_WIFI_RANGING_RESULT. Note that the CHRE_EVENT_WIFI_ASYNC_RESULT + * gives an overall status - for example, it is used to indicate failure if the + * entire ranging request was rejected because WiFi is disabled. However, it is + * valid for this event to indicate success, but RTT ranging to fail for all + * requested devices - for example, they may be out of range. Therefore, it is + * also necessary to check the status field in {@link #chreWifiRangingResult}. + * + * @param params Structure containing the parameters of the scan request, + * including the list of devices to attempt ranging. + * @param cookie An opaque value that will be included in the chreAsyncResult + * sent in relation to this request. + * @return true if the request was accepted for processing, false otherwise + * + * @since v1.2 + * @note Requires WiFi permission + */ +bool chreWifiRequestRangingAsync(const struct chreWifiRangingParams *params, + const void *cookie); + +/** + * Helper function to populate an instance of struct chreWifiRangingTarget with + * the contents of a scan result provided in struct chreWifiScanResult. + * Populates other parameters that are not directly derived from the scan result + * with default values. + * + * @param scanResult The scan result to parse as input + * @param rangingTarget The RTT ranging target to populate as output + * + * @note Requires WiFi permission + */ +static inline void chreWifiRangingTargetFromScanResult( + const struct chreWifiScanResult *scanResult, + struct chreWifiRangingTarget *rangingTarget) { + memcpy(rangingTarget->macAddress, scanResult->bssid, + sizeof(rangingTarget->macAddress)); + rangingTarget->primaryChannel = scanResult->primaryChannel; + rangingTarget->centerFreqPrimary = scanResult->centerFreqPrimary; + rangingTarget->centerFreqSecondary = scanResult->centerFreqSecondary; + rangingTarget->channelWidth = scanResult->channelWidth; + + // Note that this is not strictly necessary (CHRE can see which API version + // the nanoapp was built against, so it knows to ignore these fields), but + // we do it here to keep things nice and tidy + memset(rangingTarget->reserved, 0, sizeof(rangingTarget->reserved)); +} + +/** + * Subscribe to a NAN service. + * + * Sends a subscription request to the NAN discovery engine with the + * specified configuration parameters. If successful, a unique non-zero + * subscription ID associated with this instance of the subscription + * request is assigned by the NAN discovery engine. The subscription request + * is active until explicitly canceled, or if the connection was interrupted. + * + * Note that CHRE forwards any discovery events that it receives to the + * subscribe function instance, and does no duplicate filtering. If + * multiple events of the same discovery are undesirable, it is up to the + * platform NAN discovery engine implementation to implement redundancy + * detection mechanisms. + * + * If WiFi is turned off by the user at the Android level, an existing + * subscribe session is canceled, and a CHRE_EVENT_WIFI_ASYNC_RESULT event is + * event is sent to the subscriber. Nanoapps are expected to register for user + * settings notifications (@see chreUserSettingConfigureEvents), and + * re-establish a subscribe session on a WiFi re-enabled settings changed + * notification. + * + * @param config Service subscription configuration + * @param cookie A value that the nanoapp uses to track this particular + * subscription request. + * @return true if NAN is enabled and a subscription request was successfully + * made to the NAN engine. The actual result of the service discovery + * is sent via a CHRE_EVENT_WIFI_NAN_DISCOVERY_RESULT event. + * + * @since v1.6 + * @note Requires WiFi permission + */ +bool chreWifiNanSubscribe(struct chreWifiNanSubscribeConfig *config, + const void *cookie); + +/** + * Cancel a subscribe function instance. + * + * @param subscriptionId The ID that was originally assigned to this instance + * of the subscribe function. + * @return true if NAN is enabled, the subscribe ID was found and the instance + * successfully canceled. + * + * @since v1.6 + * @note Requires WiFi permission + */ +bool chreWifiNanSubscribeCancel(uint32_t subscriptionID); + +/** + * Request RTT ranging from a peer NAN device. + * + * Nanoapps can use this API to explicitly request measurement reports from + * the peer device. Note that both end points have to support ranging for a + * successful request. The MAC address of the peer NAN device for which ranging + * is desired may be obtained either from a NAN service discovery or from an + * out-of-band source (HAL service, BLE, etc.). + * + * If WiFi is turned off by the user at the Android level, an existing + * ranging session is canceled, and a CHRE_EVENT_WIFI_ASYNC_RESULT event is + * sent to the subscriber. Nanoapps are expected to register for user settings + * notifications (@see chreUserSettingConfigureEvents), and perform another + * ranging request on a WiFi re-enabled settings changed notification. + * + * A successful result provided in CHRE_EVENT_WIFI_ASYNC_RESULT indicates that + * the results of ranging will be delivered in a subsequent event of type + * CHRE_EVENT_WIFI_RANGING_RESULT. + * + * @param params Structure containing the parameters of the ranging request, + * including the MAC address of the peer NAN device to attempt ranging. + * @param cookie An opaque value that will be included in the chreAsyncResult + * sent in relation to this request. + * @return true if the request was accepted for processing, false otherwise. + */ +bool chreWifiNanRequestRangingAsync(const struct chreWifiNanRangingParams *params, + const void *cookie); + +#else /* defined(CHRE_NANOAPP_USES_WIFI) || !defined(CHRE_IS_NANOAPP_BUILD) */ +#define CHRE_WIFI_PERM_ERROR_STRING \ + "CHRE_NANOAPP_USES_WIFI must be defined when building this nanoapp in " \ + "order to refer to " +#define chreWifiConfigureScanMonitorAsync(...) \ + CHRE_BUILD_ERROR(CHRE_WIFI_PERM_ERROR_STRING \ + "chreWifiConfigureScanMonitorAsync") +#define chreWifiRequestScanAsync(...) \ + CHRE_BUILD_ERROR(CHRE_WIFI_PERM_ERROR_STRING \ + "chreWifiRequestScanAsync") +#define chreWifiRequestScanAsyncDefault(...) \ + CHRE_BUILD_ERROR(CHRE_WIFI_PERM_ERROR_STRING \ + "chreWifiRequestScanAsyncDefault") +#define chreWifiRequestRangingAsync(...) \ + CHRE_BUILD_ERROR(CHRE_WIFI_PERM_ERROR_STRING "chreWifiRequestRangingAsync") +#define chreWifiRangingTargetFromScanResult(...) \ + CHRE_BUILD_ERROR(CHRE_WIFI_PERM_ERROR_STRING \ + "chreWifiRangingTargetFromScanResult") +#define chreWifiNanSubscribe(...) \ + CHRE_BUILD_ERROR(CHRE_WIFI_PERM_ERROR_STRING "chreWifiNanSubscribe") +#define chreWifiNanSubscribeCancel(...) \ + CHRE_BUILD_ERROR(CHRE_WIFI_PERM_ERROR_STRING "chreWifiNanSubscribeCancel") +#define chreWifiNanRequestRangingAsync(...) \ + CHRE_BUILD_ERROR(CHRE_WIFI_PERM_ERROR_STRING "chreWifiNanRequestRangingAsync") +#endif /* defined(CHRE_NANOAPP_USES_WIFI) || !defined(CHRE_IS_NANOAPP_BUILD) */ + +#ifdef __cplusplus +} +#endif + +#endif /* _CHRE_WIFI_H_ */
diff --git a/chre_api/legacy/v1_10/chre/wwan.h b/chre_api/legacy/v1_10/chre/wwan.h new file mode 100644 index 0000000..dc46182 --- /dev/null +++ b/chre_api/legacy/v1_10/chre/wwan.h
@@ -0,0 +1,594 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// IWYU pragma: private, include "chre_api/chre.h" +// IWYU pragma: friend chre/.*\.h + +#ifndef _CHRE_WWAN_H_ +#define _CHRE_WWAN_H_ + +/** + * @file + * Wireless Wide Area Network (WWAN, i.e. mobile/cellular network) API relevant + * for querying cell tower identity and associated information that can be + * useful in determining location. + * + * Based on Android N RIL definitions (located at this path as of the time of + * this comment: hardware/ril/include/telephony/ril.h), version 12. Updated + * based on Android radio HAL definition (hardware/interfaces/radio) for more + * recent Android builds. Refer to those files and associated documentation for + * further details. + * + * In general, the parts of this API that are taken from the RIL follow the + * field naming conventions established in that interface rather than the CHRE + * API conventions, in order to avoid confusion and enable code re-use where + * applicable. Note that structure names include the chreWwan* prefix rather + * than RIL_*, but field names are the same. If necessary to enable code + * sharing, it is recommended to create typedefs that map from the CHRE + * structures to the associated RIL type names, for example "typedef struct + * chreWwanCellIdentityGsm RIL_CellIdentityGsm_v12", etc. + */ + +#include <chre/common.h> + +#include <stdbool.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The set of flags returned by chreWwanGetCapabilities(). + * @defgroup CHRE_WWAN_CAPABILITIES + * @{ + */ + +//! No WWAN APIs are supported +#define CHRE_WWAN_CAPABILITIES_NONE UINT32_C(0) + +//! Current cell information can be queried via chreWwanGetCellInfoAsync() +#define CHRE_WWAN_GET_CELL_INFO UINT32_C(1 << 0) + +/** @} */ + +/** + * Produce an event ID in the block of IDs reserved for WWAN + * @param offset Index into WWAN event ID block; valid range [0,15] + */ +#define CHRE_WWAN_EVENT_ID(offset) (CHRE_EVENT_WWAN_FIRST_EVENT + (offset)) + +/** + * nanoappHandleEvent argument: struct chreWwanCellInfoResult + * + * Provides the result of an asynchronous request for cell info sent via + * chreWwanGetCellInfoAsync(). + */ +#define CHRE_EVENT_WWAN_CELL_INFO_RESULT CHRE_WWAN_EVENT_ID(0) + +// NOTE: Do not add new events with ID > 15; only values 0-15 are reserved +// (see chre/event.h) + +/** + * The current version of struct chreWwanCellInfoResult associated with this + * API definition. + */ +#define CHRE_WWAN_CELL_INFO_RESULT_VERSION UINT8_C(1) + +//! Reference: RIL_CellIdentityGsm_v12 +struct chreWwanCellIdentityGsm { + //! 3-digit Mobile Country Code, 0..999, INT32_MAX if unknown + int32_t mcc; + + //! 2 or 3-digit Mobile Network Code, 0..999, INT32_MAX if unknown + int32_t mnc; + + //! 16-bit Location Area Code, 0..65535, INT32_MAX if unknown + int32_t lac; + + //! 16-bit GSM Cell Identity described in TS 27.007, 0..65535, + //! INT32_MAX if unknown + int32_t cid; + + //! 16-bit GSM Absolute RF channel number, INT32_MAX if unknown + int32_t arfcn; + + //! 6-bit Base Station Identity Code, UINT8_MAX if unknown + uint8_t bsic; + + //! Reserved for future use; must be set to 0 + uint8_t reserved[3]; +}; + +//! Reference: RIL_CellIdentityWcdma_v12 +struct chreWwanCellIdentityWcdma { + //! 3-digit Mobile Country Code, 0..999, INT32_MAX if unknown + int32_t mcc; + + //! 2 or 3-digit Mobile Network Code, 0..999, INT32_MAX if unknown + int32_t mnc; + + //! 16-bit Location Area Code, 0..65535, INT32_MAX if unknown + int32_t lac; + + //! 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, + //! INT32_MAX if unknown + int32_t cid; + + //! 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511, + //! INT32_MAX if unknown + int32_t psc; + + //! 16-bit UMTS Absolute RF Channel Number, INT32_MAX if unknown + int32_t uarfcn; +}; + +//! Reference: RIL_CellIdentityCdma +struct chreWwanCellIdentityCdma { + //! Network Id 0..65535, INT32_MAX if unknown + int32_t networkId; + + //! CDMA System Id 0..32767, INT32_MAX if unknown + int32_t systemId; + + //! Base Station Id 0..65535, INT32_MAX if unknown + int32_t basestationId; + + //! Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. + //! It is represented in units of 0.25 seconds and ranges from -2592000 + //! to 2592000, both values inclusive (corresponding to a range of -180 + //! to +180 degrees). INT32_MAX if unknown + int32_t longitude; + + //! Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. + //! It is represented in units of 0.25 seconds and ranges from -1296000 + //! to 1296000, both values inclusive (corresponding to a range of -90 + //! to +90 degrees). INT32_MAX if unknown + int32_t latitude; +}; + +//! Reference: RIL_CellIdentityLte_v12 +struct chreWwanCellIdentityLte { + //! 3-digit Mobile Country Code, 0..999, INT32_MAX if unknown + int32_t mcc; + + //! 2 or 3-digit Mobile Network Code, 0..999, INT32_MAX if unknown + int32_t mnc; + + //! 28-bit Cell Identity described in TS ???, INT32_MAX if unknown + int32_t ci; + + //! physical cell id 0..503, INT32_MAX if unknown + int32_t pci; + + //! 16-bit tracking area code, INT32_MAX if unknown + int32_t tac; + + //! 18-bit LTE Absolute RF Channel Number, INT32_MAX if unknown + int32_t earfcn; +}; + +//! Reference: RIL_CellIdentityTdscdma +struct chreWwanCellIdentityTdscdma { + //! 3-digit Mobile Country Code, 0..999, INT32_MAX if unknown + int32_t mcc; + + //! 2 or 3-digit Mobile Network Code, 0..999, INT32_MAX if unknown + int32_t mnc; + + //! 16-bit Location Area Code, 0..65535, INT32_MAX if unknown + int32_t lac; + + //! 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, + //! INT32_MAX if unknown + int32_t cid; + + //! 8-bit Cell Parameters ID described in TS 25.331, 0..127, INT32_MAX if + //! unknown + int32_t cpid; +}; + +//! Reference: android.hardware.radio@1.4 CellIdentityNr +//! @since v1.4 +struct chreWwanCellIdentityNr { + //! 3-digit Mobile Country Code, in range [0, 999]. This value must be valid + //! for registered or camped cells. INT32_MAX means invalid/unreported. + int32_t mcc; + + //! 2 or 3-digit Mobile Network Code, in range [0, 999]. This value must be + //! valid for registered or camped cells. INT32_MAX means + //! invalid/unreported. + int32_t mnc; + + //! NR Cell Identity in range [0, 68719476735] (36 bits), which + //! unambiguously identifies a cell within a public land mobile network + //! (PLMN). This value must be valid for registered or camped cells. + //! Reference: TS 38.413 section 9.3.1.7. + //! + //! Note: for backward compatibility reasons, the nominally int64_t nci is + //! split into two uint32_t values, with nci0 being the least significant 4 + //! bytes. If chreWwanUnpackNrNci returns INT64_MAX, it means nci is + //! invalid/unreported. + //! + //! Users are recommended to use the helper accessor chreWwanUnpackNrNci to + //! access the nci field. + //! + //! @see chreWwanUnpackNrNci + uint32_t nci0; + uint32_t nci1; + + //! Physical cell id in range [0, 1007]. This value must be valid. + //! Reference: TS 38.331 section 6.3.2. + int32_t pci; + + //! 24-bit tracking area code in range [0, 16777215]. INT32_MAX means + //! invalid/unreported. + //! Reference: TS 38.413 section 9.3.3.10 and TS 29.571 section 5.4.2. + int32_t tac; + + //! NR Absolute Radio Frequency Channel Number, in range [0, 3279165]. This + //! value must be valid. + //! Reference: TS 38.101-1 section 5.4.2.1 and TS 38.101-2 section 5.4.2.1. + int32_t nrarfcn; +}; + +//! Reference: RIL_GSM_SignalStrength_v12 +struct chreWwanSignalStrengthGsm { + //! Valid values are (0-31, 99) as defined in TS 27.007 8.5 + //! INT32_MAX means invalid/unreported. + int32_t signalStrength; + + //! bit error rate (0-7, 99) as defined in TS 27.007 8.5 + //! INT32_MAX means invalid/unreported. + int32_t bitErrorRate; + + //! Timing Advance in bit periods. 1 bit period = 48.13 us. + //! INT32_MAX means invalid/unreported. + int32_t timingAdvance; +}; + +//! Reference: RIL_SignalStrengthWcdma +struct chreWwanSignalStrengthWcdma { + //! Valid values are (0-31, 99) as defined in TS 27.007 8.5 + //! INT32_MAX means invalid/unreported. + int32_t signalStrength; + + //! bit error rate (0-7, 99) as defined in TS 27.007 8.5 + //! INT32_MAX means invalid/unreported. + int32_t bitErrorRate; +}; + +//! Reference: RIL_CDMA_SignalStrength +struct chreWwanSignalStrengthCdma { + //! Valid values are positive integers. This value is the actual RSSI value + //! multiplied by -1. Example: If the actual RSSI is -75, then this + //! response value will be 75. + //! INT32_MAX means invalid/unreported. + int32_t dbm; + + //! Valid values are positive integers. This value is the actual Ec/Io + //! multiplied by -10. Example: If the actual Ec/Io is -12.5 dB, then this + //! response value will be 125. + //! INT32_MAX means invalid/unreported. + int32_t ecio; +}; + +//! Reference: RIL_EVDO_SignalStrength +struct chreWwanSignalStrengthEvdo { + //! Valid values are positive integers. This value is the actual RSSI value + //! multiplied by -1. Example: If the actual RSSI is -75, then this + //! response value will be 75. + //! INT32_MAX means invalid/unreported. + int32_t dbm; + + //! Valid values are positive integers. This value is the actual Ec/Io + //! multiplied by -10. Example: If the actual Ec/Io is -12.5 dB, then this + //! response value will be 125. + //! INT32_MAX means invalid/unreported. + int32_t ecio; + + //! Valid values are 0-8. 8 is the highest signal to noise ratio. + //! INT32_MAX means invalid/unreported. + int32_t signalNoiseRatio; +}; + +//! Reference: RIL_LTE_SignalStrength_v8 +struct chreWwanSignalStrengthLte { + //! Valid values are (0-31, 99) as defined in TS 27.007 8.5 + int32_t signalStrength; + + //! The current Reference Signal Receive Power in dBm multiplied by -1. + //! Range: 44 to 140 dBm + //! INT32_MAX means invalid/unreported. + //! Reference: 3GPP TS 36.133 9.1.4 + int32_t rsrp; + + //! The current Reference Signal Receive Quality in dB multiplied by -1. + //! Range: 3 to 20 dB. + //! INT32_MAX means invalid/unreported. + //! Reference: 3GPP TS 36.133 9.1.7 + int32_t rsrq; + + //! The current reference signal signal-to-noise ratio in 0.1 dB units. + //! Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB). + //! INT32_MAX means invalid/unreported. + //! Reference: 3GPP TS 36.101 8.1.1 + int32_t rssnr; + + //! The current Channel Quality Indicator. + //! Range: 0 to 15. + //! INT32_MAX means invalid/unreported. + //! Reference: 3GPP TS 36.101 9.2, 9.3, A.4 + int32_t cqi; + + //! timing advance in micro seconds for a one way trip from cell to device. + //! Approximate distance can be calculated using 300m/us * timingAdvance. + //! Range: 0 to 0x7FFFFFFE + //! INT32_MAX means invalid/unreported. + //! Reference: 3GPP 36.321 section 6.1.3.5 + //! also: http://www.cellular-planningoptimization.com/2010/02/timing-advance-with-calculation.html + int32_t timingAdvance; +}; + +//! Reference: RIL_TD_SCDMA_SignalStrength +struct chreWwanSignalStrengthTdscdma { + //! The Received Signal Code Power in dBm multiplied by -1. + //! Range : 25 to 120 + //! INT32_MAX means invalid/unreported. + //! Reference: 3GPP TS 25.123, section 9.1.1.1 + int32_t rscp; +}; + +//! Reference: android.hardware.radio@1.4 NrSignalStrength +//! @since v1.4 +struct chreWwanSignalStrengthNr { + //! SS (second synchronization) reference signal received power in dBm + //! multiplied by -1. + //! Range [44, 140], INT32_MAX means invalid/unreported. + //! Reference: TS 38.215 section 5.1.1 and TS 38.133 section 10.1.6. + int32_t ssRsrp; + + //! SS reference signal received quality in 0.5 dB units. + //! Range [-86, 41] with -86 = -43.0 dB and 41 = 20.5 dB. + //! INT32_MAX means invalid/unreported. + //! Reference: TS 38.215 section 5.1.3 and TS 38.133 section 10.1.11.1. + int32_t ssRsrq; + + //! SS signal-to-noise and interference ratio in 0.5 dB units. + //! Range [-46, 81] with -46 = -23.0 dB and 81 = 40.5 dB. + //! INT32_MAX means invalid/unreported. + //! Reference: TS 38.215 section 5.1.5 and TS 38.133 section 10.1.16.1. + int32_t ssSinr; + + //! CSI reference signal received power in dBm multiplied by -1. + //! Range [44, 140], INT32_MAX means invalid/unreported. + //! Reference: TS 38.215 section 5.1.2 and TS 38.133 section 10.1.6. + int32_t csiRsrp; + + //! CSI reference signal received quality in 0.5 dB units. + //! Range [-86, 41] with -86 = -43.0 dB and 41 = 20.5 dB. + //! INT32_MAX means invalid/unreported. + //! Reference: TS 38.215 section 5.1.4 and TS 38.133 section 10.1.11.1. + int32_t csiRsrq; + + //! CSI signal-to-noise and interference ratio in 0.5 dB units. + //! Range [-46, 81] with -46 = -23.0 dB and 81 = 40.5 dB. + //! INT32_MAX means invalid/unreported. + //! Reference: TS 38.215 section 5.1.6 and TS 38.133 section 10.1.16.1. + int32_t csiSinr; +}; + +//! Reference: RIL_CellInfoGsm_v12 +struct chreWwanCellInfoGsm { + struct chreWwanCellIdentityGsm cellIdentityGsm; + struct chreWwanSignalStrengthGsm signalStrengthGsm; +}; + +//! Reference: RIL_CellInfoWcdma_v12 +struct chreWwanCellInfoWcdma { + struct chreWwanCellIdentityWcdma cellIdentityWcdma; + struct chreWwanSignalStrengthWcdma signalStrengthWcdma; +}; + +//! Reference: RIL_CellInfoCdma +struct chreWwanCellInfoCdma { + struct chreWwanCellIdentityCdma cellIdentityCdma; + struct chreWwanSignalStrengthCdma signalStrengthCdma; + struct chreWwanSignalStrengthEvdo signalStrengthEvdo; +}; + +//! Reference: RIL_CellInfoLte_v12 +struct chreWwanCellInfoLte { + struct chreWwanCellIdentityLte cellIdentityLte; + struct chreWwanSignalStrengthLte signalStrengthLte; +}; + +//! Reference: RIL_CellInfoTdscdma +struct chreWwanCellInfoTdscdma { + struct chreWwanCellIdentityTdscdma cellIdentityTdscdma; + struct chreWwanSignalStrengthTdscdma signalStrengthTdscdma; +}; + +//! Reference: android.hardware.radio@1.4 CellInfoNr +//! @since v1.4 +struct chreWwanCellInfoNr { + struct chreWwanCellIdentityNr cellIdentityNr; + struct chreWwanSignalStrengthNr signalStrengthNr; +}; + +//! Reference: RIL_CellInfoType +//! All other values are reserved and should be ignored by nanoapps. +enum chreWwanCellInfoType { + CHRE_WWAN_CELL_INFO_TYPE_GSM = 1, + CHRE_WWAN_CELL_INFO_TYPE_CDMA = 2, + CHRE_WWAN_CELL_INFO_TYPE_LTE = 3, + CHRE_WWAN_CELL_INFO_TYPE_WCDMA = 4, + CHRE_WWAN_CELL_INFO_TYPE_TD_SCDMA = 5, + CHRE_WWAN_CELL_INFO_TYPE_NR = 6, //! @since v1.4 +}; + +//! Reference: RIL_TimeStampType +enum chreWwanCellTimeStampType { + CHRE_WWAN_CELL_TIMESTAMP_TYPE_UNKNOWN = 0, + CHRE_WWAN_CELL_TIMESTAMP_TYPE_ANTENNA = 1, + CHRE_WWAN_CELL_TIMESTAMP_TYPE_MODEM = 2, + CHRE_WWAN_CELL_TIMESTAMP_TYPE_OEM_RIL = 3, + CHRE_WWAN_CELL_TIMESTAMP_TYPE_JAVA_RIL = 4, +}; + +//! Reference: RIL_CellInfo_v12 +struct chreWwanCellInfo { + //! Timestamp in nanoseconds; must be in the same time base as chreGetTime() + uint64_t timeStamp; + + //! A value from enum {@link #CellInfoType} indicating the radio access + //! technology of the cell, and which field in union CellInfo can be used + //! to retrieve additional information + uint8_t cellInfoType; + + //! A value from enum {@link #CellTimeStampType} that identifies the source + //! of the value in timeStamp. This is typically set to + //! CHRE_WWAN_CELL_TIMESTAMP_TYPE_OEM_RIL, and indicates the time given by + //! chreGetTime() that an intermediate module received the data from the + //! modem and forwarded it to the requesting CHRE client. + uint8_t timeStampType; + + //! !0 if this cell is registered, 0 if not registered + uint8_t registered; + + //! Reserved for future use; must be set to 0 + uint8_t reserved; + + //! The value in cellInfoType indicates which field in this union is valid + union chreWwanCellInfoPerRat { + struct chreWwanCellInfoGsm gsm; + struct chreWwanCellInfoCdma cdma; + struct chreWwanCellInfoLte lte; + struct chreWwanCellInfoWcdma wcdma; + struct chreWwanCellInfoTdscdma tdscdma; + struct chreWwanCellInfoNr nr; //! @since v1.4 + } CellInfo; +}; + +/** + * Data structure provided with events of type CHRE_EVENT_WWAN_CELL_INFO_RESULT. + */ +struct chreWwanCellInfoResult { + //! Indicates the version of the structure, for compatibility purposes. + //! Clients do not normally need to worry about this field; the CHRE + //! implementation guarantees that the client only receives the structure + //! version it expects. + uint8_t version; + + //! Populated with a value from enum {@link #chreError}, indicating whether + //! the request failed, and if so, provides the cause of the failure + uint8_t errorCode; + + //! The number of valid entries in cells[] + uint8_t cellInfoCount; + + //! Reserved for future use; must be set to 0 + uint8_t reserved; + + //! Set to the cookie parameter given to chreWwanGetCellInfoAsync() + const void *cookie; + + //! Pointer to an array of cellInfoCount elements containing information + //! about serving and neighbor cells + const struct chreWwanCellInfo *cells; +}; + + +/** + * Retrieves a set of flags indicating the WWAN features supported by the + * current CHRE implementation. The value returned by this function must be + * consistent for the entire duration of the Nanoapp's execution. + * + * The client must allow for more flags to be set in this response than it knows + * about, for example if the implementation supports a newer version of the API + * than the client was compiled against. + * + * @return A bitmask with zero or more CHRE_WWAN_CAPABILITIES_* flags set + * + * @since v1.1 + */ +uint32_t chreWwanGetCapabilities(void); + +/** + * Nanoapps must define CHRE_NANOAPP_USES_WWAN somewhere in their build + * system (e.g. Makefile) if the nanoapp needs to use the following WWAN APIs. + * In addition to allowing access to these APIs, defining this macro will also + * ensure CHRE enforces that all host clients this nanoapp talks to have the + * required Android permissions needed to listen to WWAN data by adding metadata + * to the nanoapp. + */ +#if defined(CHRE_NANOAPP_USES_WWAN) || !defined(CHRE_IS_NANOAPP_BUILD) + +/** + * Query information about the current serving cell and its neighbors. This does + * not perform a network scan, but should return state from the current network + * registration data stored in the cellular modem. This is effectively the same + * as a request for RIL_REQUEST_GET_CELL_INFO_LIST in the RIL. + * + * The requested cellular information is returned asynchronously via + * CHRE_EVENT_WWAN_CELL_INFO_RESULT. The implementation must send this event, + * either with successful data or an error status, within + * CHRE_ASYNC_RESULT_TIMEOUT_NS. + * + * If the airplane mode setting is enabled at the Android level, the CHRE + * implementation is expected to return a successful asynchronous result with an + * empty cell info list. + * + * @param cookie An opaque value that will be included in the + * chreWwanCellInfoResult sent in relation to this request. + * + * @return true if the request was accepted for processing, false otherwise + * + * @since v1.1 + * @note Requires WWAN permission + */ +bool chreWwanGetCellInfoAsync(const void *cookie); + +/** + * Helper accessor for nci in the chreWwanCellIdentityNr struct. + * + * @return nci or INT64_MAX if invalid/unreported. + * + * @see chreWwanCellIdentityNr + * + * @since v1.4 + * @note Requires WWAN permission + */ +static inline int64_t chreWwanUnpackNrNci( + const struct chreWwanCellIdentityNr *nrCellId) { + return (int64_t) (((uint64_t) nrCellId->nci1 << 32) | nrCellId->nci0); +} + +#else /* defined(CHRE_NANOAPP_USES_WWAN) || !defined(CHRE_IS_NANOAPP_BUILD) */ +#define CHRE_WWAN_PERM_ERROR_STRING \ + "CHRE_NANOAPP_USES_WWAN must be defined when building this nanoapp in " \ + "order to refer to " +#define chreWwanGetCellInfoAsync(...) \ + CHRE_BUILD_ERROR(CHRE_WWAN_PERM_ERROR_STRING "chreWwanGetCellInfoAsync") +#define chreWwanUnpackNrNci(...) \ + CHRE_BUILD_ERROR(CHRE_WWAN_PERM_ERROR_STRING "chreWwanUnpackNrNci") +#endif /* defined(CHRE_NANOAPP_USES_WWAN) || !defined(CHRE_IS_NANOAPP_BUILD) */ + +#ifdef __cplusplus +} +#endif + +#endif /* _CHRE_WWAN_H_ */
diff --git a/chre_flags.aconfig b/chre_flags.aconfig index 1fbb459..4348fd4 100644 --- a/chre_flags.aconfig +++ b/chre_flags.aconfig
@@ -1,13 +1,20 @@ package: "android.chre.flags" container: "system" +# Exported flags should remain here indefinitely +# Flags guarding APIs are exported +# Begin removed exported flags (keep flag definition) + flag { - name: "context_hub_callback_uuid_enabled" + name: "reliable_message" + is_exported: true namespace: "context_hub" - description: "Call IContextHubCallback.getUuid() to retrieve the UUID when this flag is on" - bug: "247124878" + description: "Enable the reliable message APIs" + bug: "314081414" } +# End removed exported flags (keep flag definition) + flag { name: "abort_if_no_context_hub_found" namespace: "context_hub" @@ -23,21 +30,6 @@ } flag { - name: "reliable_message" - is_exported: true - namespace: "context_hub" - description: "Enable the reliable message APIs" - bug: "314081414" -} - -flag { - name: "reliable_message_implementation" - namespace: "context_hub" - description: "Enable support for reliable messages in CHRE" - bug: "314081414" -} - -flag { name: "reliable_message_duplicate_detection_service" namespace: "context_hub" description: "Enable duplicate detection for reliable messages in the Context Hub Service" @@ -96,20 +88,6 @@ } flag { - name: "unified_metrics_reporting_api" - namespace: "context_hub" - description: "The API for unified metrics reporting in the Context Hub Service" - bug: "361804033" -} - -flag { - name: "unified_metrics_reporting_implementation" - namespace: "context_hub" - description: "The implementation for unified metrics reporting in the Context Hub Service" - bug: "361804033" -} - -flag { name: "reduce_locking_context_hub_transaction_manager" namespace: "context_hub" description: "Reduces locking in the ContextHubTransactionManager" @@ -118,3 +96,55 @@ purpose: PURPOSE_BUGFIX } } + +flag { + name: "offload_api" + namespace: "context_hub" + description: "Enables the generic offload APIs" + bug: "361573382" + is_exported: true +} + +flag { + name: "offload_implementation" + namespace: "context_hub" + description: "Enables support for generic offload" + bug: "361573382" +} + +flag { + name: "efw_xport_rewind_on_error" + namespace: "context_hub" + description: "Flag guarding the AOC-dependent behavior to rewind to the last good message" + bug: "371057943" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "efw_xport_in_context_hub" + namespace: "context_hub" + description: "Flag guarding the use of the new EFW transport for ContextHub <-> CHRE comms" + bug: "369883034" +} + +flag { + name: "bug_fix_remove_exit_call_in_hal" + namespace: "context_hub" + description: "Flag enabling multiclient HAL to gracefully handle connection to CHRE in init/restart" + bug: "374773993" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "hal_handle_nanoapp_query_test_mode" + namespace: "context_hub" + description: "Flag guarding the fix for nanoapp query handling when enabling test mode" + bug: "379342519" + metadata { + purpose: PURPOSE_BUGFIX + } +}
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt new file mode 100644 index 0000000..3d5485f --- /dev/null +++ b/core/CMakeLists.txt
@@ -0,0 +1,100 @@ +include($ENV{PW_ROOT}/pw_build/pigweed.cmake) + +pw_add_library(chre.core STATIC + HEADERS + include/chre/core/host_comms_manager.h + include/chre/core/settings.h + include/chre/core/audio_request_manager.h + include/chre/core/api_manager_common.h + include/chre/core/wifi_request_manager.h + include/chre/core/event_ref_queue.h + include/chre/core/sensor_request_multiplexer.h + include/chre/core/audio_util.h + include/chre/core/gnss_manager.h + include/chre/core/init.h + include/chre/core/timer_pool.h + include/chre/core/event_loop_common.h + include/chre/core/sensor_type.h + include/chre/core/wwan_request_manager.h + include/chre/core/event_loop.h + include/chre/core/sensor_request.h + include/chre/core/ble_request_multiplexer.h + include/chre/core/static_nanoapps.h + include/chre/core/sensor.h + include/chre/core/ble_request_manager.h + include/chre/core/request_multiplexer.h + include/chre/core/event_loop_manager.h + include/chre/core/system_health_monitor.h + include/chre/core/request_multiplexer_impl.h + include/chre/core/debug_dump_manager.h + include/chre/core/nanoapp.h + include/chre/core/telemetry_manager.h + include/chre/core/sensor_type_helpers.h + include/chre/core/wifi_scan_request.h + include/chre/core/sensor_request_manager.h + include/chre/core/event.h + include/chre/core/ble_request.h + include/chre/core/host_endpoint_manager.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.chre_api + chre.platform.assert + chre.platform.atomic + chre.platform.fatal_error + chre.platform.host_link + chre.platform.log + chre.platform.memory_manager + chre.platform.mutex + chre.platform.platform_audio + chre.platform.platform_ble + chre.platform.platform_debug_dump_manager + chre.platform.platform_gnss + chre.platform.platform_nanoapp + chre.platform.platform_sensor + chre.platform.platform_sensor_manager + chre.platform.platform_sensor_type_helpers + chre.platform.platform_wifi + chre.platform.platform_wwan + chre.platform.power_control_manager + chre.platform.system_time + chre.platform.system_timer + chre.util + chre.util.system + chre.variant.config + pw_function + SOURCES + audio_request_manager.cc + ble_request.cc + ble_request_manager.cc + ble_request_multiplexer.cc + debug_dump_manager.cc + event.cc + event_loop.cc + event_loop_manager.cc + event_ref_queue.cc + gnss_manager.cc + host_comms_manager.cc + host_endpoint_manager.cc + init.cc + nanoapp.cc + sensor.cc + sensor_request.cc + sensor_request_manager.cc + sensor_request_multiplexer.cc + sensor_type.cc + sensor_type_helpers.cc + settings.cc + static_nanoapps.cc + system_health_monitor.cc + timer_pool.cc + wifi_request_manager.cc + wifi_scan_request.cc + wwan_request_manager.cc + PRIVATE_DEPS + chre.platform.context + chre.platform.log + chre.platform.memory + chre.platform.tracing + chre.platform.version +)
diff --git a/core/audio_request_manager.cc b/core/audio_request_manager.cc index 47c919d..360a3e0 100644 --- a/core/audio_request_manager.cc +++ b/core/audio_request_manager.cc
@@ -14,6 +14,8 @@ * limitations under the License. */ +#ifdef CHRE_AUDIO_SUPPORT_ENABLED + #include "chre/core/audio_request_manager.h" #include "chre/core/audio_util.h" @@ -513,3 +515,5 @@ } } // namespace chre + +#endif // CHRE_AUDIO_SUPPORT_ENABLED
diff --git a/core/ble_request_manager.cc b/core/ble_request_manager.cc index ed93e3e..577a623 100644 --- a/core/ble_request_manager.cc +++ b/core/ble_request_manager.cc
@@ -14,6 +14,8 @@ * limitations under the License. */ +#ifdef CHRE_BLE_SUPPORT_ENABLED + #include "chre/core/ble_request_manager.h" #include "chre/core/event_loop_manager.h" @@ -716,3 +718,5 @@ } } // namespace chre + +#endif // CHRE_BLE_SUPPORT_ENABLED
diff --git a/core/chre_message_hub_manager.cc b/core/chre_message_hub_manager.cc new file mode 100644 index 0000000..96ed194 --- /dev/null +++ b/core/chre_message_hub_manager.cc
@@ -0,0 +1,189 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef CHRE_MESSAGE_ROUTER_SUPPORT_ENABLED + +#include "chre/core/chre_message_hub_manager.h" +#include "chre/core/event_loop_common.h" +#include "chre/core/event_loop_manager.h" +#include "chre/core/nanoapp.h" +#include "chre/util/system/message_common.h" +#include "chre/util/system/message_router.h" +#include "chre/util/unique_ptr.h" + +#include <cinttypes> +#include <optional> + +using ::chre::message::Endpoint; +using ::chre::message::EndpointId; +using ::chre::message::EndpointInfo; +using ::chre::message::EndpointType; +using ::chre::message::Message; +using ::chre::message::MessageRouter; +using ::chre::message::MessageRouterSingleton; +using ::chre::message::Session; + +namespace chre { + +void ChreMessageHubManager::init() { + std::optional<MessageRouter::MessageHub> chreMessageHub = + MessageRouterSingleton::get()->registerMessageHub( + "CHRE", kChreMessageHubId, *this); + if (chreMessageHub.has_value()) { + mChreMessageHub = std::move(*chreMessageHub); + } else { + LOGE("Failed to register the CHRE MessageHub"); + } +} + +void ChreMessageHubManager::onMessageToNanoappCallback( + SystemCallbackType /* type */, UniquePtr<MessageCallbackData> &&data) { + bool success = false; + Nanoapp *nanoapp = + EventLoopManagerSingleton::get()->getEventLoop().findNanoappByAppId( + data->nanoappId); + uint32_t messagePermissions = data->messageToNanoapp.messagePermissions; + if (nanoapp == nullptr) { + LOGE("Unable to find nanoapp with ID 0x%" PRIx64 + " to receive message with type %" PRIu32 " and permissions %" PRIu32 + " with session ID %" PRIu16, + data->nanoappId, data->messageToNanoapp.messageType, + data->messageToNanoapp.messagePermissions, + data->messageToNanoapp.sessionId); + } else if (!nanoapp->hasPermissions(messagePermissions)) { + LOGE("nanoapp with ID 0x%" PRIx64 + " does not have permissions to receive " + "message with type %" PRIu32 " and permissions 0x%" PRIx32, + nanoapp->getAppId(), data->messageToNanoapp.messageType, + data->messageToNanoapp.messagePermissions); + } else if (!EventLoopManagerSingleton::get() + ->getEventLoop() + .distributeEventSync(CHRE_EVENT_MESSAGE_FROM_ENDPOINT, + &data->messageToNanoapp, + nanoapp->getInstanceId())) { + LOGE("Unable to distribute message to nanoapp with ID 0x%" PRIx64, + nanoapp->getAppId()); + } else { + success = true; + } + + // Close session on failure so sender knows there was an issue + if (!success) { + EventLoopManagerSingleton::get() + ->getChreMessageHubManager() + .getMessageHub() + .closeSession(data->messageToNanoapp.sessionId); + } +} + +void ChreMessageHubManager::onSessionClosedCallback( + SystemCallbackType /* type */, + UniquePtr<SessionClosedCallbackData> &&data) { + Nanoapp *nanoapp = + EventLoopManagerSingleton::get()->getEventLoop().findNanoappByAppId( + data->nanoappId); + if (nanoapp == nullptr) { + LOGE("Unable to find nanoapp with ID 0x%" PRIx64 + " to close the session with ID %" PRIu16, + data->nanoappId, data->sessionClosedData.sessionId); + return; + } + + bool success = + EventLoopManagerSingleton::get()->getEventLoop().distributeEventSync( + CHRE_EVENT_ENDPOINT_SESSION_CLOSED, &data->sessionClosedData, + nanoapp->getInstanceId()); + if (!success) { + LOGE("Unable to process session closed event to nanoapp with ID 0x%" PRIx64, + nanoapp->getAppId()); + } +} + +bool ChreMessageHubManager::onMessageReceived(pw::UniquePtr<std::byte[]> &&data, + size_t length, + uint32_t messageType, + uint32_t messagePermissions, + const Session &session, + bool sentBySessionInitiator) { + Endpoint receiver = sentBySessionInitiator ? session.peer : session.initiator; + auto messageCallbackData = MakeUnique<MessageCallbackData>(); + if (messageCallbackData.isNull()) { + LOG_OOM(); + return false; + } + + messageCallbackData->messageToNanoapp = { + .messageType = messageType, + .messagePermissions = messagePermissions, + .message = data.get(), + .messageSize = length, + .sessionId = session.sessionId, + }; + messageCallbackData->data = std::move(data); + messageCallbackData->nanoappId = receiver.endpointId; + + EventLoopManagerSingleton::get()->deferCallback( + SystemCallbackType::EndpointMessageToNanoappEvent, + std::move(messageCallbackData), + ChreMessageHubManager::onMessageToNanoappCallback); + return true; +} + +void ChreMessageHubManager::onSessionClosed(const Session &session) { + auto sessionClosedCallbackData = MakeUnique<SessionClosedCallbackData>(); + if (sessionClosedCallbackData.isNull()) { + LOG_OOM(); + return; + } + + Endpoint otherParty; + uint64_t nanoappId; + if (session.initiator.messageHubId == kChreMessageHubId) { + otherParty = session.peer; + nanoappId = session.initiator.endpointId; + } else { + otherParty = session.initiator; + nanoappId = session.peer.endpointId; + } + + sessionClosedCallbackData->sessionClosedData = { + .hubId = otherParty.messageHubId, + .endpointId = otherParty.endpointId, + .sessionId = session.sessionId, + }; + sessionClosedCallbackData->nanoappId = nanoappId; + + EventLoopManagerSingleton::get()->deferCallback( + SystemCallbackType::EndpointSessionClosedEvent, + std::move(sessionClosedCallbackData), + ChreMessageHubManager::onSessionClosedCallback); +} + +void ChreMessageHubManager::forEachEndpoint( + const pw::Function<bool(const EndpointInfo &)> &function) { + EventLoopManagerSingleton::get()->getEventLoop().onMatchingNanoappEndpoint( + function); +} + +std::optional<EndpointInfo> ChreMessageHubManager::getEndpointInfo( + EndpointId endpointId) { + return EventLoopManagerSingleton::get()->getEventLoop().getEndpointInfo( + endpointId); +} + +} // namespace chre + +#endif // CHRE_MESSAGE_ROUTER_SUPPORT_ENABLED
diff --git a/core/core.mk b/core/core.mk index 02aa3ec..d931458 100644 --- a/core/core.mk +++ b/core/core.mk
@@ -9,6 +9,7 @@ # Common Source Files ########################################################## +COMMON_SRCS += $(CHRE_PREFIX)/core/chre_message_hub_manager.cc COMMON_SRCS += $(CHRE_PREFIX)/core/debug_dump_manager.cc COMMON_SRCS += $(CHRE_PREFIX)/core/event.cc COMMON_SRCS += $(CHRE_PREFIX)/core/event_loop.cc @@ -17,7 +18,6 @@ COMMON_SRCS += $(CHRE_PREFIX)/core/host_comms_manager.cc COMMON_SRCS += $(CHRE_PREFIX)/core/host_endpoint_manager.cc COMMON_SRCS += $(CHRE_PREFIX)/core/init.cc -COMMON_SRCS += $(CHRE_PREFIX)/core/log.cc COMMON_SRCS += $(CHRE_PREFIX)/core/nanoapp.cc COMMON_SRCS += $(CHRE_PREFIX)/core/settings.cc COMMON_SRCS += $(CHRE_PREFIX)/core/static_nanoapps.cc
diff --git a/core/event_loop.cc b/core/event_loop.cc index 7c304c9..d5063e8 100644 --- a/core/event_loop.cc +++ b/core/event_loop.cc
@@ -24,6 +24,7 @@ #include "chre/core/nanoapp.h" #include "chre/platform/assert.h" #include "chre/platform/context.h" +#include "chre/platform/event_loop_hooks.h" #include "chre/platform/fatal_error.h" #include "chre/platform/system_time.h" #include "chre/util/conditional_lock_guard.h" @@ -35,6 +36,9 @@ #include "chre/util/time.h" #include "chre_api/chre/version.h" +using ::chre::message::EndpointInfo; +using ::chre::message::EndpointType; + namespace chre { // Out of line declaration required for nonintegral static types @@ -301,25 +305,16 @@ targetLowPriorityEventRemove); } -bool EventLoop::deliverEventSync(uint16_t nanoappInstanceId, - uint16_t eventType, - void *eventData) { +bool EventLoop::distributeEventSync(uint16_t eventType, void *eventData, + uint16_t targetInstanceId, + uint16_t targetGroupMask) { CHRE_ASSERT(inEventLoopThread()); - Event event(eventType, eventData, /* freeCallback= */ nullptr, /* isLowPriority= */ false, - /* senderInstanceId= */ kSystemInstanceId, - /* targetInstanceId= */ nanoappInstanceId, - kDefaultTargetGroupMask); - for (const UniquePtr<Nanoapp> &app : mNanoapps) { - if (app->getInstanceId() == nanoappInstanceId) { - deliverNextEvent(app, &event); - return true; - } - } - - return false; + /* senderInstanceId= */ kSystemInstanceId, targetInstanceId, + targetGroupMask); + return distributeEventCommon(&event); } // TODO(b/264108686): Refactor this function and postSystemEvent @@ -332,6 +327,9 @@ !allocateAndPostEvent(eventType, eventData, freeCallback, /* isLowPriority= */ false, kSystemInstanceId, targetInstanceId, targetGroupMask)) { + CHRE_HANDLE_FAILED_SYSTEM_EVENT_ENQUEUE( + this, eventType, eventData, freeCallback, kSystemInstanceId, + targetInstanceId, targetGroupMask); FATAL_ERROR("Failed to post critical system event 0x%" PRIx16, eventType); } } else if (freeCallback != nullptr) { @@ -347,6 +345,8 @@ } if (hasNoSpaceForHighPriorityEvent()) { + CHRE_HANDLE_EVENT_QUEUE_FULL_DURING_SYSTEM_POST(this, eventType, eventData, + callback, extraData); FATAL_ERROR("Failed to post critical system event 0x%" PRIx16 ": Full of high priority " "events", @@ -355,6 +355,9 @@ Event *event = mEventPool.allocate(eventType, eventData, callback, extraData); if (event == nullptr || !mEvents.push(event)) { + CHRE_HANDLE_FAILED_SYSTEM_EVENT_ENQUEUE( + this, eventType, eventData, callback, kSystemInstanceId, + kBroadcastInstanceId, kDefaultTargetGroupMask); FATAL_ERROR("Failed to post critical system event 0x%" PRIx16 ": out of memory", eventType); @@ -377,6 +380,9 @@ if (!eventPosted) { LOGE("Failed to allocate event 0x%" PRIx16 " to instanceId %" PRIu16, eventType, targetInstanceId); + CHRE_HANDLE_LOW_PRIORITY_ENQUEUE_FAILURE( + this, eventType, eventData, freeCallback, senderInstanceId, + targetInstanceId, targetGroupMask); ++mNumDroppedLowPriEvents; } } @@ -408,6 +414,11 @@ return lookupAppByInstanceId(instanceId); } +Nanoapp *EventLoop::findNanoappByAppId(uint64_t appId) const { + ConditionalLockGuard<Mutex> lock(mNanoappsLock, !inEventLoopThread()); + return lookupAppByAppId(appId); +} + bool EventLoop::populateNanoappInfoForAppId( uint64_t appId, struct chreNanoappInfo *info) const { ConditionalLockGuard<Mutex> lock(mNanoappsLock, !inEventLoopThread()); @@ -462,6 +473,25 @@ } } +void EventLoop::onMatchingNanoappEndpoint( + const pw::Function<bool(const EndpointInfo &)> &function) { + ConditionalLockGuard<Mutex> lock(mNanoappsLock, !inEventLoopThread()); + + for (const UniquePtr<Nanoapp> &app : mNanoapps) { + if (function(getEndpointInfoFromNanoappLocked(*app.get()))) { + break; + } + } +} + +std::optional<EndpointInfo> EventLoop::getEndpointInfo(uint64_t appId) { + ConditionalLockGuard<Mutex> lock(mNanoappsLock, !inEventLoopThread()); + Nanoapp *app = lookupAppByAppId(appId); + return app == nullptr + ? std::nullopt + : std::make_optional(getEndpointInfoFromNanoappLocked(*app)); +} + bool EventLoop::allocateAndPostEvent(uint16_t eventType, void *eventData, chreEventCompleteFunction *freeCallback, bool isLowPriority, @@ -514,13 +544,27 @@ } void EventLoop::distributeEvent(Event *event) { + distributeEventCommon(event); + CHRE_ASSERT(event->isUnreferenced()); + freeEvent(event); +} + +bool EventLoop::distributeEventCommon(Event *event) { bool eventDelivered = false; - for (const UniquePtr<Nanoapp> &app : mNanoapps) { - if ((event->targetInstanceId == chre::kBroadcastInstanceId && - app->isRegisteredForBroadcastEvent(event)) || - event->targetInstanceId == app->getInstanceId()) { - eventDelivered = true; - deliverNextEvent(app, event); + if (event->targetInstanceId == kBroadcastInstanceId) { + for (const UniquePtr<Nanoapp> &app : mNanoapps) { + if (app->isRegisteredForBroadcastEvent(event)) { + eventDelivered = true; + deliverNextEvent(app, event); + } + } + } else { + for (const UniquePtr<Nanoapp> &app : mNanoapps) { + if (event->targetInstanceId == app->getInstanceId()) { + eventDelivered = true; + deliverNextEvent(app, event); + break; + } } } // Log if an event unicast to a nanoapp isn't delivered, as this is could be @@ -533,8 +577,7 @@ LOGW("Dropping event 0x%" PRIx16 " from instanceId %" PRIu16 "->%" PRIu16, event->eventType, event->senderInstanceId, event->targetInstanceId); } - CHRE_ASSERT(event->isUnreferenced()); - freeEvent(event); + return eventDelivered; } void EventLoop::flushInboundEventQueue() { @@ -681,4 +724,14 @@ } } +EndpointInfo EventLoop::getEndpointInfoFromNanoappLocked( + const Nanoapp &nanoapp) { + return EndpointInfo( + /* id= */ nanoapp.getAppId(), + /* name= */ nanoapp.getAppName(), + /* version= */ nanoapp.getAppVersion(), + /* type= */ EndpointType::NANOAPP, + /* requiredPermissions= */ nanoapp.getAppPermissions()); +} + } // namespace chre
diff --git a/core/event_loop_manager.cc b/core/event_loop_manager.cc index 4baf5d6..e802135 100644 --- a/core/event_loop_manager.cc +++ b/core/event_loop_manager.cc
@@ -16,6 +16,8 @@ #include "chre/core/event_loop_manager.h" +#include "chre/core/event_loop_common.h" +#include "chre/event.h" #include "chre/platform/atomic.h" #include "chre/platform/fatal_error.h" #include "chre/platform/memory.h" @@ -71,6 +73,10 @@ #ifdef CHRE_BLE_SUPPORT_ENABLED mBleRequestManager.init(); #endif // CHRE_BLE_SUPPORT_ENABLED + +#ifdef CHRE_MESSAGE_ROUTER_SUPPORT_ENABLED + mChreMessageHubManager.init(); +#endif // CHRE_MESSAGE_ROUTER_SUPPORT_ENABLED } // Explicitly instantiate the EventLoopManagerSingleton to reduce codesize.
diff --git a/core/gnss_manager.cc b/core/gnss_manager.cc index 4fce1ef..e11e9b1 100644 --- a/core/gnss_manager.cc +++ b/core/gnss_manager.cc
@@ -14,6 +14,8 @@ * limitations under the License. */ +#ifdef CHRE_GNSS_SUPPORT_ENABLED + #include "chre/core/gnss_manager.h" #include <cstddef> @@ -768,3 +770,5 @@ } } // namespace chre + +#endif // CHRE_GNSS_SUPPORT_ENABLED
diff --git a/core/host_comms_manager.cc b/core/host_comms_manager.cc index b00a8c5..1dc6b79 100644 --- a/core/host_comms_manager.cc +++ b/core/host_comms_manager.cc
@@ -27,7 +27,6 @@ #include "chre/platform/context.h" #include "chre/platform/host_link.h" #include "chre/platform/log.h" -#include "chre/target_platform/log.h" #include "chre/util/duplicate_message_detector.h" #include "chre/util/macros.h" #include "chre/util/nested_data_ptr.h" @@ -352,9 +351,9 @@ if (!foundNanoapp) { error = CHRE_ERROR_DESTINATION_NOT_FOUND; } else if (shouldDeliverMessage) { - EventLoopManagerSingleton::get()->getEventLoop().deliverEventSync( - targetInstanceId, CHRE_EVENT_MESSAGE_FROM_HOST, - &craftedMessage->fromHostData); + EventLoopManagerSingleton::get()->getEventLoop().distributeEventSync( + CHRE_EVENT_MESSAGE_FROM_HOST, &craftedMessage->fromHostData, + targetInstanceId); error = CHRE_ERROR_NONE; } @@ -485,8 +484,8 @@ asyncResult.cookie = message->cookie; onMessageToHostCompleteInternal(message); - eventLoop.deliverEventSync( - nanoappInstanceId, CHRE_EVENT_RELIABLE_MSG_ASYNC_RESULT, &asyncResult); + eventLoop.distributeEventSync(CHRE_EVENT_RELIABLE_MSG_ASYNC_RESULT, + &asyncResult, nanoappInstanceId); } }
diff --git a/core/host_endpoint_manager.cc b/core/host_endpoint_manager.cc index 694be90..3e776e8 100644 --- a/core/host_endpoint_manager.cc +++ b/core/host_endpoint_manager.cc
@@ -88,12 +88,11 @@ bool HostEndpointManager::getHostEndpointInfo( uint16_t hostEndpointId, struct chreHostEndpointInfo *info) { size_t index; - if (isHostEndpointConnected(hostEndpointId, &index)) { + bool isConnected = isHostEndpointConnected(hostEndpointId, &index); + if (isConnected) { *info = mHostEndpoints[index]; - return true; - } else { - return false; } + return isConnected; } void HostEndpointManager::postHostEndpointConnected(
diff --git a/core/include/chre/core/audio_request_manager.h b/core/include/chre/core/audio_request_manager.h index 8b97a34..a35b54b 100644 --- a/core/include/chre/core/audio_request_manager.h +++ b/core/include/chre/core/audio_request_manager.h
@@ -17,6 +17,8 @@ #ifndef CHRE_CORE_AUDIO_REQUEST_MANAGER_H_ #define CHRE_CORE_AUDIO_REQUEST_MANAGER_H_ +#ifdef CHRE_AUDIO_SUPPORT_ENABLED + #include <cstdint> #include "chre/core/nanoapp.h" @@ -383,4 +385,6 @@ } // namespace chre +#endif // CHRE_AUDIO_SUPPORT_ENABLED + #endif // CHRE_CORE_AUDIO_REQUEST_MANAGER_H_
diff --git a/core/include/chre/core/ble_request_manager.h b/core/include/chre/core/ble_request_manager.h index 957b8ab..847994d 100644 --- a/core/include/chre/core/ble_request_manager.h +++ b/core/include/chre/core/ble_request_manager.h
@@ -17,6 +17,8 @@ #ifndef CHRE_CORE_BLE_REQUEST_MANAGER_H_ #define CHRE_CORE_BLE_REQUEST_MANAGER_H_ +#ifdef CHRE_BLE_SUPPORT_ENABLED + #include "chre/core/ble_request.h" #include "chre/core/ble_request_multiplexer.h" #include "chre/core/nanoapp.h" @@ -582,4 +584,6 @@ } // namespace chre +#endif // CHRE_BLE_SUPPORT_ENABLED + #endif // CHRE_CORE_BLE_REQUEST_MANAGER_H_
diff --git a/core/include/chre/core/chre_message_hub_manager.h b/core/include/chre/core/chre_message_hub_manager.h new file mode 100644 index 0000000..15aaea9 --- /dev/null +++ b/core/include/chre/core/chre_message_hub_manager.h
@@ -0,0 +1,93 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CHRE_CORE_CHRE_MESSAGE_HUB_MANAGER_H_ +#define CHRE_CORE_CHRE_MESSAGE_HUB_MANAGER_H_ + +#ifdef CHRE_MESSAGE_ROUTER_SUPPORT_ENABLED + +#include "chre/core/event_loop_common.h" +#include "chre/util/non_copyable.h" +#include "chre/util/system/message_common.h" +#include "chre/util/system/message_router.h" +#include "chre/util/unique_ptr.h" + +#include <cinttypes> +#include <optional> + +namespace chre { + +//! Manager class for the CHRE Message Hub. +class ChreMessageHubManager + : public NonCopyable, + public message::MessageRouter::MessageHubCallback { + public: + //! The ID of the CHRE MessageHub + constexpr static message::MessageHubId kChreMessageHubId = CHRE_PLATFORM_ID; + + //! Initializes the ChreMessageHubManager + void init(); + + //! Returns the MessageHub for the CHRE Message Hub + message::MessageRouter::MessageHub &getMessageHub() { + return mChreMessageHub; + } + + private: + //! Data to be passed to the message callback + struct MessageCallbackData { + chreMessageFromEndpointData messageToNanoapp; + pw::UniquePtr<std::byte[]> data; + uint64_t nanoappId; + }; + + //! Data to be passed to the session closed callback + struct SessionClosedCallbackData { + chreEndpointSessionClosedData sessionClosedData; + uint64_t nanoappId; + }; + + //! Callback to process message sent to a nanoapp - used by the event loop + static void onMessageToNanoappCallback( + SystemCallbackType /* type */, + UniquePtr<ChreMessageHubManager::MessageCallbackData> &&data); + + //! Callback to process session closed event for a nanoapp - used by the event + //! loop + static void onSessionClosedCallback( + SystemCallbackType /* type */, + UniquePtr<ChreMessageHubManager::SessionClosedCallbackData> &&data); + + //! Definitions for MessageHubCallback + //! @see MessageRouter::MessageHubCallback + bool onMessageReceived(pw::UniquePtr<std::byte[]> &&data, size_t length, + uint32_t messageType, uint32_t messagePermissions, + const message::Session &session, + bool sentBySessionInitiator) override; + void onSessionClosed(const message::Session &session) override; + void forEachEndpoint(const pw::Function<bool(const message::EndpointInfo &)> + &function) override; + std::optional<message::EndpointInfo> getEndpointInfo( + message::EndpointId endpointId) override; + + message::MessageRouter::MessageHub mChreMessageHub; +}; + +} // namespace chre + +#endif // CHRE_MESSAGE_ROUTER_SUPPORT_ENABLED + +#endif // CHRE_CORE_CHRE_MESSAGE_HUB_MANAGER_H_
diff --git a/core/include/chre/core/event_loop.h b/core/include/chre/core/event_loop.h index fe7993a..97e11e5 100644 --- a/core/include/chre/core/event_loop.h +++ b/core/include/chre/core/event_loop.h
@@ -17,6 +17,10 @@ #ifndef CHRE_CORE_EVENT_LOOP_H_ #define CHRE_CORE_EVENT_LOOP_H_ +#include <pw_function/function.h> +#include <stddef.h> +#include <optional> + #include "chre/core/event.h" #include "chre/core/nanoapp.h" #include "chre/core/timer_pool.h" @@ -27,13 +31,14 @@ #include "chre/util/dynamic_vector.h" #include "chre/util/non_copyable.h" #include "chre/util/system/debug_dump.h" +#include "chre/util/system/message_common.h" #include "chre/util/system/stats_container.h" #include "chre/util/unique_ptr.h" #include "chre_api/chre/event.h" #ifdef CHRE_STATIC_EVENT_LOOP -#include "chre/util/fixed_size_blocking_queue.h" -#include "chre/util/synchronized_memory_pool.h" +#include "chre/util/system/fixed_size_blocking_queue.h" +#include "chre/util/system/synchronized_memory_pool.h" // These default values can be overridden in the variant-specific makefile. #ifndef CHRE_MAX_EVENT_COUNT @@ -45,7 +50,7 @@ #endif #else #include "chre/util/blocking_segmented_queue.h" -#include "chre/util/synchronized_expandable_memory_pool.h" +#include "chre/util/system/synchronized_expandable_memory_pool.h" // These default values can be overridden in the variant-specific makefile. #ifndef CHRE_EVENT_PER_BLOCK @@ -67,6 +72,11 @@ */ class EventLoop : public NonCopyable { public: + /** + * Synchronous callback used with forEachNanoapp + */ + typedef void(NanoappCallbackFunction)(const Nanoapp *nanoapp, void *data); + EventLoop() : #ifndef CHRE_STATIC_EVENT_LOOP @@ -77,11 +87,6 @@ } /** - * Synchronous callback used with forEachNanoapp - */ - typedef void(NanoappCallbackFunction)(const Nanoapp *nanoapp, void *data); - - /** * Searches the set of nanoapps managed by this EventLoop for one with the * given app ID. If found, provides its instance ID, which can be used to send * events to the app. @@ -172,8 +177,15 @@ void stop(); /** - * Synchronously deliver an event to a nanoapp. The event is sent from the - * system to the nanoapp with instance ID nanoappInstanceId. + * Synchronously distributes an event to all nanoapps that should receive it. + * The event is sent from the system to a specific nanoapp if targetInstanceId + * matches the nanoappId, or to all registered nanoapps if targetInstanceId + * is set to kBroadcastInstanceId + * + * This is intended to be used by the function provided to + * EventLoopManager::deferCallback in cases where pre- and post-processing are + * required around event delivery. This closes the gaps around event delivery + * and can remove the need for posting multiple events. * * This must only be used from the EventLoop thread, and must only be used in * rare circumstances where one of the postEvent functions cannot be used. In @@ -181,16 +193,18 @@ * ordering guarantees and trigger subtle bugs in nanoapps, so use with * caution. * - * freeCallback is guaranteed to be called before returning. + * No freeCallback is provided. The caller is expected to manage the memory + * for eventData, and handle any cleanup. * - * @param nanoappInstanceId The instance ID of the destination of this event * @param eventType Event type identifier, which implies the type of eventData * @param eventData The data being posted - * @return true if the event was successfully delivered, false otherwise. + * @param targetInstanceId The instance ID of the destination of this event + * @param targetGroupMask Mask used to limit the recipients that are + * registered to receive this event */ - bool deliverEventSync(uint16_t nanoappInstanceId, - uint16_t eventType, - void *eventData); + bool distributeEventSync(uint16_t eventType, void *eventData, + uint16_t targetInstanceId = kBroadcastInstanceId, + uint16_t targetGroupMask = kDefaultTargetGroupMask); /** * Posts an event to a nanoapp that is currently running (or all nanoapps if @@ -314,6 +328,17 @@ Nanoapp *findNanoappByInstanceId(uint16_t instanceId) const; /** + * Searches the set of nanoapps managed by this EventLoop for one with the + * given nanoapp ID. + * + * This function is safe to call from any thread. + * + * @param appId The nanoapp ID to search for. + * @return a pointer to the found nanoapp or nullptr if no match was found. + */ + Nanoapp *findNanoappByAppId(uint64_t appId) const; + + /** * Looks for an app with the given ID and if found, populates info with its * metadata. Safe to call from any thread. * @@ -347,6 +372,28 @@ void logStateToBuffer(DebugDumpWrapper &debugDump) const; /** + * Executes function for each nanoapp in the event loop. If function + * returns true, the iteration will stop. + * + * This function is safe to call from any thread. + * + * @param function The function to execute for each nanoapp. + */ + void onMatchingNanoappEndpoint( + const pw::Function<bool(const message::EndpointInfo &)> &function); + + /** + * Returns the EndpointInfo for the given nanoapp. + * + * This function is safe to call from any thread. + * + * @param appId The nanoapp ID to search for. + * @return The EndpointInfo for the given nanoapp, or std::nullopt if not + * found. + */ + std::optional<message::EndpointInfo> getEndpointInfo(uint64_t appId); + + /** * Returns a reference to the power control manager. This allows power * controls from subsystems outside the event loops. */ @@ -489,6 +536,16 @@ void distributeEvent(Event *event); /** + * Shared functionality to distributeEvent and distributeEventSync. Should + * only be called by those functions. Hnadles event distribution and logging + * without any pre- or post-processing. + * + * @param event The Event to distribute to Nanoapps + * @return True if the event was delivered to any nanoapps, otherwise false + */ + bool distributeEventCommon(Event *event); + + /** * Distribute all events pending in the inbound event queue. Note that this * function only guarantees that any events in the inbound queue at the time * it is called will be distributed to Nanoapp event queues - new events may @@ -559,6 +616,18 @@ * @param count The number of dangling resources. */ void logDanglingResources(const char *name, uint32_t count); + + /** + * Returns the EndpointInfo for the given nanoapp. + * + * Only safe to call within this EventLoop's thread, or if mNanoappsLock is + * held. + * + * @param nanoapp The nanoapp to get the EndpointInfo for. + * @return The EndpointInfo for the given nanoapp + */ + message::EndpointInfo getEndpointInfoFromNanoappLocked( + const Nanoapp &nanoapp); }; } // namespace chre
diff --git a/core/include/chre/core/event_loop_common.h b/core/include/chre/core/event_loop_common.h index ca280d1..ea2203d 100644 --- a/core/include/chre/core/event_loop_common.h +++ b/core/include/chre/core/event_loop_common.h
@@ -76,6 +76,8 @@ ReliableMessageEvent, TimerPoolTimerExpired, TransactionManagerTimeout, + EndpointMessageToNanoappEvent, + EndpointSessionClosedEvent, }; //! Deferred/delayed callbacks use the event subsystem but are invariably sent
diff --git a/core/include/chre/core/event_loop_manager.h b/core/include/chre/core/event_loop_manager.h index b5f52b3..255f9ee 100644 --- a/core/include/chre/core/event_loop_manager.h +++ b/core/include/chre/core/event_loop_manager.h
@@ -17,13 +17,21 @@ #ifndef CHRE_CORE_EVENT_LOOP_MANAGER_H_ #define CHRE_CORE_EVENT_LOOP_MANAGER_H_ +#include "chre/core/audio_request_manager.h" +#include "chre/core/ble_request_manager.h" +#include "chre/core/chre_message_hub_manager.h" #include "chre/core/debug_dump_manager.h" #include "chre/core/event_loop.h" #include "chre/core/event_loop_common.h" +#include "chre/core/gnss_manager.h" #include "chre/core/host_comms_manager.h" #include "chre/core/host_endpoint_manager.h" +#include "chre/core/sensor_request_manager.h" #include "chre/core/settings.h" #include "chre/core/system_health_monitor.h" +#include "chre/core/telemetry_manager.h" +#include "chre/core/wifi_request_manager.h" +#include "chre/core/wwan_request_manager.h" #include "chre/platform/atomic.h" #include "chre/platform/memory_manager.h" #include "chre/platform/mutex.h" @@ -34,34 +42,6 @@ #include "chre/util/unique_ptr.h" #include "chre_api/chre/event.h" -#ifdef CHRE_AUDIO_SUPPORT_ENABLED -#include "chre/core/audio_request_manager.h" -#endif // CHRE_AUDIO_SUPPORT_ENABLED - -#ifdef CHRE_BLE_SUPPORT_ENABLED -#include "chre/core/ble_request_manager.h" -#endif // CHRE_BLE_SUPPORT_ENABLED - -#ifdef CHRE_GNSS_SUPPORT_ENABLED -#include "chre/core/gnss_manager.h" -#endif // CHRE_GNSS_SUPPORT_ENABLED - -#ifdef CHRE_SENSORS_SUPPORT_ENABLED -#include "chre/core/sensor_request_manager.h" -#endif // CHRE_SENSORS_SUPPORT_ENABLED - -#ifdef CHRE_WIFI_SUPPORT_ENABLED -#include "chre/core/wifi_request_manager.h" -#endif // CHRE_WIFI_SUPPORT_ENABLED - -#ifdef CHRE_WWAN_SUPPORT_ENABLED -#include "chre/core/wwan_request_manager.h" -#endif // CHRE_WWAN_SUPPORT_ENABLED - -#ifdef CHRE_TELEMETRY_SUPPORT_ENABLED -#include "chre/core/telemetry_manager.h" -#endif // CHRE_TELEMETRY_SUPPORT_ENABLED - #include <cstddef> namespace chre { @@ -342,6 +322,12 @@ return mSystemHealthMonitor; } +#ifdef CHRE_MESSAGE_ROUTER_SUPPORT_ENABLED + ChreMessageHubManager &getChreMessageHubManager() { + return mChreMessageHubManager; + } +#endif // CHRE_MESSAGE_ROUTER_SUPPORT_ENABLED + /** * Performs second-stage initialization of things that are not necessarily * required at construction time but need to be completed prior to executing @@ -413,6 +399,11 @@ //! The SettingManager that manages setting states. SettingManager mSettingManager; + +#ifdef CHRE_MESSAGE_ROUTER_SUPPORT_ENABLED + //! The ChreMessageHubManager that manages the CHRE Message Hub. + ChreMessageHubManager mChreMessageHubManager; +#endif // CHRE_MESSAGE_ROUTER_SUPPORT_ENABLED }; //! Provide an alias to the EventLoopManager singleton.
diff --git a/core/include/chre/core/gnss_manager.h b/core/include/chre/core/gnss_manager.h index d4885ff..ed595d9 100644 --- a/core/include/chre/core/gnss_manager.h +++ b/core/include/chre/core/gnss_manager.h
@@ -17,6 +17,8 @@ #ifndef CHRE_CORE_GNSS_MANAGER_H_ #define CHRE_CORE_GNSS_MANAGER_H_ +#ifdef CHRE_GNSS_SUPPORT_ENABLED + #include <cstdint> #include "chre/core/api_manager_common.h" @@ -511,4 +513,6 @@ } // namespace chre +#endif // CHRE_GNSS_SUPPORT_ENABLED + #endif // CHRE_CORE_GNSS_MANAGER_H_
diff --git a/core/include/chre/core/host_comms_manager.h b/core/include/chre/core/host_comms_manager.h index a32a09a..305c19e 100644 --- a/core/include/chre/core/host_comms_manager.h +++ b/core/include/chre/core/host_comms_manager.h
@@ -27,9 +27,9 @@ #include "chre/util/buffer.h" #include "chre/util/duplicate_message_detector.h" #include "chre/util/non_copyable.h" -#include "chre/util/synchronized_memory_pool.h" +#include "chre/util/system/synchronized_memory_pool.h" +#include "chre/util/system/transaction_manager.h" #include "chre/util/time.h" -#include "chre/util/transaction_manager.h" #include "chre_api/chre/event.h" namespace chre {
diff --git a/core/include/chre/core/nanoapp.h b/core/include/chre/core/nanoapp.h index 9fb9a98..68404d2 100644 --- a/core/include/chre/core/nanoapp.h +++ b/core/include/chre/core/nanoapp.h
@@ -302,6 +302,15 @@ return mFirstHeader; } + /** + * @return whether the nanoapp has the provided permissions. + */ + bool hasPermissions(uint32_t permissions) const { + return permissions == 0 || + (supportsAppPermissions() && + (getAppPermissions() & permissions) == permissions); + } + private: uint16_t mInstanceId = kInvalidInstanceId;
diff --git a/core/include/chre/core/sensor_request_manager.h b/core/include/chre/core/sensor_request_manager.h index b91c154..5509d94 100644 --- a/core/include/chre/core/sensor_request_manager.h +++ b/core/include/chre/core/sensor_request_manager.h
@@ -17,6 +17,8 @@ #ifndef CHRE_CORE_SENSOR_REQUEST_MANAGER_H_ #define CHRE_CORE_SENSOR_REQUEST_MANAGER_H_ +#ifdef CHRE_SENSORS_SUPPORT_ENABLED + #include "chre/core/sensor.h" #include "chre/core/sensor_request.h" #include "chre/core/sensor_request_multiplexer.h" @@ -515,4 +517,6 @@ } // namespace chre +#endif // CHRE_SENSORS_SUPPORT_ENABLED + #endif // CHRE_CORE_SENSOR_REQUEST_MANAGER_H_
diff --git a/core/include/chre/core/telemetry_manager.h b/core/include/chre/core/telemetry_manager.h index 9364f86..768b654 100644 --- a/core/include/chre/core/telemetry_manager.h +++ b/core/include/chre/core/telemetry_manager.h
@@ -17,6 +17,8 @@ #ifndef CHRE_CORE_TELEMETRY_MANAGER_H_ #define CHRE_CORE_TELEMETRY_MANAGER_H_ +#ifdef CHRE_TELEMETRY_SUPPORT_ENABLED + #include <cinttypes> #include "chre/util/non_copyable.h" @@ -64,4 +66,6 @@ } // namespace chre +#endif // CHRE_TELEMETRY_SUPPORT_ENABLED + #endif // CHRE_CORE_TELEMETRY_MANAGER_H_
diff --git a/core/include/chre/core/wifi_request_manager.h b/core/include/chre/core/wifi_request_manager.h index b5e2708..46837d6 100644 --- a/core/include/chre/core/wifi_request_manager.h +++ b/core/include/chre/core/wifi_request_manager.h
@@ -17,6 +17,8 @@ #ifndef CHRE_CORE_WIFI_REQUEST_MANAGER_H_ #define CHRE_CORE_WIFI_REQUEST_MANAGER_H_ +#ifdef CHRE_WIFI_SUPPORT_ENABLED + #include "chre/core/api_manager_common.h" #include "chre/core/nanoapp.h" #include "chre/core/settings.h" @@ -922,4 +924,6 @@ } // namespace chre +#endif // CHRE_WIFI_SUPPORT_ENABLED + #endif // CHRE_CORE_WIFI_REQUEST_MANAGER_H_
diff --git a/core/include/chre/core/wwan_request_manager.h b/core/include/chre/core/wwan_request_manager.h index 1c1e278..9b8b1ef 100644 --- a/core/include/chre/core/wwan_request_manager.h +++ b/core/include/chre/core/wwan_request_manager.h
@@ -17,6 +17,8 @@ #ifndef CHRE_CORE_WWAN_REQUEST_MANAGER_H_ #define CHRE_CORE_WWAN_REQUEST_MANAGER_H_ +#ifdef CHRE_WWAN_SUPPORT_ENABLED + #include <cstdint> #include "chre/core/api_manager_common.h" @@ -121,4 +123,6 @@ } // namespace chre +#endif // CHRE_WWAN_SUPPORT_ENABLED + #endif // CHRE_CORE_WWAN_REQUEST_MANAGER_H_
diff --git a/core/log.cc b/core/log.cc deleted file mode 100644 index f95b888..0000000 --- a/core/log.cc +++ /dev/null
@@ -1,39 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef CHRE_TOKENIZED_LOGGING_ENABLED -#include "chre/platform/log.h" -#include "pw_log_tokenized/config.h" -#include "pw_tokenizer/encode_args.h" -#include "pw_tokenizer/tokenize.h" - -// The callback function that must be defined to handle an encoded -// tokenizer message. - -void EncodeTokenizedMessage(uint32_t level, pw_tokenizer_Token token, - pw_tokenizer_ArgTypes types, ...) { - va_list args; - va_start(args, types); - pw::tokenizer::EncodedMessage<pw::log_tokenized::kEncodingBufferSizeBytes> - encodedMessage(token, types, args); - va_end(args); - - chrePlatformEncodedLogToBuffer(static_cast<chreLogLevel>(level), - encodedMessage.data_as_uint8(), - encodedMessage.size()); -} - -#endif // CHRE_TOKENIZED_LOGGING_ENABLED
diff --git a/core/sensor_request_manager.cc b/core/sensor_request_manager.cc index 6230ccb..2888ae0 100644 --- a/core/sensor_request_manager.cc +++ b/core/sensor_request_manager.cc
@@ -14,6 +14,8 @@ * limitations under the License. */ +#ifdef CHRE_SENSORS_SUPPORT_ENABLED + #include "chre/core/sensor_request_manager.h" #include "chre/core/event_loop_manager.h" @@ -939,3 +941,5 @@ } } // namespace chre + +#endif // CHRE_SENSORS_SUPPORT_ENABLED
diff --git a/core/telemetry_manager.cc b/core/telemetry_manager.cc index 6bc32a7..70e1139 100644 --- a/core/telemetry_manager.cc +++ b/core/telemetry_manager.cc
@@ -14,13 +14,14 @@ * limitations under the License. */ +#ifdef CHRE_TELEMETRY_SUPPORT_ENABLED + #include "chre/core/telemetry_manager.h" #include <pb_encode.h> #include "chre/core/event_loop_manager.h" #include "chre/platform/fatal_error.h" -#include "chre/platform/shared/host_protocol_chre.h" #include "chre/util/macros.h" #include "chre/util/nested_data_ptr.h" #include "chre/util/time.h" @@ -173,3 +174,5 @@ } } // namespace chre + +#endif // CHRE_TELEMETRY_SUPPORT_ENABLED
diff --git a/core/timer_pool.cc b/core/timer_pool.cc index 36d032e..bb8b095 100644 --- a/core/timer_pool.cc +++ b/core/timer_pool.cc
@@ -20,8 +20,8 @@ #include "chre/core/event_loop_common.h" #include "chre/core/event_loop_manager.h" #include "chre/platform/fatal_error.h" +#include "chre/platform/log.h" #include "chre/platform/system_time.h" -#include "chre/target_platform/log.h" #include "chre/util/lock_guard.h" #include "chre/util/nested_data_ptr.h" @@ -362,11 +362,9 @@ } } - if (!EventLoopManagerSingleton::get()->getEventLoop() - .deliverEventSync( - currentTimerRequest.instanceId, - CHRE_EVENT_TIMER, - const_cast<void*>(currentTimerRequest.cookie))) { + if (!EventLoopManagerSingleton::get()->getEventLoop().distributeEventSync( + CHRE_EVENT_TIMER, const_cast<void *>(currentTimerRequest.cookie), + currentTimerRequest.instanceId)) { LOGW("Failed to deliver timer event"); } }
diff --git a/core/wifi_request_manager.cc b/core/wifi_request_manager.cc index 8aa4649..b95405b 100644 --- a/core/wifi_request_manager.cc +++ b/core/wifi_request_manager.cc
@@ -14,6 +14,8 @@ * limitations under the License. */ +#ifdef CHRE_WIFI_SUPPORT_ENABLED + #include "chre/core/wifi_request_manager.h" #include <cinttypes> @@ -1418,3 +1420,5 @@ } } // namespace chre + +#endif // CHRE_WIFI_SUPPORT_ENABLED
diff --git a/core/wwan_request_manager.cc b/core/wwan_request_manager.cc index 9fbbc92..b6ccefd 100644 --- a/core/wwan_request_manager.cc +++ b/core/wwan_request_manager.cc
@@ -14,6 +14,8 @@ * limitations under the License. */ +#ifdef CHRE_WWAN_SUPPORT_ENABLED + #include "chre/core/wwan_request_manager.h" #include "chre/core/event_loop_manager.h" @@ -127,3 +129,5 @@ } } // namespace chre + +#endif // CHRE_WWAN_SUPPORT_ENABLED
diff --git a/external/pigweed/pw_assert_nanoapp/public_overrides/pw_assert_backend/check_backend.h b/external/pigweed/pw_assert_nanoapp/public_overrides/pw_assert_backend/check_backend.h index 99029d9..b17032f 100644 --- a/external/pigweed/pw_assert_nanoapp/public_overrides/pw_assert_backend/check_backend.h +++ b/external/pigweed/pw_assert_nanoapp/public_overrides/pw_assert_backend/check_backend.h
@@ -35,6 +35,7 @@ #define PW_HANDLE_ASSERT_FAILURE(condition_string, message, ...) \ do { \ PW_LOG(PW_LOG_LEVEL_FATAL, \ + PW_LOG_LEVEL, \ PW_LOG_MODULE_NAME, \ PW_LOG_FLAGS, \ "Check failed: " condition_string ". " message, \ @@ -51,6 +52,7 @@ message, ...) \ do { \ PW_LOG(PW_LOG_LEVEL_FATAL, \ + PW_LOG_LEVEL, \ PW_LOG_MODULE_NAME, \ PW_LOG_FLAGS, \ "Check failed: " \
diff --git a/host/common/config_util.cc b/host/common/config_util.cc index fa6e985..c4e49f7 100644 --- a/host/common/config_util.cc +++ b/host/common/config_util.cc
@@ -39,8 +39,9 @@ if (!std::regex_match(entry->d_name, match, regex)) { continue; } - LOGD("Found nanoapp: %s", match[1]); - outNanoapps.push_back(match[1]); + std::string nanoapp_name = match[1]; + LOGD("Found nanoapp: %s", nanoapp_name.c_str()); + outNanoapps.push_back(nanoapp_name); } closedir(dir); return true;
diff --git a/host/common/host_protocol_host.cc b/host/common/host_protocol_host.cc index a24ec94..830f1a5 100644 --- a/host/common/host_protocol_host.cc +++ b/host/common/host_protocol_host.cc
@@ -88,9 +88,7 @@ break; default: - LOGW("Got invalid/unexpected message type %" PRIu8, - static_cast<uint8_t>(msg.type)); - success = false; + success = handlers.handleContextHubV4Message(msg); } }
diff --git a/host/common/include/chre_host/generated/host_messages_generated.h b/host/common/include/chre_host/generated/host_messages_generated.h index b386f8d..613b27f 100644 --- a/host/common/include/chre_host/generated/host_messages_generated.h +++ b/host/common/include/chre_host/generated/host_messages_generated.h
@@ -145,6 +145,90 @@ struct PulseResponseBuilder; struct PulseResponseT; +struct LeCocChannelInfo; +struct LeCocChannelInfoBuilder; +struct LeCocChannelInfoT; + +struct BtSocketOpen; +struct BtSocketOpenBuilder; +struct BtSocketOpenT; + +struct BtSocketOpenResponse; +struct BtSocketOpenResponseBuilder; +struct BtSocketOpenResponseT; + +struct BtSocketClose; +struct BtSocketCloseBuilder; +struct BtSocketCloseT; + +struct BtSocketCloseResponse; +struct BtSocketCloseResponseBuilder; +struct BtSocketCloseResponseT; + +struct VendorHubInfo; +struct VendorHubInfoBuilder; +struct VendorHubInfoT; + +struct MessageHub; +struct MessageHubBuilder; +struct MessageHubT; + +struct RegisterMessageHub; +struct RegisterMessageHubBuilder; +struct RegisterMessageHubT; + +struct UnregisterMessageHub; +struct UnregisterMessageHubBuilder; +struct UnregisterMessageHubT; + +struct EndpointId; +struct EndpointIdBuilder; +struct EndpointIdT; + +struct Service; +struct ServiceBuilder; +struct ServiceT; + +struct EndpointInfo; +struct EndpointInfoBuilder; +struct EndpointInfoT; + +struct RegisterEndpoint; +struct RegisterEndpointBuilder; +struct RegisterEndpointT; + +struct UnregisterEndpoint; +struct UnregisterEndpointBuilder; +struct UnregisterEndpointT; + +struct GetMessageHubsAndEndpointsRequest; +struct GetMessageHubsAndEndpointsRequestBuilder; +struct GetMessageHubsAndEndpointsRequestT; + +struct GetMessageHubsAndEndpointsResponse; +struct GetMessageHubsAndEndpointsResponseBuilder; +struct GetMessageHubsAndEndpointsResponseT; + +struct OpenEndpointSessionRequest; +struct OpenEndpointSessionRequestBuilder; +struct OpenEndpointSessionRequestT; + +struct EndpointSessionOpened; +struct EndpointSessionOpenedBuilder; +struct EndpointSessionOpenedT; + +struct EndpointSessionClosed; +struct EndpointSessionClosedBuilder; +struct EndpointSessionClosedT; + +struct EndpointSessionMessage; +struct EndpointSessionMessageBuilder; +struct EndpointSessionMessageT; + +struct EndpointSessionMessageDeliveryStatus; +struct EndpointSessionMessageDeliveryStatusBuilder; +struct EndpointSessionMessageDeliveryStatusT; + struct HostAddress; struct MessageContainer; @@ -327,6 +411,362 @@ return EnumNamesBtSnoopDirection()[index]; } +enum class ChannelInfo : uint8_t { + NONE = 0, + LeCocChannelInfo = 1, + MIN = NONE, + MAX = LeCocChannelInfo +}; + +inline const ChannelInfo (&EnumValuesChannelInfo())[2] { + static const ChannelInfo values[] = { + ChannelInfo::NONE, + ChannelInfo::LeCocChannelInfo + }; + return values; +} + +inline const char * const *EnumNamesChannelInfo() { + static const char * const names[3] = { + "NONE", + "LeCocChannelInfo", + nullptr + }; + return names; +} + +inline const char *EnumNameChannelInfo(ChannelInfo e) { + if (flatbuffers::IsOutRange(e, ChannelInfo::NONE, ChannelInfo::LeCocChannelInfo)) return ""; + const size_t index = static_cast<size_t>(e); + return EnumNamesChannelInfo()[index]; +} + +template<typename T> struct ChannelInfoTraits { + static const ChannelInfo enum_value = ChannelInfo::NONE; +}; + +template<> struct ChannelInfoTraits<chre::fbs::LeCocChannelInfo> { + static const ChannelInfo enum_value = ChannelInfo::LeCocChannelInfo; +}; + +struct ChannelInfoUnion { + ChannelInfo type; + void *value; + + ChannelInfoUnion() : type(ChannelInfo::NONE), value(nullptr) {} + ChannelInfoUnion(ChannelInfoUnion&& u) FLATBUFFERS_NOEXCEPT : + type(ChannelInfo::NONE), value(nullptr) + { std::swap(type, u.type); std::swap(value, u.value); } + ChannelInfoUnion(const ChannelInfoUnion &); + ChannelInfoUnion &operator=(const ChannelInfoUnion &u) + { ChannelInfoUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; } + ChannelInfoUnion &operator=(ChannelInfoUnion &&u) FLATBUFFERS_NOEXCEPT + { std::swap(type, u.type); std::swap(value, u.value); return *this; } + ~ChannelInfoUnion() { Reset(); } + + void Reset(); + +#ifndef FLATBUFFERS_CPP98_STL + template <typename T> + void Set(T&& val) { + using RT = typename std::remove_reference<T>::type; + Reset(); + type = ChannelInfoTraits<typename RT::TableType>::enum_value; + if (type != ChannelInfo::NONE) { + value = new RT(std::forward<T>(val)); + } + } +#endif // FLATBUFFERS_CPP98_STL + + static void *UnPack(const void *obj, ChannelInfo type, const flatbuffers::resolver_function_t *resolver); + flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const; + + chre::fbs::LeCocChannelInfoT *AsLeCocChannelInfo() { + return type == ChannelInfo::LeCocChannelInfo ? + reinterpret_cast<chre::fbs::LeCocChannelInfoT *>(value) : nullptr; + } + const chre::fbs::LeCocChannelInfoT *AsLeCocChannelInfo() const { + return type == ChannelInfo::LeCocChannelInfo ? + reinterpret_cast<const chre::fbs::LeCocChannelInfoT *>(value) : nullptr; + } +}; + +bool VerifyChannelInfo(flatbuffers::Verifier &verifier, const void *obj, ChannelInfo type); +bool VerifyChannelInfoVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types); + +enum class BtSocketOpenStatus : int8_t { + SUCCESS = 0, + FAILURE = 1, + MIN = SUCCESS, + MAX = FAILURE +}; + +inline const BtSocketOpenStatus (&EnumValuesBtSocketOpenStatus())[2] { + static const BtSocketOpenStatus values[] = { + BtSocketOpenStatus::SUCCESS, + BtSocketOpenStatus::FAILURE + }; + return values; +} + +inline const char * const *EnumNamesBtSocketOpenStatus() { + static const char * const names[3] = { + "SUCCESS", + "FAILURE", + nullptr + }; + return names; +} + +inline const char *EnumNameBtSocketOpenStatus(BtSocketOpenStatus e) { + if (flatbuffers::IsOutRange(e, BtSocketOpenStatus::SUCCESS, BtSocketOpenStatus::FAILURE)) return ""; + const size_t index = static_cast<size_t>(e); + return EnumNamesBtSocketOpenStatus()[index]; +} + +enum class MessageHubDetails : uint8_t { + NONE = 0, + HubInfoResponse = 1, + VendorHubInfo = 2, + MIN = NONE, + MAX = VendorHubInfo +}; + +inline const MessageHubDetails (&EnumValuesMessageHubDetails())[3] { + static const MessageHubDetails values[] = { + MessageHubDetails::NONE, + MessageHubDetails::HubInfoResponse, + MessageHubDetails::VendorHubInfo + }; + return values; +} + +inline const char * const *EnumNamesMessageHubDetails() { + static const char * const names[4] = { + "NONE", + "HubInfoResponse", + "VendorHubInfo", + nullptr + }; + return names; +} + +inline const char *EnumNameMessageHubDetails(MessageHubDetails e) { + if (flatbuffers::IsOutRange(e, MessageHubDetails::NONE, MessageHubDetails::VendorHubInfo)) return ""; + const size_t index = static_cast<size_t>(e); + return EnumNamesMessageHubDetails()[index]; +} + +template<typename T> struct MessageHubDetailsTraits { + static const MessageHubDetails enum_value = MessageHubDetails::NONE; +}; + +template<> struct MessageHubDetailsTraits<chre::fbs::HubInfoResponse> { + static const MessageHubDetails enum_value = MessageHubDetails::HubInfoResponse; +}; + +template<> struct MessageHubDetailsTraits<chre::fbs::VendorHubInfo> { + static const MessageHubDetails enum_value = MessageHubDetails::VendorHubInfo; +}; + +struct MessageHubDetailsUnion { + MessageHubDetails type; + void *value; + + MessageHubDetailsUnion() : type(MessageHubDetails::NONE), value(nullptr) {} + MessageHubDetailsUnion(MessageHubDetailsUnion&& u) FLATBUFFERS_NOEXCEPT : + type(MessageHubDetails::NONE), value(nullptr) + { std::swap(type, u.type); std::swap(value, u.value); } + MessageHubDetailsUnion(const MessageHubDetailsUnion &); + MessageHubDetailsUnion &operator=(const MessageHubDetailsUnion &u) + { MessageHubDetailsUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; } + MessageHubDetailsUnion &operator=(MessageHubDetailsUnion &&u) FLATBUFFERS_NOEXCEPT + { std::swap(type, u.type); std::swap(value, u.value); return *this; } + ~MessageHubDetailsUnion() { Reset(); } + + void Reset(); + +#ifndef FLATBUFFERS_CPP98_STL + template <typename T> + void Set(T&& val) { + using RT = typename std::remove_reference<T>::type; + Reset(); + type = MessageHubDetailsTraits<typename RT::TableType>::enum_value; + if (type != MessageHubDetails::NONE) { + value = new RT(std::forward<T>(val)); + } + } +#endif // FLATBUFFERS_CPP98_STL + + static void *UnPack(const void *obj, MessageHubDetails type, const flatbuffers::resolver_function_t *resolver); + flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const; + + chre::fbs::HubInfoResponseT *AsHubInfoResponse() { + return type == MessageHubDetails::HubInfoResponse ? + reinterpret_cast<chre::fbs::HubInfoResponseT *>(value) : nullptr; + } + const chre::fbs::HubInfoResponseT *AsHubInfoResponse() const { + return type == MessageHubDetails::HubInfoResponse ? + reinterpret_cast<const chre::fbs::HubInfoResponseT *>(value) : nullptr; + } + chre::fbs::VendorHubInfoT *AsVendorHubInfo() { + return type == MessageHubDetails::VendorHubInfo ? + reinterpret_cast<chre::fbs::VendorHubInfoT *>(value) : nullptr; + } + const chre::fbs::VendorHubInfoT *AsVendorHubInfo() const { + return type == MessageHubDetails::VendorHubInfo ? + reinterpret_cast<const chre::fbs::VendorHubInfoT *>(value) : nullptr; + } +}; + +bool VerifyMessageHubDetails(flatbuffers::Verifier &verifier, const void *obj, MessageHubDetails type); +bool VerifyMessageHubDetailsVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types); + +/// An enum describing the type of an endpoint. +enum class EndpointType : uint8_t { + INVALID = 0, + /// The endpoint is part of the Android Framework + FRAMEWORK = 1, + /// The endpoint is an Android app + APP = 2, + /// The endpoint is a native Android program + NATIVE = 3, + /// The endpoint is a nanoapp + NANOAPP = 4, + /// A generic, non-nanoapp endpoint + GENERIC = 5, + MIN = INVALID, + MAX = GENERIC +}; + +inline const EndpointType (&EnumValuesEndpointType())[6] { + static const EndpointType values[] = { + EndpointType::INVALID, + EndpointType::FRAMEWORK, + EndpointType::APP, + EndpointType::NATIVE, + EndpointType::NANOAPP, + EndpointType::GENERIC + }; + return values; +} + +inline const char * const *EnumNamesEndpointType() { + static const char * const names[7] = { + "INVALID", + "FRAMEWORK", + "APP", + "NATIVE", + "NANOAPP", + "GENERIC", + nullptr + }; + return names; +} + +inline const char *EnumNameEndpointType(EndpointType e) { + if (flatbuffers::IsOutRange(e, EndpointType::INVALID, EndpointType::GENERIC)) return ""; + const size_t index = static_cast<size_t>(e); + return EnumNamesEndpointType()[index]; +} + +enum class RpcFormat : uint8_t { + /// Fully custom format + CUSTOM = 0, + /// Stable AIDL defined interface using Binder marshalling + AIDL = 1, + /// Pigweed RPC defined interface using Protobuf marshalling + PW_RPC = 2, + MIN = CUSTOM, + MAX = PW_RPC +}; + +inline const RpcFormat (&EnumValuesRpcFormat())[3] { + static const RpcFormat values[] = { + RpcFormat::CUSTOM, + RpcFormat::AIDL, + RpcFormat::PW_RPC + }; + return values; +} + +inline const char * const *EnumNamesRpcFormat() { + static const char * const names[4] = { + "CUSTOM", + "AIDL", + "PW_RPC", + nullptr + }; + return names; +} + +inline const char *EnumNameRpcFormat(RpcFormat e) { + if (flatbuffers::IsOutRange(e, RpcFormat::CUSTOM, RpcFormat::PW_RPC)) return ""; + const size_t index = static_cast<size_t>(e); + return EnumNamesRpcFormat()[index]; +} + +/// "Reason"s for stopping an endpoint or session over an endpoint. +enum class Reason : uint8_t { + /// Unspecified reason. + UNSPECIFIED = 0, + /// Out of memory. There's not enough memory to perform this operation. + OUT_OF_MEMORY = 1, + /// Timeout. This operation timed out. + TIMEOUT = 2, + /// Endpoint rejected this openEndpointSession request. + OPEN_ENDPOINT_SESSION_REQUEST_REJECTED = 3, + /// Endpoint requested closeEndpointSession. + CLOSE_ENDPOINT_SESSION_REQUESTED = 4, + /// Invalid endpoint. + ENDPOINT_INVALID = 5, + /// Endpoint is now stopped. + ENDPOINT_GONE = 6, + /// Endpoint crashed. + ENDPOINT_CRASHED = 7, + /// Hub was reset or is resetting. + HUB_RESET = 8, + MIN = UNSPECIFIED, + MAX = HUB_RESET +}; + +inline const Reason (&EnumValuesReason())[9] { + static const Reason values[] = { + Reason::UNSPECIFIED, + Reason::OUT_OF_MEMORY, + Reason::TIMEOUT, + Reason::OPEN_ENDPOINT_SESSION_REQUEST_REJECTED, + Reason::CLOSE_ENDPOINT_SESSION_REQUESTED, + Reason::ENDPOINT_INVALID, + Reason::ENDPOINT_GONE, + Reason::ENDPOINT_CRASHED, + Reason::HUB_RESET + }; + return values; +} + +inline const char * const *EnumNamesReason() { + static const char * const names[10] = { + "UNSPECIFIED", + "OUT_OF_MEMORY", + "TIMEOUT", + "OPEN_ENDPOINT_SESSION_REQUEST_REJECTED", + "CLOSE_ENDPOINT_SESSION_REQUESTED", + "ENDPOINT_INVALID", + "ENDPOINT_GONE", + "ENDPOINT_CRASHED", + "HUB_RESET", + nullptr + }; + return names; +} + +inline const char *EnumNameReason(Reason e) { + if (flatbuffers::IsOutRange(e, Reason::UNSPECIFIED, Reason::HUB_RESET)) return ""; + const size_t index = static_cast<size_t>(e); + return EnumNamesReason()[index]; +} + /// A union that joins together all possible messages. Note that in FlatBuffers, /// unions have an implicit type enum class ChreMessage : uint8_t { @@ -363,11 +803,26 @@ PulseResponse = 30, NanoappTokenDatabaseInfo = 31, MessageDeliveryStatus = 32, + BtSocketOpen = 33, + BtSocketOpenResponse = 34, + BtSocketClose = 35, + BtSocketCloseResponse = 36, + GetMessageHubsAndEndpointsRequest = 37, + GetMessageHubsAndEndpointsResponse = 38, + RegisterMessageHub = 39, + UnregisterMessageHub = 40, + RegisterEndpoint = 41, + UnregisterEndpoint = 42, + OpenEndpointSessionRequest = 43, + EndpointSessionOpened = 44, + EndpointSessionClosed = 45, + EndpointSessionMessage = 46, + EndpointSessionMessageDeliveryStatus = 47, MIN = NONE, - MAX = MessageDeliveryStatus + MAX = EndpointSessionMessageDeliveryStatus }; -inline const ChreMessage (&EnumValuesChreMessage())[33] { +inline const ChreMessage (&EnumValuesChreMessage())[48] { static const ChreMessage values[] = { ChreMessage::NONE, ChreMessage::NanoappMessage, @@ -401,13 +856,28 @@ ChreMessage::PulseRequest, ChreMessage::PulseResponse, ChreMessage::NanoappTokenDatabaseInfo, - ChreMessage::MessageDeliveryStatus + ChreMessage::MessageDeliveryStatus, + ChreMessage::BtSocketOpen, + ChreMessage::BtSocketOpenResponse, + ChreMessage::BtSocketClose, + ChreMessage::BtSocketCloseResponse, + ChreMessage::GetMessageHubsAndEndpointsRequest, + ChreMessage::GetMessageHubsAndEndpointsResponse, + ChreMessage::RegisterMessageHub, + ChreMessage::UnregisterMessageHub, + ChreMessage::RegisterEndpoint, + ChreMessage::UnregisterEndpoint, + ChreMessage::OpenEndpointSessionRequest, + ChreMessage::EndpointSessionOpened, + ChreMessage::EndpointSessionClosed, + ChreMessage::EndpointSessionMessage, + ChreMessage::EndpointSessionMessageDeliveryStatus }; return values; } inline const char * const *EnumNamesChreMessage() { - static const char * const names[34] = { + static const char * const names[49] = { "NONE", "NanoappMessage", "HubInfoRequest", @@ -441,13 +911,28 @@ "PulseResponse", "NanoappTokenDatabaseInfo", "MessageDeliveryStatus", + "BtSocketOpen", + "BtSocketOpenResponse", + "BtSocketClose", + "BtSocketCloseResponse", + "GetMessageHubsAndEndpointsRequest", + "GetMessageHubsAndEndpointsResponse", + "RegisterMessageHub", + "UnregisterMessageHub", + "RegisterEndpoint", + "UnregisterEndpoint", + "OpenEndpointSessionRequest", + "EndpointSessionOpened", + "EndpointSessionClosed", + "EndpointSessionMessage", + "EndpointSessionMessageDeliveryStatus", nullptr }; return names; } inline const char *EnumNameChreMessage(ChreMessage e) { - if (flatbuffers::IsOutRange(e, ChreMessage::NONE, ChreMessage::MessageDeliveryStatus)) return ""; + if (flatbuffers::IsOutRange(e, ChreMessage::NONE, ChreMessage::EndpointSessionMessageDeliveryStatus)) return ""; const size_t index = static_cast<size_t>(e); return EnumNamesChreMessage()[index]; } @@ -584,6 +1069,66 @@ static const ChreMessage enum_value = ChreMessage::MessageDeliveryStatus; }; +template<> struct ChreMessageTraits<chre::fbs::BtSocketOpen> { + static const ChreMessage enum_value = ChreMessage::BtSocketOpen; +}; + +template<> struct ChreMessageTraits<chre::fbs::BtSocketOpenResponse> { + static const ChreMessage enum_value = ChreMessage::BtSocketOpenResponse; +}; + +template<> struct ChreMessageTraits<chre::fbs::BtSocketClose> { + static const ChreMessage enum_value = ChreMessage::BtSocketClose; +}; + +template<> struct ChreMessageTraits<chre::fbs::BtSocketCloseResponse> { + static const ChreMessage enum_value = ChreMessage::BtSocketCloseResponse; +}; + +template<> struct ChreMessageTraits<chre::fbs::GetMessageHubsAndEndpointsRequest> { + static const ChreMessage enum_value = ChreMessage::GetMessageHubsAndEndpointsRequest; +}; + +template<> struct ChreMessageTraits<chre::fbs::GetMessageHubsAndEndpointsResponse> { + static const ChreMessage enum_value = ChreMessage::GetMessageHubsAndEndpointsResponse; +}; + +template<> struct ChreMessageTraits<chre::fbs::RegisterMessageHub> { + static const ChreMessage enum_value = ChreMessage::RegisterMessageHub; +}; + +template<> struct ChreMessageTraits<chre::fbs::UnregisterMessageHub> { + static const ChreMessage enum_value = ChreMessage::UnregisterMessageHub; +}; + +template<> struct ChreMessageTraits<chre::fbs::RegisterEndpoint> { + static const ChreMessage enum_value = ChreMessage::RegisterEndpoint; +}; + +template<> struct ChreMessageTraits<chre::fbs::UnregisterEndpoint> { + static const ChreMessage enum_value = ChreMessage::UnregisterEndpoint; +}; + +template<> struct ChreMessageTraits<chre::fbs::OpenEndpointSessionRequest> { + static const ChreMessage enum_value = ChreMessage::OpenEndpointSessionRequest; +}; + +template<> struct ChreMessageTraits<chre::fbs::EndpointSessionOpened> { + static const ChreMessage enum_value = ChreMessage::EndpointSessionOpened; +}; + +template<> struct ChreMessageTraits<chre::fbs::EndpointSessionClosed> { + static const ChreMessage enum_value = ChreMessage::EndpointSessionClosed; +}; + +template<> struct ChreMessageTraits<chre::fbs::EndpointSessionMessage> { + static const ChreMessage enum_value = ChreMessage::EndpointSessionMessage; +}; + +template<> struct ChreMessageTraits<chre::fbs::EndpointSessionMessageDeliveryStatus> { + static const ChreMessage enum_value = ChreMessage::EndpointSessionMessageDeliveryStatus; +}; + struct ChreMessageUnion { ChreMessage type; void *value; @@ -872,6 +1417,126 @@ return type == ChreMessage::MessageDeliveryStatus ? reinterpret_cast<const chre::fbs::MessageDeliveryStatusT *>(value) : nullptr; } + chre::fbs::BtSocketOpenT *AsBtSocketOpen() { + return type == ChreMessage::BtSocketOpen ? + reinterpret_cast<chre::fbs::BtSocketOpenT *>(value) : nullptr; + } + const chre::fbs::BtSocketOpenT *AsBtSocketOpen() const { + return type == ChreMessage::BtSocketOpen ? + reinterpret_cast<const chre::fbs::BtSocketOpenT *>(value) : nullptr; + } + chre::fbs::BtSocketOpenResponseT *AsBtSocketOpenResponse() { + return type == ChreMessage::BtSocketOpenResponse ? + reinterpret_cast<chre::fbs::BtSocketOpenResponseT *>(value) : nullptr; + } + const chre::fbs::BtSocketOpenResponseT *AsBtSocketOpenResponse() const { + return type == ChreMessage::BtSocketOpenResponse ? + reinterpret_cast<const chre::fbs::BtSocketOpenResponseT *>(value) : nullptr; + } + chre::fbs::BtSocketCloseT *AsBtSocketClose() { + return type == ChreMessage::BtSocketClose ? + reinterpret_cast<chre::fbs::BtSocketCloseT *>(value) : nullptr; + } + const chre::fbs::BtSocketCloseT *AsBtSocketClose() const { + return type == ChreMessage::BtSocketClose ? + reinterpret_cast<const chre::fbs::BtSocketCloseT *>(value) : nullptr; + } + chre::fbs::BtSocketCloseResponseT *AsBtSocketCloseResponse() { + return type == ChreMessage::BtSocketCloseResponse ? + reinterpret_cast<chre::fbs::BtSocketCloseResponseT *>(value) : nullptr; + } + const chre::fbs::BtSocketCloseResponseT *AsBtSocketCloseResponse() const { + return type == ChreMessage::BtSocketCloseResponse ? + reinterpret_cast<const chre::fbs::BtSocketCloseResponseT *>(value) : nullptr; + } + chre::fbs::GetMessageHubsAndEndpointsRequestT *AsGetMessageHubsAndEndpointsRequest() { + return type == ChreMessage::GetMessageHubsAndEndpointsRequest ? + reinterpret_cast<chre::fbs::GetMessageHubsAndEndpointsRequestT *>(value) : nullptr; + } + const chre::fbs::GetMessageHubsAndEndpointsRequestT *AsGetMessageHubsAndEndpointsRequest() const { + return type == ChreMessage::GetMessageHubsAndEndpointsRequest ? + reinterpret_cast<const chre::fbs::GetMessageHubsAndEndpointsRequestT *>(value) : nullptr; + } + chre::fbs::GetMessageHubsAndEndpointsResponseT *AsGetMessageHubsAndEndpointsResponse() { + return type == ChreMessage::GetMessageHubsAndEndpointsResponse ? + reinterpret_cast<chre::fbs::GetMessageHubsAndEndpointsResponseT *>(value) : nullptr; + } + const chre::fbs::GetMessageHubsAndEndpointsResponseT *AsGetMessageHubsAndEndpointsResponse() const { + return type == ChreMessage::GetMessageHubsAndEndpointsResponse ? + reinterpret_cast<const chre::fbs::GetMessageHubsAndEndpointsResponseT *>(value) : nullptr; + } + chre::fbs::RegisterMessageHubT *AsRegisterMessageHub() { + return type == ChreMessage::RegisterMessageHub ? + reinterpret_cast<chre::fbs::RegisterMessageHubT *>(value) : nullptr; + } + const chre::fbs::RegisterMessageHubT *AsRegisterMessageHub() const { + return type == ChreMessage::RegisterMessageHub ? + reinterpret_cast<const chre::fbs::RegisterMessageHubT *>(value) : nullptr; + } + chre::fbs::UnregisterMessageHubT *AsUnregisterMessageHub() { + return type == ChreMessage::UnregisterMessageHub ? + reinterpret_cast<chre::fbs::UnregisterMessageHubT *>(value) : nullptr; + } + const chre::fbs::UnregisterMessageHubT *AsUnregisterMessageHub() const { + return type == ChreMessage::UnregisterMessageHub ? + reinterpret_cast<const chre::fbs::UnregisterMessageHubT *>(value) : nullptr; + } + chre::fbs::RegisterEndpointT *AsRegisterEndpoint() { + return type == ChreMessage::RegisterEndpoint ? + reinterpret_cast<chre::fbs::RegisterEndpointT *>(value) : nullptr; + } + const chre::fbs::RegisterEndpointT *AsRegisterEndpoint() const { + return type == ChreMessage::RegisterEndpoint ? + reinterpret_cast<const chre::fbs::RegisterEndpointT *>(value) : nullptr; + } + chre::fbs::UnregisterEndpointT *AsUnregisterEndpoint() { + return type == ChreMessage::UnregisterEndpoint ? + reinterpret_cast<chre::fbs::UnregisterEndpointT *>(value) : nullptr; + } + const chre::fbs::UnregisterEndpointT *AsUnregisterEndpoint() const { + return type == ChreMessage::UnregisterEndpoint ? + reinterpret_cast<const chre::fbs::UnregisterEndpointT *>(value) : nullptr; + } + chre::fbs::OpenEndpointSessionRequestT *AsOpenEndpointSessionRequest() { + return type == ChreMessage::OpenEndpointSessionRequest ? + reinterpret_cast<chre::fbs::OpenEndpointSessionRequestT *>(value) : nullptr; + } + const chre::fbs::OpenEndpointSessionRequestT *AsOpenEndpointSessionRequest() const { + return type == ChreMessage::OpenEndpointSessionRequest ? + reinterpret_cast<const chre::fbs::OpenEndpointSessionRequestT *>(value) : nullptr; + } + chre::fbs::EndpointSessionOpenedT *AsEndpointSessionOpened() { + return type == ChreMessage::EndpointSessionOpened ? + reinterpret_cast<chre::fbs::EndpointSessionOpenedT *>(value) : nullptr; + } + const chre::fbs::EndpointSessionOpenedT *AsEndpointSessionOpened() const { + return type == ChreMessage::EndpointSessionOpened ? + reinterpret_cast<const chre::fbs::EndpointSessionOpenedT *>(value) : nullptr; + } + chre::fbs::EndpointSessionClosedT *AsEndpointSessionClosed() { + return type == ChreMessage::EndpointSessionClosed ? + reinterpret_cast<chre::fbs::EndpointSessionClosedT *>(value) : nullptr; + } + const chre::fbs::EndpointSessionClosedT *AsEndpointSessionClosed() const { + return type == ChreMessage::EndpointSessionClosed ? + reinterpret_cast<const chre::fbs::EndpointSessionClosedT *>(value) : nullptr; + } + chre::fbs::EndpointSessionMessageT *AsEndpointSessionMessage() { + return type == ChreMessage::EndpointSessionMessage ? + reinterpret_cast<chre::fbs::EndpointSessionMessageT *>(value) : nullptr; + } + const chre::fbs::EndpointSessionMessageT *AsEndpointSessionMessage() const { + return type == ChreMessage::EndpointSessionMessage ? + reinterpret_cast<const chre::fbs::EndpointSessionMessageT *>(value) : nullptr; + } + chre::fbs::EndpointSessionMessageDeliveryStatusT *AsEndpointSessionMessageDeliveryStatus() { + return type == ChreMessage::EndpointSessionMessageDeliveryStatus ? + reinterpret_cast<chre::fbs::EndpointSessionMessageDeliveryStatusT *>(value) : nullptr; + } + const chre::fbs::EndpointSessionMessageDeliveryStatusT *AsEndpointSessionMessageDeliveryStatus() const { + return type == ChreMessage::EndpointSessionMessageDeliveryStatus ? + reinterpret_cast<const chre::fbs::EndpointSessionMessageDeliveryStatusT *>(value) : nullptr; + } }; bool VerifyChreMessage(flatbuffers::Verifier &verifier, const void *obj, ChreMessage type); @@ -3888,6 +4553,2027 @@ flatbuffers::Offset<PulseResponse> CreatePulseResponse(flatbuffers::FlatBufferBuilder &_fbb, const PulseResponseT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +struct LeCocChannelInfoT : public flatbuffers::NativeTable { + typedef LeCocChannelInfo TableType; + int32_t localCid; + int32_t remoteCid; + int32_t psm; + int32_t localMtu; + int32_t remoteMtu; + int32_t localMps; + int32_t remoteMps; + int32_t initialRxCredits; + int32_t initialTxCredits; + LeCocChannelInfoT() + : localCid(0), + remoteCid(0), + psm(0), + localMtu(0), + remoteMtu(0), + localMps(0), + remoteMps(0), + initialRxCredits(0), + initialTxCredits(0) { + } +}; + +struct LeCocChannelInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef LeCocChannelInfoT NativeTableType; + typedef LeCocChannelInfoBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_LOCALCID = 4, + VT_REMOTECID = 6, + VT_PSM = 8, + VT_LOCALMTU = 10, + VT_REMOTEMTU = 12, + VT_LOCALMPS = 14, + VT_REMOTEMPS = 16, + VT_INITIALRXCREDITS = 18, + VT_INITIALTXCREDITS = 20 + }; + int32_t localCid() const { + return GetField<int32_t>(VT_LOCALCID, 0); + } + bool mutate_localCid(int32_t _localCid) { + return SetField<int32_t>(VT_LOCALCID, _localCid, 0); + } + int32_t remoteCid() const { + return GetField<int32_t>(VT_REMOTECID, 0); + } + bool mutate_remoteCid(int32_t _remoteCid) { + return SetField<int32_t>(VT_REMOTECID, _remoteCid, 0); + } + int32_t psm() const { + return GetField<int32_t>(VT_PSM, 0); + } + bool mutate_psm(int32_t _psm) { + return SetField<int32_t>(VT_PSM, _psm, 0); + } + int32_t localMtu() const { + return GetField<int32_t>(VT_LOCALMTU, 0); + } + bool mutate_localMtu(int32_t _localMtu) { + return SetField<int32_t>(VT_LOCALMTU, _localMtu, 0); + } + int32_t remoteMtu() const { + return GetField<int32_t>(VT_REMOTEMTU, 0); + } + bool mutate_remoteMtu(int32_t _remoteMtu) { + return SetField<int32_t>(VT_REMOTEMTU, _remoteMtu, 0); + } + int32_t localMps() const { + return GetField<int32_t>(VT_LOCALMPS, 0); + } + bool mutate_localMps(int32_t _localMps) { + return SetField<int32_t>(VT_LOCALMPS, _localMps, 0); + } + int32_t remoteMps() const { + return GetField<int32_t>(VT_REMOTEMPS, 0); + } + bool mutate_remoteMps(int32_t _remoteMps) { + return SetField<int32_t>(VT_REMOTEMPS, _remoteMps, 0); + } + int32_t initialRxCredits() const { + return GetField<int32_t>(VT_INITIALRXCREDITS, 0); + } + bool mutate_initialRxCredits(int32_t _initialRxCredits) { + return SetField<int32_t>(VT_INITIALRXCREDITS, _initialRxCredits, 0); + } + int32_t initialTxCredits() const { + return GetField<int32_t>(VT_INITIALTXCREDITS, 0); + } + bool mutate_initialTxCredits(int32_t _initialTxCredits) { + return SetField<int32_t>(VT_INITIALTXCREDITS, _initialTxCredits, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<int32_t>(verifier, VT_LOCALCID) && + VerifyField<int32_t>(verifier, VT_REMOTECID) && + VerifyField<int32_t>(verifier, VT_PSM) && + VerifyField<int32_t>(verifier, VT_LOCALMTU) && + VerifyField<int32_t>(verifier, VT_REMOTEMTU) && + VerifyField<int32_t>(verifier, VT_LOCALMPS) && + VerifyField<int32_t>(verifier, VT_REMOTEMPS) && + VerifyField<int32_t>(verifier, VT_INITIALRXCREDITS) && + VerifyField<int32_t>(verifier, VT_INITIALTXCREDITS) && + verifier.EndTable(); + } + LeCocChannelInfoT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(LeCocChannelInfoT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<LeCocChannelInfo> Pack(flatbuffers::FlatBufferBuilder &_fbb, const LeCocChannelInfoT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct LeCocChannelInfoBuilder { + typedef LeCocChannelInfo Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_localCid(int32_t localCid) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_LOCALCID, localCid, 0); + } + void add_remoteCid(int32_t remoteCid) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_REMOTECID, remoteCid, 0); + } + void add_psm(int32_t psm) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_PSM, psm, 0); + } + void add_localMtu(int32_t localMtu) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_LOCALMTU, localMtu, 0); + } + void add_remoteMtu(int32_t remoteMtu) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_REMOTEMTU, remoteMtu, 0); + } + void add_localMps(int32_t localMps) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_LOCALMPS, localMps, 0); + } + void add_remoteMps(int32_t remoteMps) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_REMOTEMPS, remoteMps, 0); + } + void add_initialRxCredits(int32_t initialRxCredits) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_INITIALRXCREDITS, initialRxCredits, 0); + } + void add_initialTxCredits(int32_t initialTxCredits) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_INITIALTXCREDITS, initialTxCredits, 0); + } + explicit LeCocChannelInfoBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + LeCocChannelInfoBuilder &operator=(const LeCocChannelInfoBuilder &); + flatbuffers::Offset<LeCocChannelInfo> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<LeCocChannelInfo>(end); + return o; + } +}; + +inline flatbuffers::Offset<LeCocChannelInfo> CreateLeCocChannelInfo( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t localCid = 0, + int32_t remoteCid = 0, + int32_t psm = 0, + int32_t localMtu = 0, + int32_t remoteMtu = 0, + int32_t localMps = 0, + int32_t remoteMps = 0, + int32_t initialRxCredits = 0, + int32_t initialTxCredits = 0) { + LeCocChannelInfoBuilder builder_(_fbb); + builder_.add_initialTxCredits(initialTxCredits); + builder_.add_initialRxCredits(initialRxCredits); + builder_.add_remoteMps(remoteMps); + builder_.add_localMps(localMps); + builder_.add_remoteMtu(remoteMtu); + builder_.add_localMtu(localMtu); + builder_.add_psm(psm); + builder_.add_remoteCid(remoteCid); + builder_.add_localCid(localCid); + return builder_.Finish(); +} + +flatbuffers::Offset<LeCocChannelInfo> CreateLeCocChannelInfo(flatbuffers::FlatBufferBuilder &_fbb, const LeCocChannelInfoT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct BtSocketOpenT : public flatbuffers::NativeTable { + typedef BtSocketOpen TableType; + int64_t socketId; + std::vector<int8_t> name; + int32_t aclConnectionHandle; + chre::fbs::ChannelInfoUnion channelInfo; + int64_t hubId; + int64_t endpointId; + BtSocketOpenT() + : socketId(0), + aclConnectionHandle(0), + hubId(0), + endpointId(0) { + } +}; + +struct BtSocketOpen FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef BtSocketOpenT NativeTableType; + typedef BtSocketOpenBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SOCKETID = 4, + VT_NAME = 6, + VT_ACLCONNECTIONHANDLE = 8, + VT_CHANNELINFO_TYPE = 10, + VT_CHANNELINFO = 12, + VT_HUBID = 14, + VT_ENDPOINTID = 16 + }; + int64_t socketId() const { + return GetField<int64_t>(VT_SOCKETID, 0); + } + bool mutate_socketId(int64_t _socketId) { + return SetField<int64_t>(VT_SOCKETID, _socketId, 0); + } + const flatbuffers::Vector<int8_t> *name() const { + return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_NAME); + } + flatbuffers::Vector<int8_t> *mutable_name() { + return GetPointer<flatbuffers::Vector<int8_t> *>(VT_NAME); + } + int32_t aclConnectionHandle() const { + return GetField<int32_t>(VT_ACLCONNECTIONHANDLE, 0); + } + bool mutate_aclConnectionHandle(int32_t _aclConnectionHandle) { + return SetField<int32_t>(VT_ACLCONNECTIONHANDLE, _aclConnectionHandle, 0); + } + chre::fbs::ChannelInfo channelInfo_type() const { + return static_cast<chre::fbs::ChannelInfo>(GetField<uint8_t>(VT_CHANNELINFO_TYPE, 0)); + } + const void *channelInfo() const { + return GetPointer<const void *>(VT_CHANNELINFO); + } + template<typename T> const T *channelInfo_as() const; + const chre::fbs::LeCocChannelInfo *channelInfo_as_LeCocChannelInfo() const { + return channelInfo_type() == chre::fbs::ChannelInfo::LeCocChannelInfo ? static_cast<const chre::fbs::LeCocChannelInfo *>(channelInfo()) : nullptr; + } + void *mutable_channelInfo() { + return GetPointer<void *>(VT_CHANNELINFO); + } + int64_t hubId() const { + return GetField<int64_t>(VT_HUBID, 0); + } + bool mutate_hubId(int64_t _hubId) { + return SetField<int64_t>(VT_HUBID, _hubId, 0); + } + int64_t endpointId() const { + return GetField<int64_t>(VT_ENDPOINTID, 0); + } + bool mutate_endpointId(int64_t _endpointId) { + return SetField<int64_t>(VT_ENDPOINTID, _endpointId, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<int64_t>(verifier, VT_SOCKETID) && + VerifyOffset(verifier, VT_NAME) && + verifier.VerifyVector(name()) && + VerifyField<int32_t>(verifier, VT_ACLCONNECTIONHANDLE) && + VerifyField<uint8_t>(verifier, VT_CHANNELINFO_TYPE) && + VerifyOffset(verifier, VT_CHANNELINFO) && + VerifyChannelInfo(verifier, channelInfo(), channelInfo_type()) && + VerifyField<int64_t>(verifier, VT_HUBID) && + VerifyField<int64_t>(verifier, VT_ENDPOINTID) && + verifier.EndTable(); + } + BtSocketOpenT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(BtSocketOpenT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<BtSocketOpen> Pack(flatbuffers::FlatBufferBuilder &_fbb, const BtSocketOpenT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +template<> inline const chre::fbs::LeCocChannelInfo *BtSocketOpen::channelInfo_as<chre::fbs::LeCocChannelInfo>() const { + return channelInfo_as_LeCocChannelInfo(); +} + +struct BtSocketOpenBuilder { + typedef BtSocketOpen Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_socketId(int64_t socketId) { + fbb_.AddElement<int64_t>(BtSocketOpen::VT_SOCKETID, socketId, 0); + } + void add_name(flatbuffers::Offset<flatbuffers::Vector<int8_t>> name) { + fbb_.AddOffset(BtSocketOpen::VT_NAME, name); + } + void add_aclConnectionHandle(int32_t aclConnectionHandle) { + fbb_.AddElement<int32_t>(BtSocketOpen::VT_ACLCONNECTIONHANDLE, aclConnectionHandle, 0); + } + void add_channelInfo_type(chre::fbs::ChannelInfo channelInfo_type) { + fbb_.AddElement<uint8_t>(BtSocketOpen::VT_CHANNELINFO_TYPE, static_cast<uint8_t>(channelInfo_type), 0); + } + void add_channelInfo(flatbuffers::Offset<void> channelInfo) { + fbb_.AddOffset(BtSocketOpen::VT_CHANNELINFO, channelInfo); + } + void add_hubId(int64_t hubId) { + fbb_.AddElement<int64_t>(BtSocketOpen::VT_HUBID, hubId, 0); + } + void add_endpointId(int64_t endpointId) { + fbb_.AddElement<int64_t>(BtSocketOpen::VT_ENDPOINTID, endpointId, 0); + } + explicit BtSocketOpenBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + BtSocketOpenBuilder &operator=(const BtSocketOpenBuilder &); + flatbuffers::Offset<BtSocketOpen> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<BtSocketOpen>(end); + return o; + } +}; + +inline flatbuffers::Offset<BtSocketOpen> CreateBtSocketOpen( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t socketId = 0, + flatbuffers::Offset<flatbuffers::Vector<int8_t>> name = 0, + int32_t aclConnectionHandle = 0, + chre::fbs::ChannelInfo channelInfo_type = chre::fbs::ChannelInfo::NONE, + flatbuffers::Offset<void> channelInfo = 0, + int64_t hubId = 0, + int64_t endpointId = 0) { + BtSocketOpenBuilder builder_(_fbb); + builder_.add_endpointId(endpointId); + builder_.add_hubId(hubId); + builder_.add_socketId(socketId); + builder_.add_channelInfo(channelInfo); + builder_.add_aclConnectionHandle(aclConnectionHandle); + builder_.add_name(name); + builder_.add_channelInfo_type(channelInfo_type); + return builder_.Finish(); +} + +inline flatbuffers::Offset<BtSocketOpen> CreateBtSocketOpenDirect( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t socketId = 0, + const std::vector<int8_t> *name = nullptr, + int32_t aclConnectionHandle = 0, + chre::fbs::ChannelInfo channelInfo_type = chre::fbs::ChannelInfo::NONE, + flatbuffers::Offset<void> channelInfo = 0, + int64_t hubId = 0, + int64_t endpointId = 0) { + auto name__ = name ? _fbb.CreateVector<int8_t>(*name) : 0; + return chre::fbs::CreateBtSocketOpen( + _fbb, + socketId, + name__, + aclConnectionHandle, + channelInfo_type, + channelInfo, + hubId, + endpointId); +} + +flatbuffers::Offset<BtSocketOpen> CreateBtSocketOpen(flatbuffers::FlatBufferBuilder &_fbb, const BtSocketOpenT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct BtSocketOpenResponseT : public flatbuffers::NativeTable { + typedef BtSocketOpenResponse TableType; + int64_t socketId; + chre::fbs::BtSocketOpenStatus status; + std::vector<int8_t> reason; + BtSocketOpenResponseT() + : socketId(0), + status(chre::fbs::BtSocketOpenStatus::SUCCESS) { + } +}; + +struct BtSocketOpenResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef BtSocketOpenResponseT NativeTableType; + typedef BtSocketOpenResponseBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SOCKETID = 4, + VT_STATUS = 6, + VT_REASON = 8 + }; + int64_t socketId() const { + return GetField<int64_t>(VT_SOCKETID, 0); + } + bool mutate_socketId(int64_t _socketId) { + return SetField<int64_t>(VT_SOCKETID, _socketId, 0); + } + chre::fbs::BtSocketOpenStatus status() const { + return static_cast<chre::fbs::BtSocketOpenStatus>(GetField<int8_t>(VT_STATUS, 0)); + } + bool mutate_status(chre::fbs::BtSocketOpenStatus _status) { + return SetField<int8_t>(VT_STATUS, static_cast<int8_t>(_status), 0); + } + const flatbuffers::Vector<int8_t> *reason() const { + return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_REASON); + } + flatbuffers::Vector<int8_t> *mutable_reason() { + return GetPointer<flatbuffers::Vector<int8_t> *>(VT_REASON); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<int64_t>(verifier, VT_SOCKETID) && + VerifyField<int8_t>(verifier, VT_STATUS) && + VerifyOffset(verifier, VT_REASON) && + verifier.VerifyVector(reason()) && + verifier.EndTable(); + } + BtSocketOpenResponseT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(BtSocketOpenResponseT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<BtSocketOpenResponse> Pack(flatbuffers::FlatBufferBuilder &_fbb, const BtSocketOpenResponseT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct BtSocketOpenResponseBuilder { + typedef BtSocketOpenResponse Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_socketId(int64_t socketId) { + fbb_.AddElement<int64_t>(BtSocketOpenResponse::VT_SOCKETID, socketId, 0); + } + void add_status(chre::fbs::BtSocketOpenStatus status) { + fbb_.AddElement<int8_t>(BtSocketOpenResponse::VT_STATUS, static_cast<int8_t>(status), 0); + } + void add_reason(flatbuffers::Offset<flatbuffers::Vector<int8_t>> reason) { + fbb_.AddOffset(BtSocketOpenResponse::VT_REASON, reason); + } + explicit BtSocketOpenResponseBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + BtSocketOpenResponseBuilder &operator=(const BtSocketOpenResponseBuilder &); + flatbuffers::Offset<BtSocketOpenResponse> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<BtSocketOpenResponse>(end); + return o; + } +}; + +inline flatbuffers::Offset<BtSocketOpenResponse> CreateBtSocketOpenResponse( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t socketId = 0, + chre::fbs::BtSocketOpenStatus status = chre::fbs::BtSocketOpenStatus::SUCCESS, + flatbuffers::Offset<flatbuffers::Vector<int8_t>> reason = 0) { + BtSocketOpenResponseBuilder builder_(_fbb); + builder_.add_socketId(socketId); + builder_.add_reason(reason); + builder_.add_status(status); + return builder_.Finish(); +} + +inline flatbuffers::Offset<BtSocketOpenResponse> CreateBtSocketOpenResponseDirect( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t socketId = 0, + chre::fbs::BtSocketOpenStatus status = chre::fbs::BtSocketOpenStatus::SUCCESS, + const std::vector<int8_t> *reason = nullptr) { + auto reason__ = reason ? _fbb.CreateVector<int8_t>(*reason) : 0; + return chre::fbs::CreateBtSocketOpenResponse( + _fbb, + socketId, + status, + reason__); +} + +flatbuffers::Offset<BtSocketOpenResponse> CreateBtSocketOpenResponse(flatbuffers::FlatBufferBuilder &_fbb, const BtSocketOpenResponseT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct BtSocketCloseT : public flatbuffers::NativeTable { + typedef BtSocketClose TableType; + int64_t socketId; + std::vector<int8_t> reason; + BtSocketCloseT() + : socketId(0) { + } +}; + +struct BtSocketClose FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef BtSocketCloseT NativeTableType; + typedef BtSocketCloseBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SOCKETID = 4, + VT_REASON = 6 + }; + int64_t socketId() const { + return GetField<int64_t>(VT_SOCKETID, 0); + } + bool mutate_socketId(int64_t _socketId) { + return SetField<int64_t>(VT_SOCKETID, _socketId, 0); + } + const flatbuffers::Vector<int8_t> *reason() const { + return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_REASON); + } + flatbuffers::Vector<int8_t> *mutable_reason() { + return GetPointer<flatbuffers::Vector<int8_t> *>(VT_REASON); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<int64_t>(verifier, VT_SOCKETID) && + VerifyOffset(verifier, VT_REASON) && + verifier.VerifyVector(reason()) && + verifier.EndTable(); + } + BtSocketCloseT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(BtSocketCloseT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<BtSocketClose> Pack(flatbuffers::FlatBufferBuilder &_fbb, const BtSocketCloseT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct BtSocketCloseBuilder { + typedef BtSocketClose Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_socketId(int64_t socketId) { + fbb_.AddElement<int64_t>(BtSocketClose::VT_SOCKETID, socketId, 0); + } + void add_reason(flatbuffers::Offset<flatbuffers::Vector<int8_t>> reason) { + fbb_.AddOffset(BtSocketClose::VT_REASON, reason); + } + explicit BtSocketCloseBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + BtSocketCloseBuilder &operator=(const BtSocketCloseBuilder &); + flatbuffers::Offset<BtSocketClose> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<BtSocketClose>(end); + return o; + } +}; + +inline flatbuffers::Offset<BtSocketClose> CreateBtSocketClose( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t socketId = 0, + flatbuffers::Offset<flatbuffers::Vector<int8_t>> reason = 0) { + BtSocketCloseBuilder builder_(_fbb); + builder_.add_socketId(socketId); + builder_.add_reason(reason); + return builder_.Finish(); +} + +inline flatbuffers::Offset<BtSocketClose> CreateBtSocketCloseDirect( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t socketId = 0, + const std::vector<int8_t> *reason = nullptr) { + auto reason__ = reason ? _fbb.CreateVector<int8_t>(*reason) : 0; + return chre::fbs::CreateBtSocketClose( + _fbb, + socketId, + reason__); +} + +flatbuffers::Offset<BtSocketClose> CreateBtSocketClose(flatbuffers::FlatBufferBuilder &_fbb, const BtSocketCloseT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct BtSocketCloseResponseT : public flatbuffers::NativeTable { + typedef BtSocketCloseResponse TableType; + int64_t socketId; + BtSocketCloseResponseT() + : socketId(0) { + } +}; + +struct BtSocketCloseResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef BtSocketCloseResponseT NativeTableType; + typedef BtSocketCloseResponseBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SOCKETID = 4 + }; + int64_t socketId() const { + return GetField<int64_t>(VT_SOCKETID, 0); + } + bool mutate_socketId(int64_t _socketId) { + return SetField<int64_t>(VT_SOCKETID, _socketId, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<int64_t>(verifier, VT_SOCKETID) && + verifier.EndTable(); + } + BtSocketCloseResponseT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(BtSocketCloseResponseT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<BtSocketCloseResponse> Pack(flatbuffers::FlatBufferBuilder &_fbb, const BtSocketCloseResponseT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct BtSocketCloseResponseBuilder { + typedef BtSocketCloseResponse Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_socketId(int64_t socketId) { + fbb_.AddElement<int64_t>(BtSocketCloseResponse::VT_SOCKETID, socketId, 0); + } + explicit BtSocketCloseResponseBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + BtSocketCloseResponseBuilder &operator=(const BtSocketCloseResponseBuilder &); + flatbuffers::Offset<BtSocketCloseResponse> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<BtSocketCloseResponse>(end); + return o; + } +}; + +inline flatbuffers::Offset<BtSocketCloseResponse> CreateBtSocketCloseResponse( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t socketId = 0) { + BtSocketCloseResponseBuilder builder_(_fbb); + builder_.add_socketId(socketId); + return builder_.Finish(); +} + +flatbuffers::Offset<BtSocketCloseResponse> CreateBtSocketCloseResponse(flatbuffers::FlatBufferBuilder &_fbb, const BtSocketCloseResponseT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct VendorHubInfoT : public flatbuffers::NativeTable { + typedef VendorHubInfo TableType; + std::vector<int8_t> name; + uint32_t version; + std::vector<uint8_t> extended_info; + VendorHubInfoT() + : version(0) { + } +}; + +struct VendorHubInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef VendorHubInfoT NativeTableType; + typedef VendorHubInfoBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NAME = 4, + VT_VERSION = 6, + VT_EXTENDED_INFO = 8 + }; + /// The name of the hub. Nominally a UTF-8 string, but note that we're not + /// using the built-in "string" data type from FlatBuffers here, because the + /// generated C++ uses std::string which is not well-supported in CHRE. + const flatbuffers::Vector<int8_t> *name() const { + return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_NAME); + } + flatbuffers::Vector<int8_t> *mutable_name() { + return GetPointer<flatbuffers::Vector<int8_t> *>(VT_NAME); + } + /// Hub version + uint32_t version() const { + return GetField<uint32_t>(VT_VERSION, 0); + } + bool mutate_version(uint32_t _version) { + return SetField<uint32_t>(VT_VERSION, _version, 0); + } + /// Additional vendor-defined data + const flatbuffers::Vector<uint8_t> *extended_info() const { + return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_EXTENDED_INFO); + } + flatbuffers::Vector<uint8_t> *mutable_extended_info() { + return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_EXTENDED_INFO); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_NAME) && + verifier.VerifyVector(name()) && + VerifyField<uint32_t>(verifier, VT_VERSION) && + VerifyOffset(verifier, VT_EXTENDED_INFO) && + verifier.VerifyVector(extended_info()) && + verifier.EndTable(); + } + VendorHubInfoT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(VendorHubInfoT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<VendorHubInfo> Pack(flatbuffers::FlatBufferBuilder &_fbb, const VendorHubInfoT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct VendorHubInfoBuilder { + typedef VendorHubInfo Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_name(flatbuffers::Offset<flatbuffers::Vector<int8_t>> name) { + fbb_.AddOffset(VendorHubInfo::VT_NAME, name); + } + void add_version(uint32_t version) { + fbb_.AddElement<uint32_t>(VendorHubInfo::VT_VERSION, version, 0); + } + void add_extended_info(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> extended_info) { + fbb_.AddOffset(VendorHubInfo::VT_EXTENDED_INFO, extended_info); + } + explicit VendorHubInfoBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + VendorHubInfoBuilder &operator=(const VendorHubInfoBuilder &); + flatbuffers::Offset<VendorHubInfo> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<VendorHubInfo>(end); + return o; + } +}; + +inline flatbuffers::Offset<VendorHubInfo> CreateVendorHubInfo( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<flatbuffers::Vector<int8_t>> name = 0, + uint32_t version = 0, + flatbuffers::Offset<flatbuffers::Vector<uint8_t>> extended_info = 0) { + VendorHubInfoBuilder builder_(_fbb); + builder_.add_extended_info(extended_info); + builder_.add_version(version); + builder_.add_name(name); + return builder_.Finish(); +} + +inline flatbuffers::Offset<VendorHubInfo> CreateVendorHubInfoDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector<int8_t> *name = nullptr, + uint32_t version = 0, + const std::vector<uint8_t> *extended_info = nullptr) { + auto name__ = name ? _fbb.CreateVector<int8_t>(*name) : 0; + auto extended_info__ = extended_info ? _fbb.CreateVector<uint8_t>(*extended_info) : 0; + return chre::fbs::CreateVendorHubInfo( + _fbb, + name__, + version, + extended_info__); +} + +flatbuffers::Offset<VendorHubInfo> CreateVendorHubInfo(flatbuffers::FlatBufferBuilder &_fbb, const VendorHubInfoT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct MessageHubT : public flatbuffers::NativeTable { + typedef MessageHub TableType; + int64_t id; + chre::fbs::MessageHubDetailsUnion details; + MessageHubT() + : id(0) { + } +}; + +struct MessageHub FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef MessageHubT NativeTableType; + typedef MessageHubBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ID = 4, + VT_DETAILS_TYPE = 6, + VT_DETAILS = 8 + }; + /// The hub id. -1 is reserved and 0 is invalid. 0x416e64726f696400 represents + /// the ContextHub service. + int64_t id() const { + return GetField<int64_t>(VT_ID, 0); + } + bool mutate_id(int64_t _id) { + return SetField<int64_t>(VT_ID, _id, 0); + } + chre::fbs::MessageHubDetails details_type() const { + return static_cast<chre::fbs::MessageHubDetails>(GetField<uint8_t>(VT_DETAILS_TYPE, 0)); + } + /// Details of the message hub. + const void *details() const { + return GetPointer<const void *>(VT_DETAILS); + } + template<typename T> const T *details_as() const; + const chre::fbs::HubInfoResponse *details_as_HubInfoResponse() const { + return details_type() == chre::fbs::MessageHubDetails::HubInfoResponse ? static_cast<const chre::fbs::HubInfoResponse *>(details()) : nullptr; + } + const chre::fbs::VendorHubInfo *details_as_VendorHubInfo() const { + return details_type() == chre::fbs::MessageHubDetails::VendorHubInfo ? static_cast<const chre::fbs::VendorHubInfo *>(details()) : nullptr; + } + void *mutable_details() { + return GetPointer<void *>(VT_DETAILS); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<int64_t>(verifier, VT_ID) && + VerifyField<uint8_t>(verifier, VT_DETAILS_TYPE) && + VerifyOffset(verifier, VT_DETAILS) && + VerifyMessageHubDetails(verifier, details(), details_type()) && + verifier.EndTable(); + } + MessageHubT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(MessageHubT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<MessageHub> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MessageHubT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +template<> inline const chre::fbs::HubInfoResponse *MessageHub::details_as<chre::fbs::HubInfoResponse>() const { + return details_as_HubInfoResponse(); +} + +template<> inline const chre::fbs::VendorHubInfo *MessageHub::details_as<chre::fbs::VendorHubInfo>() const { + return details_as_VendorHubInfo(); +} + +struct MessageHubBuilder { + typedef MessageHub Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_id(int64_t id) { + fbb_.AddElement<int64_t>(MessageHub::VT_ID, id, 0); + } + void add_details_type(chre::fbs::MessageHubDetails details_type) { + fbb_.AddElement<uint8_t>(MessageHub::VT_DETAILS_TYPE, static_cast<uint8_t>(details_type), 0); + } + void add_details(flatbuffers::Offset<void> details) { + fbb_.AddOffset(MessageHub::VT_DETAILS, details); + } + explicit MessageHubBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + MessageHubBuilder &operator=(const MessageHubBuilder &); + flatbuffers::Offset<MessageHub> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<MessageHub>(end); + return o; + } +}; + +inline flatbuffers::Offset<MessageHub> CreateMessageHub( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t id = 0, + chre::fbs::MessageHubDetails details_type = chre::fbs::MessageHubDetails::NONE, + flatbuffers::Offset<void> details = 0) { + MessageHubBuilder builder_(_fbb); + builder_.add_id(id); + builder_.add_details(details); + builder_.add_details_type(details_type); + return builder_.Finish(); +} + +flatbuffers::Offset<MessageHub> CreateMessageHub(flatbuffers::FlatBufferBuilder &_fbb, const MessageHubT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct RegisterMessageHubT : public flatbuffers::NativeTable { + typedef RegisterMessageHub TableType; + std::unique_ptr<chre::fbs::MessageHubT> hub; + RegisterMessageHubT() { + } +}; + +struct RegisterMessageHub FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RegisterMessageHubT NativeTableType; + typedef RegisterMessageHubBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_HUB = 4 + }; + const chre::fbs::MessageHub *hub() const { + return GetPointer<const chre::fbs::MessageHub *>(VT_HUB); + } + chre::fbs::MessageHub *mutable_hub() { + return GetPointer<chre::fbs::MessageHub *>(VT_HUB); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_HUB) && + verifier.VerifyTable(hub()) && + verifier.EndTable(); + } + RegisterMessageHubT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(RegisterMessageHubT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<RegisterMessageHub> Pack(flatbuffers::FlatBufferBuilder &_fbb, const RegisterMessageHubT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct RegisterMessageHubBuilder { + typedef RegisterMessageHub Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_hub(flatbuffers::Offset<chre::fbs::MessageHub> hub) { + fbb_.AddOffset(RegisterMessageHub::VT_HUB, hub); + } + explicit RegisterMessageHubBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + RegisterMessageHubBuilder &operator=(const RegisterMessageHubBuilder &); + flatbuffers::Offset<RegisterMessageHub> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<RegisterMessageHub>(end); + return o; + } +}; + +inline flatbuffers::Offset<RegisterMessageHub> CreateRegisterMessageHub( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<chre::fbs::MessageHub> hub = 0) { + RegisterMessageHubBuilder builder_(_fbb); + builder_.add_hub(hub); + return builder_.Finish(); +} + +flatbuffers::Offset<RegisterMessageHub> CreateRegisterMessageHub(flatbuffers::FlatBufferBuilder &_fbb, const RegisterMessageHubT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct UnregisterMessageHubT : public flatbuffers::NativeTable { + typedef UnregisterMessageHub TableType; + int64_t id; + UnregisterMessageHubT() + : id(0) { + } +}; + +struct UnregisterMessageHub FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef UnregisterMessageHubT NativeTableType; + typedef UnregisterMessageHubBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ID = 4 + }; + int64_t id() const { + return GetField<int64_t>(VT_ID, 0); + } + bool mutate_id(int64_t _id) { + return SetField<int64_t>(VT_ID, _id, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<int64_t>(verifier, VT_ID) && + verifier.EndTable(); + } + UnregisterMessageHubT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(UnregisterMessageHubT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<UnregisterMessageHub> Pack(flatbuffers::FlatBufferBuilder &_fbb, const UnregisterMessageHubT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct UnregisterMessageHubBuilder { + typedef UnregisterMessageHub Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_id(int64_t id) { + fbb_.AddElement<int64_t>(UnregisterMessageHub::VT_ID, id, 0); + } + explicit UnregisterMessageHubBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + UnregisterMessageHubBuilder &operator=(const UnregisterMessageHubBuilder &); + flatbuffers::Offset<UnregisterMessageHub> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<UnregisterMessageHub>(end); + return o; + } +}; + +inline flatbuffers::Offset<UnregisterMessageHub> CreateUnregisterMessageHub( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t id = 0) { + UnregisterMessageHubBuilder builder_(_fbb); + builder_.add_id(id); + return builder_.Finish(); +} + +flatbuffers::Offset<UnregisterMessageHub> CreateUnregisterMessageHub(flatbuffers::FlatBufferBuilder &_fbb, const UnregisterMessageHubT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct EndpointIdT : public flatbuffers::NativeTable { + typedef EndpointId TableType; + int64_t hubId; + int64_t id; + EndpointIdT() + : hubId(0), + id(0) { + } +}; + +struct EndpointId FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef EndpointIdT NativeTableType; + typedef EndpointIdBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_HUBID = 4, + VT_ID = 6 + }; + /// Id of the hub hosting the endpoint + int64_t hubId() const { + return GetField<int64_t>(VT_HUBID, 0); + } + bool mutate_hubId(int64_t _hubId) { + return SetField<int64_t>(VT_HUBID, _hubId, 0); + } + /// The id of the endpoint scoped to the hub + int64_t id() const { + return GetField<int64_t>(VT_ID, 0); + } + bool mutate_id(int64_t _id) { + return SetField<int64_t>(VT_ID, _id, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<int64_t>(verifier, VT_HUBID) && + VerifyField<int64_t>(verifier, VT_ID) && + verifier.EndTable(); + } + EndpointIdT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(EndpointIdT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<EndpointId> Pack(flatbuffers::FlatBufferBuilder &_fbb, const EndpointIdT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct EndpointIdBuilder { + typedef EndpointId Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_hubId(int64_t hubId) { + fbb_.AddElement<int64_t>(EndpointId::VT_HUBID, hubId, 0); + } + void add_id(int64_t id) { + fbb_.AddElement<int64_t>(EndpointId::VT_ID, id, 0); + } + explicit EndpointIdBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + EndpointIdBuilder &operator=(const EndpointIdBuilder &); + flatbuffers::Offset<EndpointId> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<EndpointId>(end); + return o; + } +}; + +inline flatbuffers::Offset<EndpointId> CreateEndpointId( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t hubId = 0, + int64_t id = 0) { + EndpointIdBuilder builder_(_fbb); + builder_.add_id(id); + builder_.add_hubId(hubId); + return builder_.Finish(); +} + +flatbuffers::Offset<EndpointId> CreateEndpointId(flatbuffers::FlatBufferBuilder &_fbb, const EndpointIdT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ServiceT : public flatbuffers::NativeTable { + typedef Service TableType; + chre::fbs::RpcFormat format; + std::vector<int8_t> descriptor; + uint32_t major_version; + uint32_t minor_version; + ServiceT() + : format(chre::fbs::RpcFormat::CUSTOM), + major_version(0), + minor_version(0) { + } +}; + +struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ServiceT NativeTableType; + typedef ServiceBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_FORMAT = 4, + VT_DESCRIPTOR = 6, + VT_MAJOR_VERSION = 8, + VT_MINOR_VERSION = 10 + }; + chre::fbs::RpcFormat format() const { + return static_cast<chre::fbs::RpcFormat>(GetField<uint8_t>(VT_FORMAT, 0)); + } + bool mutate_format(chre::fbs::RpcFormat _format) { + return SetField<uint8_t>(VT_FORMAT, static_cast<uint8_t>(_format), 0); + } + /// Service descriptor. Nominally a UTF-8 string, but note that we're not + /// using the built-in "string" data type from FlatBuffers here, because the + /// generated C++ uses std::string which is not well-supported in CHRE. + const flatbuffers::Vector<int8_t> *descriptor() const { + return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_DESCRIPTOR); + } + flatbuffers::Vector<int8_t> *mutable_descriptor() { + return GetPointer<flatbuffers::Vector<int8_t> *>(VT_DESCRIPTOR); + } + /// Breaking changes should bump the major version. + uint32_t major_version() const { + return GetField<uint32_t>(VT_MAJOR_VERSION, 0); + } + bool mutate_major_version(uint32_t _major_version) { + return SetField<uint32_t>(VT_MAJOR_VERSION, _major_version, 0); + } + /// Monotonically increasing minor version. + uint32_t minor_version() const { + return GetField<uint32_t>(VT_MINOR_VERSION, 0); + } + bool mutate_minor_version(uint32_t _minor_version) { + return SetField<uint32_t>(VT_MINOR_VERSION, _minor_version, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<uint8_t>(verifier, VT_FORMAT) && + VerifyOffset(verifier, VT_DESCRIPTOR) && + verifier.VerifyVector(descriptor()) && + VerifyField<uint32_t>(verifier, VT_MAJOR_VERSION) && + VerifyField<uint32_t>(verifier, VT_MINOR_VERSION) && + verifier.EndTable(); + } + ServiceT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ServiceT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<Service> Pack(flatbuffers::FlatBufferBuilder &_fbb, const ServiceT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ServiceBuilder { + typedef Service Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_format(chre::fbs::RpcFormat format) { + fbb_.AddElement<uint8_t>(Service::VT_FORMAT, static_cast<uint8_t>(format), 0); + } + void add_descriptor(flatbuffers::Offset<flatbuffers::Vector<int8_t>> descriptor) { + fbb_.AddOffset(Service::VT_DESCRIPTOR, descriptor); + } + void add_major_version(uint32_t major_version) { + fbb_.AddElement<uint32_t>(Service::VT_MAJOR_VERSION, major_version, 0); + } + void add_minor_version(uint32_t minor_version) { + fbb_.AddElement<uint32_t>(Service::VT_MINOR_VERSION, minor_version, 0); + } + explicit ServiceBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ServiceBuilder &operator=(const ServiceBuilder &); + flatbuffers::Offset<Service> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<Service>(end); + return o; + } +}; + +inline flatbuffers::Offset<Service> CreateService( + flatbuffers::FlatBufferBuilder &_fbb, + chre::fbs::RpcFormat format = chre::fbs::RpcFormat::CUSTOM, + flatbuffers::Offset<flatbuffers::Vector<int8_t>> descriptor = 0, + uint32_t major_version = 0, + uint32_t minor_version = 0) { + ServiceBuilder builder_(_fbb); + builder_.add_minor_version(minor_version); + builder_.add_major_version(major_version); + builder_.add_descriptor(descriptor); + builder_.add_format(format); + return builder_.Finish(); +} + +inline flatbuffers::Offset<Service> CreateServiceDirect( + flatbuffers::FlatBufferBuilder &_fbb, + chre::fbs::RpcFormat format = chre::fbs::RpcFormat::CUSTOM, + const std::vector<int8_t> *descriptor = nullptr, + uint32_t major_version = 0, + uint32_t minor_version = 0) { + auto descriptor__ = descriptor ? _fbb.CreateVector<int8_t>(*descriptor) : 0; + return chre::fbs::CreateService( + _fbb, + format, + descriptor__, + major_version, + minor_version); +} + +flatbuffers::Offset<Service> CreateService(flatbuffers::FlatBufferBuilder &_fbb, const ServiceT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct EndpointInfoT : public flatbuffers::NativeTable { + typedef EndpointInfo TableType; + std::unique_ptr<chre::fbs::EndpointIdT> id; + chre::fbs::EndpointType type; + std::vector<int8_t> name; + uint32_t version; + uint32_t required_permissions; + std::vector<std::unique_ptr<chre::fbs::ServiceT>> services; + EndpointInfoT() + : type(chre::fbs::EndpointType::INVALID), + version(0), + required_permissions(0) { + } +}; + +struct EndpointInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef EndpointInfoT NativeTableType; + typedef EndpointInfoBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ID = 4, + VT_TYPE = 6, + VT_NAME = 8, + VT_VERSION = 10, + VT_REQUIRED_PERMISSIONS = 12, + VT_SERVICES = 14 + }; + const chre::fbs::EndpointId *id() const { + return GetPointer<const chre::fbs::EndpointId *>(VT_ID); + } + chre::fbs::EndpointId *mutable_id() { + return GetPointer<chre::fbs::EndpointId *>(VT_ID); + } + chre::fbs::EndpointType type() const { + return static_cast<chre::fbs::EndpointType>(GetField<uint8_t>(VT_TYPE, 0)); + } + bool mutate_type(chre::fbs::EndpointType _type) { + return SetField<uint8_t>(VT_TYPE, static_cast<uint8_t>(_type), 0); + } + /// Endpoing name. Nominally a UTF-8 string, but note that we're not using + /// the built-in "string" data type from FlatBuffers here, because the + /// generated C++ uses std::string which is not well-supported in CHRE. + const flatbuffers::Vector<int8_t> *name() const { + return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_NAME); + } + flatbuffers::Vector<int8_t> *mutable_name() { + return GetPointer<flatbuffers::Vector<int8_t> *>(VT_NAME); + } + uint32_t version() const { + return GetField<uint32_t>(VT_VERSION, 0); + } + bool mutate_version(uint32_t _version) { + return SetField<uint32_t>(VT_VERSION, _version, 0); + } + /// Values from CHRE_MESSAGE_PERMISSION_* + uint32_t required_permissions() const { + return GetField<uint32_t>(VT_REQUIRED_PERMISSIONS, 0); + } + bool mutate_required_permissions(uint32_t _required_permissions) { + return SetField<uint32_t>(VT_REQUIRED_PERMISSIONS, _required_permissions, 0); + } + const flatbuffers::Vector<flatbuffers::Offset<chre::fbs::Service>> *services() const { + return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<chre::fbs::Service>> *>(VT_SERVICES); + } + flatbuffers::Vector<flatbuffers::Offset<chre::fbs::Service>> *mutable_services() { + return GetPointer<flatbuffers::Vector<flatbuffers::Offset<chre::fbs::Service>> *>(VT_SERVICES); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_ID) && + verifier.VerifyTable(id()) && + VerifyField<uint8_t>(verifier, VT_TYPE) && + VerifyOffset(verifier, VT_NAME) && + verifier.VerifyVector(name()) && + VerifyField<uint32_t>(verifier, VT_VERSION) && + VerifyField<uint32_t>(verifier, VT_REQUIRED_PERMISSIONS) && + VerifyOffset(verifier, VT_SERVICES) && + verifier.VerifyVector(services()) && + verifier.VerifyVectorOfTables(services()) && + verifier.EndTable(); + } + EndpointInfoT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(EndpointInfoT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<EndpointInfo> Pack(flatbuffers::FlatBufferBuilder &_fbb, const EndpointInfoT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct EndpointInfoBuilder { + typedef EndpointInfo Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_id(flatbuffers::Offset<chre::fbs::EndpointId> id) { + fbb_.AddOffset(EndpointInfo::VT_ID, id); + } + void add_type(chre::fbs::EndpointType type) { + fbb_.AddElement<uint8_t>(EndpointInfo::VT_TYPE, static_cast<uint8_t>(type), 0); + } + void add_name(flatbuffers::Offset<flatbuffers::Vector<int8_t>> name) { + fbb_.AddOffset(EndpointInfo::VT_NAME, name); + } + void add_version(uint32_t version) { + fbb_.AddElement<uint32_t>(EndpointInfo::VT_VERSION, version, 0); + } + void add_required_permissions(uint32_t required_permissions) { + fbb_.AddElement<uint32_t>(EndpointInfo::VT_REQUIRED_PERMISSIONS, required_permissions, 0); + } + void add_services(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<chre::fbs::Service>>> services) { + fbb_.AddOffset(EndpointInfo::VT_SERVICES, services); + } + explicit EndpointInfoBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + EndpointInfoBuilder &operator=(const EndpointInfoBuilder &); + flatbuffers::Offset<EndpointInfo> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<EndpointInfo>(end); + return o; + } +}; + +inline flatbuffers::Offset<EndpointInfo> CreateEndpointInfo( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<chre::fbs::EndpointId> id = 0, + chre::fbs::EndpointType type = chre::fbs::EndpointType::INVALID, + flatbuffers::Offset<flatbuffers::Vector<int8_t>> name = 0, + uint32_t version = 0, + uint32_t required_permissions = 0, + flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<chre::fbs::Service>>> services = 0) { + EndpointInfoBuilder builder_(_fbb); + builder_.add_services(services); + builder_.add_required_permissions(required_permissions); + builder_.add_version(version); + builder_.add_name(name); + builder_.add_id(id); + builder_.add_type(type); + return builder_.Finish(); +} + +inline flatbuffers::Offset<EndpointInfo> CreateEndpointInfoDirect( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<chre::fbs::EndpointId> id = 0, + chre::fbs::EndpointType type = chre::fbs::EndpointType::INVALID, + const std::vector<int8_t> *name = nullptr, + uint32_t version = 0, + uint32_t required_permissions = 0, + const std::vector<flatbuffers::Offset<chre::fbs::Service>> *services = nullptr) { + auto name__ = name ? _fbb.CreateVector<int8_t>(*name) : 0; + auto services__ = services ? _fbb.CreateVector<flatbuffers::Offset<chre::fbs::Service>>(*services) : 0; + return chre::fbs::CreateEndpointInfo( + _fbb, + id, + type, + name__, + version, + required_permissions, + services__); +} + +flatbuffers::Offset<EndpointInfo> CreateEndpointInfo(flatbuffers::FlatBufferBuilder &_fbb, const EndpointInfoT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct RegisterEndpointT : public flatbuffers::NativeTable { + typedef RegisterEndpoint TableType; + std::unique_ptr<chre::fbs::EndpointInfoT> endpoint; + RegisterEndpointT() { + } +}; + +struct RegisterEndpoint FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RegisterEndpointT NativeTableType; + typedef RegisterEndpointBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ENDPOINT = 4 + }; + const chre::fbs::EndpointInfo *endpoint() const { + return GetPointer<const chre::fbs::EndpointInfo *>(VT_ENDPOINT); + } + chre::fbs::EndpointInfo *mutable_endpoint() { + return GetPointer<chre::fbs::EndpointInfo *>(VT_ENDPOINT); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_ENDPOINT) && + verifier.VerifyTable(endpoint()) && + verifier.EndTable(); + } + RegisterEndpointT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(RegisterEndpointT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<RegisterEndpoint> Pack(flatbuffers::FlatBufferBuilder &_fbb, const RegisterEndpointT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct RegisterEndpointBuilder { + typedef RegisterEndpoint Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_endpoint(flatbuffers::Offset<chre::fbs::EndpointInfo> endpoint) { + fbb_.AddOffset(RegisterEndpoint::VT_ENDPOINT, endpoint); + } + explicit RegisterEndpointBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + RegisterEndpointBuilder &operator=(const RegisterEndpointBuilder &); + flatbuffers::Offset<RegisterEndpoint> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<RegisterEndpoint>(end); + return o; + } +}; + +inline flatbuffers::Offset<RegisterEndpoint> CreateRegisterEndpoint( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<chre::fbs::EndpointInfo> endpoint = 0) { + RegisterEndpointBuilder builder_(_fbb); + builder_.add_endpoint(endpoint); + return builder_.Finish(); +} + +flatbuffers::Offset<RegisterEndpoint> CreateRegisterEndpoint(flatbuffers::FlatBufferBuilder &_fbb, const RegisterEndpointT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct UnregisterEndpointT : public flatbuffers::NativeTable { + typedef UnregisterEndpoint TableType; + std::unique_ptr<chre::fbs::EndpointIdT> endpoint; + UnregisterEndpointT() { + } +}; + +struct UnregisterEndpoint FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef UnregisterEndpointT NativeTableType; + typedef UnregisterEndpointBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ENDPOINT = 4 + }; + const chre::fbs::EndpointId *endpoint() const { + return GetPointer<const chre::fbs::EndpointId *>(VT_ENDPOINT); + } + chre::fbs::EndpointId *mutable_endpoint() { + return GetPointer<chre::fbs::EndpointId *>(VT_ENDPOINT); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_ENDPOINT) && + verifier.VerifyTable(endpoint()) && + verifier.EndTable(); + } + UnregisterEndpointT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(UnregisterEndpointT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<UnregisterEndpoint> Pack(flatbuffers::FlatBufferBuilder &_fbb, const UnregisterEndpointT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct UnregisterEndpointBuilder { + typedef UnregisterEndpoint Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_endpoint(flatbuffers::Offset<chre::fbs::EndpointId> endpoint) { + fbb_.AddOffset(UnregisterEndpoint::VT_ENDPOINT, endpoint); + } + explicit UnregisterEndpointBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + UnregisterEndpointBuilder &operator=(const UnregisterEndpointBuilder &); + flatbuffers::Offset<UnregisterEndpoint> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<UnregisterEndpoint>(end); + return o; + } +}; + +inline flatbuffers::Offset<UnregisterEndpoint> CreateUnregisterEndpoint( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<chre::fbs::EndpointId> endpoint = 0) { + UnregisterEndpointBuilder builder_(_fbb); + builder_.add_endpoint(endpoint); + return builder_.Finish(); +} + +flatbuffers::Offset<UnregisterEndpoint> CreateUnregisterEndpoint(flatbuffers::FlatBufferBuilder &_fbb, const UnregisterEndpointT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct GetMessageHubsAndEndpointsRequestT : public flatbuffers::NativeTable { + typedef GetMessageHubsAndEndpointsRequest TableType; + GetMessageHubsAndEndpointsRequestT() { + } +}; + +/// HAL->CHRE, indicates the HAL is coming up +struct GetMessageHubsAndEndpointsRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef GetMessageHubsAndEndpointsRequestT NativeTableType; + typedef GetMessageHubsAndEndpointsRequestBuilder Builder; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + GetMessageHubsAndEndpointsRequestT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(GetMessageHubsAndEndpointsRequestT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<GetMessageHubsAndEndpointsRequest> Pack(flatbuffers::FlatBufferBuilder &_fbb, const GetMessageHubsAndEndpointsRequestT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct GetMessageHubsAndEndpointsRequestBuilder { + typedef GetMessageHubsAndEndpointsRequest Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit GetMessageHubsAndEndpointsRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + GetMessageHubsAndEndpointsRequestBuilder &operator=(const GetMessageHubsAndEndpointsRequestBuilder &); + flatbuffers::Offset<GetMessageHubsAndEndpointsRequest> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<GetMessageHubsAndEndpointsRequest>(end); + return o; + } +}; + +inline flatbuffers::Offset<GetMessageHubsAndEndpointsRequest> CreateGetMessageHubsAndEndpointsRequest( + flatbuffers::FlatBufferBuilder &_fbb) { + GetMessageHubsAndEndpointsRequestBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset<GetMessageHubsAndEndpointsRequest> CreateGetMessageHubsAndEndpointsRequest(flatbuffers::FlatBufferBuilder &_fbb, const GetMessageHubsAndEndpointsRequestT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct GetMessageHubsAndEndpointsResponseT : public flatbuffers::NativeTable { + typedef GetMessageHubsAndEndpointsResponse TableType; + std::vector<std::unique_ptr<chre::fbs::MessageHubT>> hubs; + std::vector<std::unique_ptr<chre::fbs::EndpointInfoT>> endpoints; + GetMessageHubsAndEndpointsResponseT() { + } +}; + +struct GetMessageHubsAndEndpointsResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef GetMessageHubsAndEndpointsResponseT NativeTableType; + typedef GetMessageHubsAndEndpointsResponseBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_HUBS = 4, + VT_ENDPOINTS = 6 + }; + const flatbuffers::Vector<flatbuffers::Offset<chre::fbs::MessageHub>> *hubs() const { + return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<chre::fbs::MessageHub>> *>(VT_HUBS); + } + flatbuffers::Vector<flatbuffers::Offset<chre::fbs::MessageHub>> *mutable_hubs() { + return GetPointer<flatbuffers::Vector<flatbuffers::Offset<chre::fbs::MessageHub>> *>(VT_HUBS); + } + const flatbuffers::Vector<flatbuffers::Offset<chre::fbs::EndpointInfo>> *endpoints() const { + return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<chre::fbs::EndpointInfo>> *>(VT_ENDPOINTS); + } + flatbuffers::Vector<flatbuffers::Offset<chre::fbs::EndpointInfo>> *mutable_endpoints() { + return GetPointer<flatbuffers::Vector<flatbuffers::Offset<chre::fbs::EndpointInfo>> *>(VT_ENDPOINTS); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_HUBS) && + verifier.VerifyVector(hubs()) && + verifier.VerifyVectorOfTables(hubs()) && + VerifyOffset(verifier, VT_ENDPOINTS) && + verifier.VerifyVector(endpoints()) && + verifier.VerifyVectorOfTables(endpoints()) && + verifier.EndTable(); + } + GetMessageHubsAndEndpointsResponseT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(GetMessageHubsAndEndpointsResponseT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<GetMessageHubsAndEndpointsResponse> Pack(flatbuffers::FlatBufferBuilder &_fbb, const GetMessageHubsAndEndpointsResponseT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct GetMessageHubsAndEndpointsResponseBuilder { + typedef GetMessageHubsAndEndpointsResponse Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_hubs(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<chre::fbs::MessageHub>>> hubs) { + fbb_.AddOffset(GetMessageHubsAndEndpointsResponse::VT_HUBS, hubs); + } + void add_endpoints(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<chre::fbs::EndpointInfo>>> endpoints) { + fbb_.AddOffset(GetMessageHubsAndEndpointsResponse::VT_ENDPOINTS, endpoints); + } + explicit GetMessageHubsAndEndpointsResponseBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + GetMessageHubsAndEndpointsResponseBuilder &operator=(const GetMessageHubsAndEndpointsResponseBuilder &); + flatbuffers::Offset<GetMessageHubsAndEndpointsResponse> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<GetMessageHubsAndEndpointsResponse>(end); + return o; + } +}; + +inline flatbuffers::Offset<GetMessageHubsAndEndpointsResponse> CreateGetMessageHubsAndEndpointsResponse( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<chre::fbs::MessageHub>>> hubs = 0, + flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<chre::fbs::EndpointInfo>>> endpoints = 0) { + GetMessageHubsAndEndpointsResponseBuilder builder_(_fbb); + builder_.add_endpoints(endpoints); + builder_.add_hubs(hubs); + return builder_.Finish(); +} + +inline flatbuffers::Offset<GetMessageHubsAndEndpointsResponse> CreateGetMessageHubsAndEndpointsResponseDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector<flatbuffers::Offset<chre::fbs::MessageHub>> *hubs = nullptr, + const std::vector<flatbuffers::Offset<chre::fbs::EndpointInfo>> *endpoints = nullptr) { + auto hubs__ = hubs ? _fbb.CreateVector<flatbuffers::Offset<chre::fbs::MessageHub>>(*hubs) : 0; + auto endpoints__ = endpoints ? _fbb.CreateVector<flatbuffers::Offset<chre::fbs::EndpointInfo>>(*endpoints) : 0; + return chre::fbs::CreateGetMessageHubsAndEndpointsResponse( + _fbb, + hubs__, + endpoints__); +} + +flatbuffers::Offset<GetMessageHubsAndEndpointsResponse> CreateGetMessageHubsAndEndpointsResponse(flatbuffers::FlatBufferBuilder &_fbb, const GetMessageHubsAndEndpointsResponseT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct OpenEndpointSessionRequestT : public flatbuffers::NativeTable { + typedef OpenEndpointSessionRequest TableType; + uint16_t id; + std::unique_ptr<chre::fbs::EndpointIdT> fromEndpoint; + std::unique_ptr<chre::fbs::EndpointIdT> toEndpoint; + std::vector<int8_t> serviceDescriptor; + OpenEndpointSessionRequestT() + : id(0) { + } +}; + +struct OpenEndpointSessionRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef OpenEndpointSessionRequestT NativeTableType; + typedef OpenEndpointSessionRequestBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ID = 4, + VT_FROMENDPOINT = 6, + VT_TOENDPOINT = 8, + VT_SERVICEDESCRIPTOR = 10 + }; + uint16_t id() const { + return GetField<uint16_t>(VT_ID, 0); + } + bool mutate_id(uint16_t _id) { + return SetField<uint16_t>(VT_ID, _id, 0); + } + const chre::fbs::EndpointId *fromEndpoint() const { + return GetPointer<const chre::fbs::EndpointId *>(VT_FROMENDPOINT); + } + chre::fbs::EndpointId *mutable_fromEndpoint() { + return GetPointer<chre::fbs::EndpointId *>(VT_FROMENDPOINT); + } + const chre::fbs::EndpointId *toEndpoint() const { + return GetPointer<const chre::fbs::EndpointId *>(VT_TOENDPOINT); + } + chre::fbs::EndpointId *mutable_toEndpoint() { + return GetPointer<chre::fbs::EndpointId *>(VT_TOENDPOINT); + } + /// If present, describes the service definition used over the session + const flatbuffers::Vector<int8_t> *serviceDescriptor() const { + return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_SERVICEDESCRIPTOR); + } + flatbuffers::Vector<int8_t> *mutable_serviceDescriptor() { + return GetPointer<flatbuffers::Vector<int8_t> *>(VT_SERVICEDESCRIPTOR); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<uint16_t>(verifier, VT_ID) && + VerifyOffset(verifier, VT_FROMENDPOINT) && + verifier.VerifyTable(fromEndpoint()) && + VerifyOffset(verifier, VT_TOENDPOINT) && + verifier.VerifyTable(toEndpoint()) && + VerifyOffset(verifier, VT_SERVICEDESCRIPTOR) && + verifier.VerifyVector(serviceDescriptor()) && + verifier.EndTable(); + } + OpenEndpointSessionRequestT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(OpenEndpointSessionRequestT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<OpenEndpointSessionRequest> Pack(flatbuffers::FlatBufferBuilder &_fbb, const OpenEndpointSessionRequestT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct OpenEndpointSessionRequestBuilder { + typedef OpenEndpointSessionRequest Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_id(uint16_t id) { + fbb_.AddElement<uint16_t>(OpenEndpointSessionRequest::VT_ID, id, 0); + } + void add_fromEndpoint(flatbuffers::Offset<chre::fbs::EndpointId> fromEndpoint) { + fbb_.AddOffset(OpenEndpointSessionRequest::VT_FROMENDPOINT, fromEndpoint); + } + void add_toEndpoint(flatbuffers::Offset<chre::fbs::EndpointId> toEndpoint) { + fbb_.AddOffset(OpenEndpointSessionRequest::VT_TOENDPOINT, toEndpoint); + } + void add_serviceDescriptor(flatbuffers::Offset<flatbuffers::Vector<int8_t>> serviceDescriptor) { + fbb_.AddOffset(OpenEndpointSessionRequest::VT_SERVICEDESCRIPTOR, serviceDescriptor); + } + explicit OpenEndpointSessionRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + OpenEndpointSessionRequestBuilder &operator=(const OpenEndpointSessionRequestBuilder &); + flatbuffers::Offset<OpenEndpointSessionRequest> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<OpenEndpointSessionRequest>(end); + return o; + } +}; + +inline flatbuffers::Offset<OpenEndpointSessionRequest> CreateOpenEndpointSessionRequest( + flatbuffers::FlatBufferBuilder &_fbb, + uint16_t id = 0, + flatbuffers::Offset<chre::fbs::EndpointId> fromEndpoint = 0, + flatbuffers::Offset<chre::fbs::EndpointId> toEndpoint = 0, + flatbuffers::Offset<flatbuffers::Vector<int8_t>> serviceDescriptor = 0) { + OpenEndpointSessionRequestBuilder builder_(_fbb); + builder_.add_serviceDescriptor(serviceDescriptor); + builder_.add_toEndpoint(toEndpoint); + builder_.add_fromEndpoint(fromEndpoint); + builder_.add_id(id); + return builder_.Finish(); +} + +inline flatbuffers::Offset<OpenEndpointSessionRequest> CreateOpenEndpointSessionRequestDirect( + flatbuffers::FlatBufferBuilder &_fbb, + uint16_t id = 0, + flatbuffers::Offset<chre::fbs::EndpointId> fromEndpoint = 0, + flatbuffers::Offset<chre::fbs::EndpointId> toEndpoint = 0, + const std::vector<int8_t> *serviceDescriptor = nullptr) { + auto serviceDescriptor__ = serviceDescriptor ? _fbb.CreateVector<int8_t>(*serviceDescriptor) : 0; + return chre::fbs::CreateOpenEndpointSessionRequest( + _fbb, + id, + fromEndpoint, + toEndpoint, + serviceDescriptor__); +} + +flatbuffers::Offset<OpenEndpointSessionRequest> CreateOpenEndpointSessionRequest(flatbuffers::FlatBufferBuilder &_fbb, const OpenEndpointSessionRequestT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct EndpointSessionOpenedT : public flatbuffers::NativeTable { + typedef EndpointSessionOpened TableType; + uint16_t id; + EndpointSessionOpenedT() + : id(0) { + } +}; + +struct EndpointSessionOpened FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef EndpointSessionOpenedT NativeTableType; + typedef EndpointSessionOpenedBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ID = 4 + }; + uint16_t id() const { + return GetField<uint16_t>(VT_ID, 0); + } + bool mutate_id(uint16_t _id) { + return SetField<uint16_t>(VT_ID, _id, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<uint16_t>(verifier, VT_ID) && + verifier.EndTable(); + } + EndpointSessionOpenedT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(EndpointSessionOpenedT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<EndpointSessionOpened> Pack(flatbuffers::FlatBufferBuilder &_fbb, const EndpointSessionOpenedT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct EndpointSessionOpenedBuilder { + typedef EndpointSessionOpened Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_id(uint16_t id) { + fbb_.AddElement<uint16_t>(EndpointSessionOpened::VT_ID, id, 0); + } + explicit EndpointSessionOpenedBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + EndpointSessionOpenedBuilder &operator=(const EndpointSessionOpenedBuilder &); + flatbuffers::Offset<EndpointSessionOpened> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<EndpointSessionOpened>(end); + return o; + } +}; + +inline flatbuffers::Offset<EndpointSessionOpened> CreateEndpointSessionOpened( + flatbuffers::FlatBufferBuilder &_fbb, + uint16_t id = 0) { + EndpointSessionOpenedBuilder builder_(_fbb); + builder_.add_id(id); + return builder_.Finish(); +} + +flatbuffers::Offset<EndpointSessionOpened> CreateEndpointSessionOpened(flatbuffers::FlatBufferBuilder &_fbb, const EndpointSessionOpenedT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct EndpointSessionClosedT : public flatbuffers::NativeTable { + typedef EndpointSessionClosed TableType; + uint16_t id; + chre::fbs::Reason reason; + EndpointSessionClosedT() + : id(0), + reason(chre::fbs::Reason::UNSPECIFIED) { + } +}; + +struct EndpointSessionClosed FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef EndpointSessionClosedT NativeTableType; + typedef EndpointSessionClosedBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ID = 4, + VT_REASON = 6 + }; + uint16_t id() const { + return GetField<uint16_t>(VT_ID, 0); + } + bool mutate_id(uint16_t _id) { + return SetField<uint16_t>(VT_ID, _id, 0); + } + chre::fbs::Reason reason() const { + return static_cast<chre::fbs::Reason>(GetField<uint8_t>(VT_REASON, 0)); + } + bool mutate_reason(chre::fbs::Reason _reason) { + return SetField<uint8_t>(VT_REASON, static_cast<uint8_t>(_reason), 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<uint16_t>(verifier, VT_ID) && + VerifyField<uint8_t>(verifier, VT_REASON) && + verifier.EndTable(); + } + EndpointSessionClosedT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(EndpointSessionClosedT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<EndpointSessionClosed> Pack(flatbuffers::FlatBufferBuilder &_fbb, const EndpointSessionClosedT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct EndpointSessionClosedBuilder { + typedef EndpointSessionClosed Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_id(uint16_t id) { + fbb_.AddElement<uint16_t>(EndpointSessionClosed::VT_ID, id, 0); + } + void add_reason(chre::fbs::Reason reason) { + fbb_.AddElement<uint8_t>(EndpointSessionClosed::VT_REASON, static_cast<uint8_t>(reason), 0); + } + explicit EndpointSessionClosedBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + EndpointSessionClosedBuilder &operator=(const EndpointSessionClosedBuilder &); + flatbuffers::Offset<EndpointSessionClosed> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<EndpointSessionClosed>(end); + return o; + } +}; + +inline flatbuffers::Offset<EndpointSessionClosed> CreateEndpointSessionClosed( + flatbuffers::FlatBufferBuilder &_fbb, + uint16_t id = 0, + chre::fbs::Reason reason = chre::fbs::Reason::UNSPECIFIED) { + EndpointSessionClosedBuilder builder_(_fbb); + builder_.add_id(id); + builder_.add_reason(reason); + return builder_.Finish(); +} + +flatbuffers::Offset<EndpointSessionClosed> CreateEndpointSessionClosed(flatbuffers::FlatBufferBuilder &_fbb, const EndpointSessionClosedT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct EndpointSessionMessageT : public flatbuffers::NativeTable { + typedef EndpointSessionMessage TableType; + uint16_t session_id; + uint32_t type; + uint32_t permissions; + std::vector<uint8_t> data; + uint32_t flags; + uint32_t sequence_number; + EndpointSessionMessageT() + : session_id(0), + type(0), + permissions(0), + flags(0), + sequence_number(0) { + } +}; + +struct EndpointSessionMessage FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef EndpointSessionMessageT NativeTableType; + typedef EndpointSessionMessageBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SESSION_ID = 4, + VT_TYPE = 6, + VT_PERMISSIONS = 8, + VT_DATA = 10, + VT_FLAGS = 12, + VT_SEQUENCE_NUMBER = 14 + }; + /// Id of session this message is being sent within + uint16_t session_id() const { + return GetField<uint16_t>(VT_SESSION_ID, 0); + } + bool mutate_session_id(uint16_t _session_id) { + return SetField<uint16_t>(VT_SESSION_ID, _session_id, 0); + } + /// Type of the message, specific to the Session protocol + uint32_t type() const { + return GetField<uint32_t>(VT_TYPE, 0); + } + bool mutate_type(uint32_t _type) { + return SetField<uint32_t>(VT_TYPE, _type, 0); + } + /// Values from CHRE_MESSAGE_PERMISSION_*. Permissions required to read the + /// message. + uint32_t permissions() const { + return GetField<uint32_t>(VT_PERMISSIONS, 0); + } + bool mutate_permissions(uint32_t _permissions) { + return SetField<uint32_t>(VT_PERMISSIONS, _permissions, 0); + } + const flatbuffers::Vector<uint8_t> *data() const { + return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_DATA); + } + flatbuffers::Vector<uint8_t> *mutable_data() { + return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_DATA); + } + /// Bitmask of additional flags applied to the message: + /// - 0x1: Message delivery status required within 1s + uint32_t flags() const { + return GetField<uint32_t>(VT_FLAGS, 0); + } + bool mutate_flags(uint32_t _flags) { + return SetField<uint32_t>(VT_FLAGS, _flags, 0); + } + uint32_t sequence_number() const { + return GetField<uint32_t>(VT_SEQUENCE_NUMBER, 0); + } + bool mutate_sequence_number(uint32_t _sequence_number) { + return SetField<uint32_t>(VT_SEQUENCE_NUMBER, _sequence_number, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<uint16_t>(verifier, VT_SESSION_ID) && + VerifyField<uint32_t>(verifier, VT_TYPE) && + VerifyField<uint32_t>(verifier, VT_PERMISSIONS) && + VerifyOffset(verifier, VT_DATA) && + verifier.VerifyVector(data()) && + VerifyField<uint32_t>(verifier, VT_FLAGS) && + VerifyField<uint32_t>(verifier, VT_SEQUENCE_NUMBER) && + verifier.EndTable(); + } + EndpointSessionMessageT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(EndpointSessionMessageT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<EndpointSessionMessage> Pack(flatbuffers::FlatBufferBuilder &_fbb, const EndpointSessionMessageT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct EndpointSessionMessageBuilder { + typedef EndpointSessionMessage Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_session_id(uint16_t session_id) { + fbb_.AddElement<uint16_t>(EndpointSessionMessage::VT_SESSION_ID, session_id, 0); + } + void add_type(uint32_t type) { + fbb_.AddElement<uint32_t>(EndpointSessionMessage::VT_TYPE, type, 0); + } + void add_permissions(uint32_t permissions) { + fbb_.AddElement<uint32_t>(EndpointSessionMessage::VT_PERMISSIONS, permissions, 0); + } + void add_data(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> data) { + fbb_.AddOffset(EndpointSessionMessage::VT_DATA, data); + } + void add_flags(uint32_t flags) { + fbb_.AddElement<uint32_t>(EndpointSessionMessage::VT_FLAGS, flags, 0); + } + void add_sequence_number(uint32_t sequence_number) { + fbb_.AddElement<uint32_t>(EndpointSessionMessage::VT_SEQUENCE_NUMBER, sequence_number, 0); + } + explicit EndpointSessionMessageBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + EndpointSessionMessageBuilder &operator=(const EndpointSessionMessageBuilder &); + flatbuffers::Offset<EndpointSessionMessage> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<EndpointSessionMessage>(end); + return o; + } +}; + +inline flatbuffers::Offset<EndpointSessionMessage> CreateEndpointSessionMessage( + flatbuffers::FlatBufferBuilder &_fbb, + uint16_t session_id = 0, + uint32_t type = 0, + uint32_t permissions = 0, + flatbuffers::Offset<flatbuffers::Vector<uint8_t>> data = 0, + uint32_t flags = 0, + uint32_t sequence_number = 0) { + EndpointSessionMessageBuilder builder_(_fbb); + builder_.add_sequence_number(sequence_number); + builder_.add_flags(flags); + builder_.add_data(data); + builder_.add_permissions(permissions); + builder_.add_type(type); + builder_.add_session_id(session_id); + return builder_.Finish(); +} + +inline flatbuffers::Offset<EndpointSessionMessage> CreateEndpointSessionMessageDirect( + flatbuffers::FlatBufferBuilder &_fbb, + uint16_t session_id = 0, + uint32_t type = 0, + uint32_t permissions = 0, + const std::vector<uint8_t> *data = nullptr, + uint32_t flags = 0, + uint32_t sequence_number = 0) { + auto data__ = data ? _fbb.CreateVector<uint8_t>(*data) : 0; + return chre::fbs::CreateEndpointSessionMessage( + _fbb, + session_id, + type, + permissions, + data__, + flags, + sequence_number); +} + +flatbuffers::Offset<EndpointSessionMessage> CreateEndpointSessionMessage(flatbuffers::FlatBufferBuilder &_fbb, const EndpointSessionMessageT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct EndpointSessionMessageDeliveryStatusT : public flatbuffers::NativeTable { + typedef EndpointSessionMessageDeliveryStatus TableType; + uint16_t session_id; + std::unique_ptr<chre::fbs::MessageDeliveryStatusT> status; + EndpointSessionMessageDeliveryStatusT() + : session_id(0) { + } +}; + +struct EndpointSessionMessageDeliveryStatus FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef EndpointSessionMessageDeliveryStatusT NativeTableType; + typedef EndpointSessionMessageDeliveryStatusBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SESSION_ID = 4, + VT_STATUS = 6 + }; + /// Id of session the message was sent within + uint16_t session_id() const { + return GetField<uint16_t>(VT_SESSION_ID, 0); + } + bool mutate_session_id(uint16_t _session_id) { + return SetField<uint16_t>(VT_SESSION_ID, _session_id, 0); + } + const chre::fbs::MessageDeliveryStatus *status() const { + return GetPointer<const chre::fbs::MessageDeliveryStatus *>(VT_STATUS); + } + chre::fbs::MessageDeliveryStatus *mutable_status() { + return GetPointer<chre::fbs::MessageDeliveryStatus *>(VT_STATUS); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<uint16_t>(verifier, VT_SESSION_ID) && + VerifyOffset(verifier, VT_STATUS) && + verifier.VerifyTable(status()) && + verifier.EndTable(); + } + EndpointSessionMessageDeliveryStatusT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(EndpointSessionMessageDeliveryStatusT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset<EndpointSessionMessageDeliveryStatus> Pack(flatbuffers::FlatBufferBuilder &_fbb, const EndpointSessionMessageDeliveryStatusT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct EndpointSessionMessageDeliveryStatusBuilder { + typedef EndpointSessionMessageDeliveryStatus Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_session_id(uint16_t session_id) { + fbb_.AddElement<uint16_t>(EndpointSessionMessageDeliveryStatus::VT_SESSION_ID, session_id, 0); + } + void add_status(flatbuffers::Offset<chre::fbs::MessageDeliveryStatus> status) { + fbb_.AddOffset(EndpointSessionMessageDeliveryStatus::VT_STATUS, status); + } + explicit EndpointSessionMessageDeliveryStatusBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + EndpointSessionMessageDeliveryStatusBuilder &operator=(const EndpointSessionMessageDeliveryStatusBuilder &); + flatbuffers::Offset<EndpointSessionMessageDeliveryStatus> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<EndpointSessionMessageDeliveryStatus>(end); + return o; + } +}; + +inline flatbuffers::Offset<EndpointSessionMessageDeliveryStatus> CreateEndpointSessionMessageDeliveryStatus( + flatbuffers::FlatBufferBuilder &_fbb, + uint16_t session_id = 0, + flatbuffers::Offset<chre::fbs::MessageDeliveryStatus> status = 0) { + EndpointSessionMessageDeliveryStatusBuilder builder_(_fbb); + builder_.add_status(status); + builder_.add_session_id(session_id); + return builder_.Finish(); +} + +flatbuffers::Offset<EndpointSessionMessageDeliveryStatus> CreateEndpointSessionMessageDeliveryStatus(flatbuffers::FlatBufferBuilder &_fbb, const EndpointSessionMessageDeliveryStatusT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + struct MessageContainerT : public flatbuffers::NativeTable { typedef MessageContainer TableType; chre::fbs::ChreMessageUnion message; @@ -4010,6 +6696,51 @@ const chre::fbs::MessageDeliveryStatus *message_as_MessageDeliveryStatus() const { return message_type() == chre::fbs::ChreMessage::MessageDeliveryStatus ? static_cast<const chre::fbs::MessageDeliveryStatus *>(message()) : nullptr; } + const chre::fbs::BtSocketOpen *message_as_BtSocketOpen() const { + return message_type() == chre::fbs::ChreMessage::BtSocketOpen ? static_cast<const chre::fbs::BtSocketOpen *>(message()) : nullptr; + } + const chre::fbs::BtSocketOpenResponse *message_as_BtSocketOpenResponse() const { + return message_type() == chre::fbs::ChreMessage::BtSocketOpenResponse ? static_cast<const chre::fbs::BtSocketOpenResponse *>(message()) : nullptr; + } + const chre::fbs::BtSocketClose *message_as_BtSocketClose() const { + return message_type() == chre::fbs::ChreMessage::BtSocketClose ? static_cast<const chre::fbs::BtSocketClose *>(message()) : nullptr; + } + const chre::fbs::BtSocketCloseResponse *message_as_BtSocketCloseResponse() const { + return message_type() == chre::fbs::ChreMessage::BtSocketCloseResponse ? static_cast<const chre::fbs::BtSocketCloseResponse *>(message()) : nullptr; + } + const chre::fbs::GetMessageHubsAndEndpointsRequest *message_as_GetMessageHubsAndEndpointsRequest() const { + return message_type() == chre::fbs::ChreMessage::GetMessageHubsAndEndpointsRequest ? static_cast<const chre::fbs::GetMessageHubsAndEndpointsRequest *>(message()) : nullptr; + } + const chre::fbs::GetMessageHubsAndEndpointsResponse *message_as_GetMessageHubsAndEndpointsResponse() const { + return message_type() == chre::fbs::ChreMessage::GetMessageHubsAndEndpointsResponse ? static_cast<const chre::fbs::GetMessageHubsAndEndpointsResponse *>(message()) : nullptr; + } + const chre::fbs::RegisterMessageHub *message_as_RegisterMessageHub() const { + return message_type() == chre::fbs::ChreMessage::RegisterMessageHub ? static_cast<const chre::fbs::RegisterMessageHub *>(message()) : nullptr; + } + const chre::fbs::UnregisterMessageHub *message_as_UnregisterMessageHub() const { + return message_type() == chre::fbs::ChreMessage::UnregisterMessageHub ? static_cast<const chre::fbs::UnregisterMessageHub *>(message()) : nullptr; + } + const chre::fbs::RegisterEndpoint *message_as_RegisterEndpoint() const { + return message_type() == chre::fbs::ChreMessage::RegisterEndpoint ? static_cast<const chre::fbs::RegisterEndpoint *>(message()) : nullptr; + } + const chre::fbs::UnregisterEndpoint *message_as_UnregisterEndpoint() const { + return message_type() == chre::fbs::ChreMessage::UnregisterEndpoint ? static_cast<const chre::fbs::UnregisterEndpoint *>(message()) : nullptr; + } + const chre::fbs::OpenEndpointSessionRequest *message_as_OpenEndpointSessionRequest() const { + return message_type() == chre::fbs::ChreMessage::OpenEndpointSessionRequest ? static_cast<const chre::fbs::OpenEndpointSessionRequest *>(message()) : nullptr; + } + const chre::fbs::EndpointSessionOpened *message_as_EndpointSessionOpened() const { + return message_type() == chre::fbs::ChreMessage::EndpointSessionOpened ? static_cast<const chre::fbs::EndpointSessionOpened *>(message()) : nullptr; + } + const chre::fbs::EndpointSessionClosed *message_as_EndpointSessionClosed() const { + return message_type() == chre::fbs::ChreMessage::EndpointSessionClosed ? static_cast<const chre::fbs::EndpointSessionClosed *>(message()) : nullptr; + } + const chre::fbs::EndpointSessionMessage *message_as_EndpointSessionMessage() const { + return message_type() == chre::fbs::ChreMessage::EndpointSessionMessage ? static_cast<const chre::fbs::EndpointSessionMessage *>(message()) : nullptr; + } + const chre::fbs::EndpointSessionMessageDeliveryStatus *message_as_EndpointSessionMessageDeliveryStatus() const { + return message_type() == chre::fbs::ChreMessage::EndpointSessionMessageDeliveryStatus ? static_cast<const chre::fbs::EndpointSessionMessageDeliveryStatus *>(message()) : nullptr; + } void *mutable_message() { return GetPointer<void *>(VT_MESSAGE); } @@ -4166,6 +6897,66 @@ return message_as_MessageDeliveryStatus(); } +template<> inline const chre::fbs::BtSocketOpen *MessageContainer::message_as<chre::fbs::BtSocketOpen>() const { + return message_as_BtSocketOpen(); +} + +template<> inline const chre::fbs::BtSocketOpenResponse *MessageContainer::message_as<chre::fbs::BtSocketOpenResponse>() const { + return message_as_BtSocketOpenResponse(); +} + +template<> inline const chre::fbs::BtSocketClose *MessageContainer::message_as<chre::fbs::BtSocketClose>() const { + return message_as_BtSocketClose(); +} + +template<> inline const chre::fbs::BtSocketCloseResponse *MessageContainer::message_as<chre::fbs::BtSocketCloseResponse>() const { + return message_as_BtSocketCloseResponse(); +} + +template<> inline const chre::fbs::GetMessageHubsAndEndpointsRequest *MessageContainer::message_as<chre::fbs::GetMessageHubsAndEndpointsRequest>() const { + return message_as_GetMessageHubsAndEndpointsRequest(); +} + +template<> inline const chre::fbs::GetMessageHubsAndEndpointsResponse *MessageContainer::message_as<chre::fbs::GetMessageHubsAndEndpointsResponse>() const { + return message_as_GetMessageHubsAndEndpointsResponse(); +} + +template<> inline const chre::fbs::RegisterMessageHub *MessageContainer::message_as<chre::fbs::RegisterMessageHub>() const { + return message_as_RegisterMessageHub(); +} + +template<> inline const chre::fbs::UnregisterMessageHub *MessageContainer::message_as<chre::fbs::UnregisterMessageHub>() const { + return message_as_UnregisterMessageHub(); +} + +template<> inline const chre::fbs::RegisterEndpoint *MessageContainer::message_as<chre::fbs::RegisterEndpoint>() const { + return message_as_RegisterEndpoint(); +} + +template<> inline const chre::fbs::UnregisterEndpoint *MessageContainer::message_as<chre::fbs::UnregisterEndpoint>() const { + return message_as_UnregisterEndpoint(); +} + +template<> inline const chre::fbs::OpenEndpointSessionRequest *MessageContainer::message_as<chre::fbs::OpenEndpointSessionRequest>() const { + return message_as_OpenEndpointSessionRequest(); +} + +template<> inline const chre::fbs::EndpointSessionOpened *MessageContainer::message_as<chre::fbs::EndpointSessionOpened>() const { + return message_as_EndpointSessionOpened(); +} + +template<> inline const chre::fbs::EndpointSessionClosed *MessageContainer::message_as<chre::fbs::EndpointSessionClosed>() const { + return message_as_EndpointSessionClosed(); +} + +template<> inline const chre::fbs::EndpointSessionMessage *MessageContainer::message_as<chre::fbs::EndpointSessionMessage>() const { + return message_as_EndpointSessionMessage(); +} + +template<> inline const chre::fbs::EndpointSessionMessageDeliveryStatus *MessageContainer::message_as<chre::fbs::EndpointSessionMessageDeliveryStatus>() const { + return message_as_EndpointSessionMessageDeliveryStatus(); +} + struct MessageContainerBuilder { typedef MessageContainer Table; flatbuffers::FlatBufferBuilder &fbb_; @@ -5217,6 +8008,672 @@ _fbb); } +inline LeCocChannelInfoT *LeCocChannelInfo::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::LeCocChannelInfoT> _o = std::unique_ptr<chre::fbs::LeCocChannelInfoT>(new LeCocChannelInfoT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void LeCocChannelInfo::UnPackTo(LeCocChannelInfoT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = localCid(); _o->localCid = _e; } + { auto _e = remoteCid(); _o->remoteCid = _e; } + { auto _e = psm(); _o->psm = _e; } + { auto _e = localMtu(); _o->localMtu = _e; } + { auto _e = remoteMtu(); _o->remoteMtu = _e; } + { auto _e = localMps(); _o->localMps = _e; } + { auto _e = remoteMps(); _o->remoteMps = _e; } + { auto _e = initialRxCredits(); _o->initialRxCredits = _e; } + { auto _e = initialTxCredits(); _o->initialTxCredits = _e; } +} + +inline flatbuffers::Offset<LeCocChannelInfo> LeCocChannelInfo::Pack(flatbuffers::FlatBufferBuilder &_fbb, const LeCocChannelInfoT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateLeCocChannelInfo(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<LeCocChannelInfo> CreateLeCocChannelInfo(flatbuffers::FlatBufferBuilder &_fbb, const LeCocChannelInfoT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const LeCocChannelInfoT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _localCid = _o->localCid; + auto _remoteCid = _o->remoteCid; + auto _psm = _o->psm; + auto _localMtu = _o->localMtu; + auto _remoteMtu = _o->remoteMtu; + auto _localMps = _o->localMps; + auto _remoteMps = _o->remoteMps; + auto _initialRxCredits = _o->initialRxCredits; + auto _initialTxCredits = _o->initialTxCredits; + return chre::fbs::CreateLeCocChannelInfo( + _fbb, + _localCid, + _remoteCid, + _psm, + _localMtu, + _remoteMtu, + _localMps, + _remoteMps, + _initialRxCredits, + _initialTxCredits); +} + +inline BtSocketOpenT *BtSocketOpen::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::BtSocketOpenT> _o = std::unique_ptr<chre::fbs::BtSocketOpenT>(new BtSocketOpenT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void BtSocketOpen::UnPackTo(BtSocketOpenT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = socketId(); _o->socketId = _e; } + { auto _e = name(); if (_e) { _o->name.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->name[_i] = _e->Get(_i); } } } + { auto _e = aclConnectionHandle(); _o->aclConnectionHandle = _e; } + { auto _e = channelInfo_type(); _o->channelInfo.type = _e; } + { auto _e = channelInfo(); if (_e) _o->channelInfo.value = chre::fbs::ChannelInfoUnion::UnPack(_e, channelInfo_type(), _resolver); } + { auto _e = hubId(); _o->hubId = _e; } + { auto _e = endpointId(); _o->endpointId = _e; } +} + +inline flatbuffers::Offset<BtSocketOpen> BtSocketOpen::Pack(flatbuffers::FlatBufferBuilder &_fbb, const BtSocketOpenT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateBtSocketOpen(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<BtSocketOpen> CreateBtSocketOpen(flatbuffers::FlatBufferBuilder &_fbb, const BtSocketOpenT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const BtSocketOpenT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _socketId = _o->socketId; + auto _name = _o->name.size() ? _fbb.CreateVector(_o->name) : 0; + auto _aclConnectionHandle = _o->aclConnectionHandle; + auto _channelInfo_type = _o->channelInfo.type; + auto _channelInfo = _o->channelInfo.Pack(_fbb); + auto _hubId = _o->hubId; + auto _endpointId = _o->endpointId; + return chre::fbs::CreateBtSocketOpen( + _fbb, + _socketId, + _name, + _aclConnectionHandle, + _channelInfo_type, + _channelInfo, + _hubId, + _endpointId); +} + +inline BtSocketOpenResponseT *BtSocketOpenResponse::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::BtSocketOpenResponseT> _o = std::unique_ptr<chre::fbs::BtSocketOpenResponseT>(new BtSocketOpenResponseT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void BtSocketOpenResponse::UnPackTo(BtSocketOpenResponseT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = socketId(); _o->socketId = _e; } + { auto _e = status(); _o->status = _e; } + { auto _e = reason(); if (_e) { _o->reason.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->reason[_i] = _e->Get(_i); } } } +} + +inline flatbuffers::Offset<BtSocketOpenResponse> BtSocketOpenResponse::Pack(flatbuffers::FlatBufferBuilder &_fbb, const BtSocketOpenResponseT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateBtSocketOpenResponse(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<BtSocketOpenResponse> CreateBtSocketOpenResponse(flatbuffers::FlatBufferBuilder &_fbb, const BtSocketOpenResponseT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const BtSocketOpenResponseT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _socketId = _o->socketId; + auto _status = _o->status; + auto _reason = _o->reason.size() ? _fbb.CreateVector(_o->reason) : 0; + return chre::fbs::CreateBtSocketOpenResponse( + _fbb, + _socketId, + _status, + _reason); +} + +inline BtSocketCloseT *BtSocketClose::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::BtSocketCloseT> _o = std::unique_ptr<chre::fbs::BtSocketCloseT>(new BtSocketCloseT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void BtSocketClose::UnPackTo(BtSocketCloseT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = socketId(); _o->socketId = _e; } + { auto _e = reason(); if (_e) { _o->reason.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->reason[_i] = _e->Get(_i); } } } +} + +inline flatbuffers::Offset<BtSocketClose> BtSocketClose::Pack(flatbuffers::FlatBufferBuilder &_fbb, const BtSocketCloseT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateBtSocketClose(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<BtSocketClose> CreateBtSocketClose(flatbuffers::FlatBufferBuilder &_fbb, const BtSocketCloseT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const BtSocketCloseT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _socketId = _o->socketId; + auto _reason = _o->reason.size() ? _fbb.CreateVector(_o->reason) : 0; + return chre::fbs::CreateBtSocketClose( + _fbb, + _socketId, + _reason); +} + +inline BtSocketCloseResponseT *BtSocketCloseResponse::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::BtSocketCloseResponseT> _o = std::unique_ptr<chre::fbs::BtSocketCloseResponseT>(new BtSocketCloseResponseT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void BtSocketCloseResponse::UnPackTo(BtSocketCloseResponseT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = socketId(); _o->socketId = _e; } +} + +inline flatbuffers::Offset<BtSocketCloseResponse> BtSocketCloseResponse::Pack(flatbuffers::FlatBufferBuilder &_fbb, const BtSocketCloseResponseT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateBtSocketCloseResponse(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<BtSocketCloseResponse> CreateBtSocketCloseResponse(flatbuffers::FlatBufferBuilder &_fbb, const BtSocketCloseResponseT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const BtSocketCloseResponseT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _socketId = _o->socketId; + return chre::fbs::CreateBtSocketCloseResponse( + _fbb, + _socketId); +} + +inline VendorHubInfoT *VendorHubInfo::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::VendorHubInfoT> _o = std::unique_ptr<chre::fbs::VendorHubInfoT>(new VendorHubInfoT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void VendorHubInfo::UnPackTo(VendorHubInfoT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = name(); if (_e) { _o->name.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->name[_i] = _e->Get(_i); } } } + { auto _e = version(); _o->version = _e; } + { auto _e = extended_info(); if (_e) { _o->extended_info.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->extended_info[_i] = _e->Get(_i); } } } +} + +inline flatbuffers::Offset<VendorHubInfo> VendorHubInfo::Pack(flatbuffers::FlatBufferBuilder &_fbb, const VendorHubInfoT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateVendorHubInfo(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<VendorHubInfo> CreateVendorHubInfo(flatbuffers::FlatBufferBuilder &_fbb, const VendorHubInfoT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const VendorHubInfoT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _name = _o->name.size() ? _fbb.CreateVector(_o->name) : 0; + auto _version = _o->version; + auto _extended_info = _o->extended_info.size() ? _fbb.CreateVector(_o->extended_info) : 0; + return chre::fbs::CreateVendorHubInfo( + _fbb, + _name, + _version, + _extended_info); +} + +inline MessageHubT *MessageHub::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::MessageHubT> _o = std::unique_ptr<chre::fbs::MessageHubT>(new MessageHubT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void MessageHub::UnPackTo(MessageHubT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = id(); _o->id = _e; } + { auto _e = details_type(); _o->details.type = _e; } + { auto _e = details(); if (_e) _o->details.value = chre::fbs::MessageHubDetailsUnion::UnPack(_e, details_type(), _resolver); } +} + +inline flatbuffers::Offset<MessageHub> MessageHub::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MessageHubT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateMessageHub(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<MessageHub> CreateMessageHub(flatbuffers::FlatBufferBuilder &_fbb, const MessageHubT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MessageHubT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _id = _o->id; + auto _details_type = _o->details.type; + auto _details = _o->details.Pack(_fbb); + return chre::fbs::CreateMessageHub( + _fbb, + _id, + _details_type, + _details); +} + +inline RegisterMessageHubT *RegisterMessageHub::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::RegisterMessageHubT> _o = std::unique_ptr<chre::fbs::RegisterMessageHubT>(new RegisterMessageHubT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void RegisterMessageHub::UnPackTo(RegisterMessageHubT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = hub(); if (_e) _o->hub = std::unique_ptr<chre::fbs::MessageHubT>(_e->UnPack(_resolver)); } +} + +inline flatbuffers::Offset<RegisterMessageHub> RegisterMessageHub::Pack(flatbuffers::FlatBufferBuilder &_fbb, const RegisterMessageHubT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateRegisterMessageHub(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<RegisterMessageHub> CreateRegisterMessageHub(flatbuffers::FlatBufferBuilder &_fbb, const RegisterMessageHubT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const RegisterMessageHubT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _hub = _o->hub ? CreateMessageHub(_fbb, _o->hub.get(), _rehasher) : 0; + return chre::fbs::CreateRegisterMessageHub( + _fbb, + _hub); +} + +inline UnregisterMessageHubT *UnregisterMessageHub::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::UnregisterMessageHubT> _o = std::unique_ptr<chre::fbs::UnregisterMessageHubT>(new UnregisterMessageHubT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void UnregisterMessageHub::UnPackTo(UnregisterMessageHubT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = id(); _o->id = _e; } +} + +inline flatbuffers::Offset<UnregisterMessageHub> UnregisterMessageHub::Pack(flatbuffers::FlatBufferBuilder &_fbb, const UnregisterMessageHubT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateUnregisterMessageHub(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<UnregisterMessageHub> CreateUnregisterMessageHub(flatbuffers::FlatBufferBuilder &_fbb, const UnregisterMessageHubT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const UnregisterMessageHubT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _id = _o->id; + return chre::fbs::CreateUnregisterMessageHub( + _fbb, + _id); +} + +inline EndpointIdT *EndpointId::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::EndpointIdT> _o = std::unique_ptr<chre::fbs::EndpointIdT>(new EndpointIdT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void EndpointId::UnPackTo(EndpointIdT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = hubId(); _o->hubId = _e; } + { auto _e = id(); _o->id = _e; } +} + +inline flatbuffers::Offset<EndpointId> EndpointId::Pack(flatbuffers::FlatBufferBuilder &_fbb, const EndpointIdT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateEndpointId(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<EndpointId> CreateEndpointId(flatbuffers::FlatBufferBuilder &_fbb, const EndpointIdT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const EndpointIdT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _hubId = _o->hubId; + auto _id = _o->id; + return chre::fbs::CreateEndpointId( + _fbb, + _hubId, + _id); +} + +inline ServiceT *Service::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::ServiceT> _o = std::unique_ptr<chre::fbs::ServiceT>(new ServiceT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void Service::UnPackTo(ServiceT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = format(); _o->format = _e; } + { auto _e = descriptor(); if (_e) { _o->descriptor.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->descriptor[_i] = _e->Get(_i); } } } + { auto _e = major_version(); _o->major_version = _e; } + { auto _e = minor_version(); _o->minor_version = _e; } +} + +inline flatbuffers::Offset<Service> Service::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ServiceT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateService(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<Service> CreateService(flatbuffers::FlatBufferBuilder &_fbb, const ServiceT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ServiceT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _format = _o->format; + auto _descriptor = _o->descriptor.size() ? _fbb.CreateVector(_o->descriptor) : 0; + auto _major_version = _o->major_version; + auto _minor_version = _o->minor_version; + return chre::fbs::CreateService( + _fbb, + _format, + _descriptor, + _major_version, + _minor_version); +} + +inline EndpointInfoT *EndpointInfo::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::EndpointInfoT> _o = std::unique_ptr<chre::fbs::EndpointInfoT>(new EndpointInfoT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void EndpointInfo::UnPackTo(EndpointInfoT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = id(); if (_e) _o->id = std::unique_ptr<chre::fbs::EndpointIdT>(_e->UnPack(_resolver)); } + { auto _e = type(); _o->type = _e; } + { auto _e = name(); if (_e) { _o->name.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->name[_i] = _e->Get(_i); } } } + { auto _e = version(); _o->version = _e; } + { auto _e = required_permissions(); _o->required_permissions = _e; } + { auto _e = services(); if (_e) { _o->services.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->services[_i] = std::unique_ptr<chre::fbs::ServiceT>(_e->Get(_i)->UnPack(_resolver)); } } } +} + +inline flatbuffers::Offset<EndpointInfo> EndpointInfo::Pack(flatbuffers::FlatBufferBuilder &_fbb, const EndpointInfoT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateEndpointInfo(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<EndpointInfo> CreateEndpointInfo(flatbuffers::FlatBufferBuilder &_fbb, const EndpointInfoT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const EndpointInfoT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _id = _o->id ? CreateEndpointId(_fbb, _o->id.get(), _rehasher) : 0; + auto _type = _o->type; + auto _name = _o->name.size() ? _fbb.CreateVector(_o->name) : 0; + auto _version = _o->version; + auto _required_permissions = _o->required_permissions; + auto _services = _o->services.size() ? _fbb.CreateVector<flatbuffers::Offset<chre::fbs::Service>> (_o->services.size(), [](size_t i, _VectorArgs *__va) { return CreateService(*__va->__fbb, __va->__o->services[i].get(), __va->__rehasher); }, &_va ) : 0; + return chre::fbs::CreateEndpointInfo( + _fbb, + _id, + _type, + _name, + _version, + _required_permissions, + _services); +} + +inline RegisterEndpointT *RegisterEndpoint::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::RegisterEndpointT> _o = std::unique_ptr<chre::fbs::RegisterEndpointT>(new RegisterEndpointT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void RegisterEndpoint::UnPackTo(RegisterEndpointT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = endpoint(); if (_e) _o->endpoint = std::unique_ptr<chre::fbs::EndpointInfoT>(_e->UnPack(_resolver)); } +} + +inline flatbuffers::Offset<RegisterEndpoint> RegisterEndpoint::Pack(flatbuffers::FlatBufferBuilder &_fbb, const RegisterEndpointT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateRegisterEndpoint(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<RegisterEndpoint> CreateRegisterEndpoint(flatbuffers::FlatBufferBuilder &_fbb, const RegisterEndpointT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const RegisterEndpointT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _endpoint = _o->endpoint ? CreateEndpointInfo(_fbb, _o->endpoint.get(), _rehasher) : 0; + return chre::fbs::CreateRegisterEndpoint( + _fbb, + _endpoint); +} + +inline UnregisterEndpointT *UnregisterEndpoint::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::UnregisterEndpointT> _o = std::unique_ptr<chre::fbs::UnregisterEndpointT>(new UnregisterEndpointT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void UnregisterEndpoint::UnPackTo(UnregisterEndpointT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = endpoint(); if (_e) _o->endpoint = std::unique_ptr<chre::fbs::EndpointIdT>(_e->UnPack(_resolver)); } +} + +inline flatbuffers::Offset<UnregisterEndpoint> UnregisterEndpoint::Pack(flatbuffers::FlatBufferBuilder &_fbb, const UnregisterEndpointT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateUnregisterEndpoint(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<UnregisterEndpoint> CreateUnregisterEndpoint(flatbuffers::FlatBufferBuilder &_fbb, const UnregisterEndpointT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const UnregisterEndpointT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _endpoint = _o->endpoint ? CreateEndpointId(_fbb, _o->endpoint.get(), _rehasher) : 0; + return chre::fbs::CreateUnregisterEndpoint( + _fbb, + _endpoint); +} + +inline GetMessageHubsAndEndpointsRequestT *GetMessageHubsAndEndpointsRequest::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::GetMessageHubsAndEndpointsRequestT> _o = std::unique_ptr<chre::fbs::GetMessageHubsAndEndpointsRequestT>(new GetMessageHubsAndEndpointsRequestT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void GetMessageHubsAndEndpointsRequest::UnPackTo(GetMessageHubsAndEndpointsRequestT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset<GetMessageHubsAndEndpointsRequest> GetMessageHubsAndEndpointsRequest::Pack(flatbuffers::FlatBufferBuilder &_fbb, const GetMessageHubsAndEndpointsRequestT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateGetMessageHubsAndEndpointsRequest(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<GetMessageHubsAndEndpointsRequest> CreateGetMessageHubsAndEndpointsRequest(flatbuffers::FlatBufferBuilder &_fbb, const GetMessageHubsAndEndpointsRequestT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const GetMessageHubsAndEndpointsRequestT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return chre::fbs::CreateGetMessageHubsAndEndpointsRequest( + _fbb); +} + +inline GetMessageHubsAndEndpointsResponseT *GetMessageHubsAndEndpointsResponse::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::GetMessageHubsAndEndpointsResponseT> _o = std::unique_ptr<chre::fbs::GetMessageHubsAndEndpointsResponseT>(new GetMessageHubsAndEndpointsResponseT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void GetMessageHubsAndEndpointsResponse::UnPackTo(GetMessageHubsAndEndpointsResponseT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = hubs(); if (_e) { _o->hubs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->hubs[_i] = std::unique_ptr<chre::fbs::MessageHubT>(_e->Get(_i)->UnPack(_resolver)); } } } + { auto _e = endpoints(); if (_e) { _o->endpoints.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->endpoints[_i] = std::unique_ptr<chre::fbs::EndpointInfoT>(_e->Get(_i)->UnPack(_resolver)); } } } +} + +inline flatbuffers::Offset<GetMessageHubsAndEndpointsResponse> GetMessageHubsAndEndpointsResponse::Pack(flatbuffers::FlatBufferBuilder &_fbb, const GetMessageHubsAndEndpointsResponseT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateGetMessageHubsAndEndpointsResponse(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<GetMessageHubsAndEndpointsResponse> CreateGetMessageHubsAndEndpointsResponse(flatbuffers::FlatBufferBuilder &_fbb, const GetMessageHubsAndEndpointsResponseT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const GetMessageHubsAndEndpointsResponseT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _hubs = _o->hubs.size() ? _fbb.CreateVector<flatbuffers::Offset<chre::fbs::MessageHub>> (_o->hubs.size(), [](size_t i, _VectorArgs *__va) { return CreateMessageHub(*__va->__fbb, __va->__o->hubs[i].get(), __va->__rehasher); }, &_va ) : 0; + auto _endpoints = _o->endpoints.size() ? _fbb.CreateVector<flatbuffers::Offset<chre::fbs::EndpointInfo>> (_o->endpoints.size(), [](size_t i, _VectorArgs *__va) { return CreateEndpointInfo(*__va->__fbb, __va->__o->endpoints[i].get(), __va->__rehasher); }, &_va ) : 0; + return chre::fbs::CreateGetMessageHubsAndEndpointsResponse( + _fbb, + _hubs, + _endpoints); +} + +inline OpenEndpointSessionRequestT *OpenEndpointSessionRequest::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::OpenEndpointSessionRequestT> _o = std::unique_ptr<chre::fbs::OpenEndpointSessionRequestT>(new OpenEndpointSessionRequestT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void OpenEndpointSessionRequest::UnPackTo(OpenEndpointSessionRequestT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = id(); _o->id = _e; } + { auto _e = fromEndpoint(); if (_e) _o->fromEndpoint = std::unique_ptr<chre::fbs::EndpointIdT>(_e->UnPack(_resolver)); } + { auto _e = toEndpoint(); if (_e) _o->toEndpoint = std::unique_ptr<chre::fbs::EndpointIdT>(_e->UnPack(_resolver)); } + { auto _e = serviceDescriptor(); if (_e) { _o->serviceDescriptor.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->serviceDescriptor[_i] = _e->Get(_i); } } } +} + +inline flatbuffers::Offset<OpenEndpointSessionRequest> OpenEndpointSessionRequest::Pack(flatbuffers::FlatBufferBuilder &_fbb, const OpenEndpointSessionRequestT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateOpenEndpointSessionRequest(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<OpenEndpointSessionRequest> CreateOpenEndpointSessionRequest(flatbuffers::FlatBufferBuilder &_fbb, const OpenEndpointSessionRequestT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const OpenEndpointSessionRequestT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _id = _o->id; + auto _fromEndpoint = _o->fromEndpoint ? CreateEndpointId(_fbb, _o->fromEndpoint.get(), _rehasher) : 0; + auto _toEndpoint = _o->toEndpoint ? CreateEndpointId(_fbb, _o->toEndpoint.get(), _rehasher) : 0; + auto _serviceDescriptor = _o->serviceDescriptor.size() ? _fbb.CreateVector(_o->serviceDescriptor) : 0; + return chre::fbs::CreateOpenEndpointSessionRequest( + _fbb, + _id, + _fromEndpoint, + _toEndpoint, + _serviceDescriptor); +} + +inline EndpointSessionOpenedT *EndpointSessionOpened::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::EndpointSessionOpenedT> _o = std::unique_ptr<chre::fbs::EndpointSessionOpenedT>(new EndpointSessionOpenedT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void EndpointSessionOpened::UnPackTo(EndpointSessionOpenedT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = id(); _o->id = _e; } +} + +inline flatbuffers::Offset<EndpointSessionOpened> EndpointSessionOpened::Pack(flatbuffers::FlatBufferBuilder &_fbb, const EndpointSessionOpenedT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateEndpointSessionOpened(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<EndpointSessionOpened> CreateEndpointSessionOpened(flatbuffers::FlatBufferBuilder &_fbb, const EndpointSessionOpenedT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const EndpointSessionOpenedT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _id = _o->id; + return chre::fbs::CreateEndpointSessionOpened( + _fbb, + _id); +} + +inline EndpointSessionClosedT *EndpointSessionClosed::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::EndpointSessionClosedT> _o = std::unique_ptr<chre::fbs::EndpointSessionClosedT>(new EndpointSessionClosedT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void EndpointSessionClosed::UnPackTo(EndpointSessionClosedT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = id(); _o->id = _e; } + { auto _e = reason(); _o->reason = _e; } +} + +inline flatbuffers::Offset<EndpointSessionClosed> EndpointSessionClosed::Pack(flatbuffers::FlatBufferBuilder &_fbb, const EndpointSessionClosedT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateEndpointSessionClosed(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<EndpointSessionClosed> CreateEndpointSessionClosed(flatbuffers::FlatBufferBuilder &_fbb, const EndpointSessionClosedT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const EndpointSessionClosedT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _id = _o->id; + auto _reason = _o->reason; + return chre::fbs::CreateEndpointSessionClosed( + _fbb, + _id, + _reason); +} + +inline EndpointSessionMessageT *EndpointSessionMessage::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::EndpointSessionMessageT> _o = std::unique_ptr<chre::fbs::EndpointSessionMessageT>(new EndpointSessionMessageT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void EndpointSessionMessage::UnPackTo(EndpointSessionMessageT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = session_id(); _o->session_id = _e; } + { auto _e = type(); _o->type = _e; } + { auto _e = permissions(); _o->permissions = _e; } + { auto _e = data(); if (_e) { _o->data.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->data[_i] = _e->Get(_i); } } } + { auto _e = flags(); _o->flags = _e; } + { auto _e = sequence_number(); _o->sequence_number = _e; } +} + +inline flatbuffers::Offset<EndpointSessionMessage> EndpointSessionMessage::Pack(flatbuffers::FlatBufferBuilder &_fbb, const EndpointSessionMessageT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateEndpointSessionMessage(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<EndpointSessionMessage> CreateEndpointSessionMessage(flatbuffers::FlatBufferBuilder &_fbb, const EndpointSessionMessageT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const EndpointSessionMessageT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _session_id = _o->session_id; + auto _type = _o->type; + auto _permissions = _o->permissions; + auto _data = _o->data.size() ? _fbb.CreateVector(_o->data) : 0; + auto _flags = _o->flags; + auto _sequence_number = _o->sequence_number; + return chre::fbs::CreateEndpointSessionMessage( + _fbb, + _session_id, + _type, + _permissions, + _data, + _flags, + _sequence_number); +} + +inline EndpointSessionMessageDeliveryStatusT *EndpointSessionMessageDeliveryStatus::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + std::unique_ptr<chre::fbs::EndpointSessionMessageDeliveryStatusT> _o = std::unique_ptr<chre::fbs::EndpointSessionMessageDeliveryStatusT>(new EndpointSessionMessageDeliveryStatusT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void EndpointSessionMessageDeliveryStatus::UnPackTo(EndpointSessionMessageDeliveryStatusT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = session_id(); _o->session_id = _e; } + { auto _e = status(); if (_e) _o->status = std::unique_ptr<chre::fbs::MessageDeliveryStatusT>(_e->UnPack(_resolver)); } +} + +inline flatbuffers::Offset<EndpointSessionMessageDeliveryStatus> EndpointSessionMessageDeliveryStatus::Pack(flatbuffers::FlatBufferBuilder &_fbb, const EndpointSessionMessageDeliveryStatusT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateEndpointSessionMessageDeliveryStatus(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset<EndpointSessionMessageDeliveryStatus> CreateEndpointSessionMessageDeliveryStatus(flatbuffers::FlatBufferBuilder &_fbb, const EndpointSessionMessageDeliveryStatusT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const EndpointSessionMessageDeliveryStatusT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _session_id = _o->session_id; + auto _status = _o->status ? CreateMessageDeliveryStatus(_fbb, _o->status.get(), _rehasher) : 0; + return chre::fbs::CreateEndpointSessionMessageDeliveryStatus( + _fbb, + _session_id, + _status); +} + inline MessageContainerT *MessageContainer::UnPack(const flatbuffers::resolver_function_t *_resolver) const { std::unique_ptr<chre::fbs::MessageContainerT> _o = std::unique_ptr<chre::fbs::MessageContainerT>(new MessageContainerT()); UnPackTo(_o.get(), _resolver); @@ -5249,6 +8706,165 @@ _host_addr); } +inline bool VerifyChannelInfo(flatbuffers::Verifier &verifier, const void *obj, ChannelInfo type) { + switch (type) { + case ChannelInfo::NONE: { + return true; + } + case ChannelInfo::LeCocChannelInfo: { + auto ptr = reinterpret_cast<const chre::fbs::LeCocChannelInfo *>(obj); + return verifier.VerifyTable(ptr); + } + default: return true; + } +} + +inline bool VerifyChannelInfoVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) { + if (!values || !types) return !values && !types; + if (values->size() != types->size()) return false; + for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) { + if (!VerifyChannelInfo( + verifier, values->Get(i), types->GetEnum<ChannelInfo>(i))) { + return false; + } + } + return true; +} + +inline void *ChannelInfoUnion::UnPack(const void *obj, ChannelInfo type, const flatbuffers::resolver_function_t *resolver) { + switch (type) { + case ChannelInfo::LeCocChannelInfo: { + auto ptr = reinterpret_cast<const chre::fbs::LeCocChannelInfo *>(obj); + return ptr->UnPack(resolver); + } + default: return nullptr; + } +} + +inline flatbuffers::Offset<void> ChannelInfoUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const { + switch (type) { + case ChannelInfo::LeCocChannelInfo: { + auto ptr = reinterpret_cast<const chre::fbs::LeCocChannelInfoT *>(value); + return CreateLeCocChannelInfo(_fbb, ptr, _rehasher).Union(); + } + default: return 0; + } +} + +inline ChannelInfoUnion::ChannelInfoUnion(const ChannelInfoUnion &u) : type(u.type), value(nullptr) { + switch (type) { + case ChannelInfo::LeCocChannelInfo: { + value = new chre::fbs::LeCocChannelInfoT(*reinterpret_cast<chre::fbs::LeCocChannelInfoT *>(u.value)); + break; + } + default: + break; + } +} + +inline void ChannelInfoUnion::Reset() { + switch (type) { + case ChannelInfo::LeCocChannelInfo: { + auto ptr = reinterpret_cast<chre::fbs::LeCocChannelInfoT *>(value); + delete ptr; + break; + } + default: break; + } + value = nullptr; + type = ChannelInfo::NONE; +} + +inline bool VerifyMessageHubDetails(flatbuffers::Verifier &verifier, const void *obj, MessageHubDetails type) { + switch (type) { + case MessageHubDetails::NONE: { + return true; + } + case MessageHubDetails::HubInfoResponse: { + auto ptr = reinterpret_cast<const chre::fbs::HubInfoResponse *>(obj); + return verifier.VerifyTable(ptr); + } + case MessageHubDetails::VendorHubInfo: { + auto ptr = reinterpret_cast<const chre::fbs::VendorHubInfo *>(obj); + return verifier.VerifyTable(ptr); + } + default: return true; + } +} + +inline bool VerifyMessageHubDetailsVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) { + if (!values || !types) return !values && !types; + if (values->size() != types->size()) return false; + for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) { + if (!VerifyMessageHubDetails( + verifier, values->Get(i), types->GetEnum<MessageHubDetails>(i))) { + return false; + } + } + return true; +} + +inline void *MessageHubDetailsUnion::UnPack(const void *obj, MessageHubDetails type, const flatbuffers::resolver_function_t *resolver) { + switch (type) { + case MessageHubDetails::HubInfoResponse: { + auto ptr = reinterpret_cast<const chre::fbs::HubInfoResponse *>(obj); + return ptr->UnPack(resolver); + } + case MessageHubDetails::VendorHubInfo: { + auto ptr = reinterpret_cast<const chre::fbs::VendorHubInfo *>(obj); + return ptr->UnPack(resolver); + } + default: return nullptr; + } +} + +inline flatbuffers::Offset<void> MessageHubDetailsUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const { + switch (type) { + case MessageHubDetails::HubInfoResponse: { + auto ptr = reinterpret_cast<const chre::fbs::HubInfoResponseT *>(value); + return CreateHubInfoResponse(_fbb, ptr, _rehasher).Union(); + } + case MessageHubDetails::VendorHubInfo: { + auto ptr = reinterpret_cast<const chre::fbs::VendorHubInfoT *>(value); + return CreateVendorHubInfo(_fbb, ptr, _rehasher).Union(); + } + default: return 0; + } +} + +inline MessageHubDetailsUnion::MessageHubDetailsUnion(const MessageHubDetailsUnion &u) : type(u.type), value(nullptr) { + switch (type) { + case MessageHubDetails::HubInfoResponse: { + value = new chre::fbs::HubInfoResponseT(*reinterpret_cast<chre::fbs::HubInfoResponseT *>(u.value)); + break; + } + case MessageHubDetails::VendorHubInfo: { + value = new chre::fbs::VendorHubInfoT(*reinterpret_cast<chre::fbs::VendorHubInfoT *>(u.value)); + break; + } + default: + break; + } +} + +inline void MessageHubDetailsUnion::Reset() { + switch (type) { + case MessageHubDetails::HubInfoResponse: { + auto ptr = reinterpret_cast<chre::fbs::HubInfoResponseT *>(value); + delete ptr; + break; + } + case MessageHubDetails::VendorHubInfo: { + auto ptr = reinterpret_cast<chre::fbs::VendorHubInfoT *>(value); + delete ptr; + break; + } + default: break; + } + value = nullptr; + type = MessageHubDetails::NONE; +} + inline bool VerifyChreMessage(flatbuffers::Verifier &verifier, const void *obj, ChreMessage type) { switch (type) { case ChreMessage::NONE: { @@ -5382,6 +8998,66 @@ auto ptr = reinterpret_cast<const chre::fbs::MessageDeliveryStatus *>(obj); return verifier.VerifyTable(ptr); } + case ChreMessage::BtSocketOpen: { + auto ptr = reinterpret_cast<const chre::fbs::BtSocketOpen *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::BtSocketOpenResponse: { + auto ptr = reinterpret_cast<const chre::fbs::BtSocketOpenResponse *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::BtSocketClose: { + auto ptr = reinterpret_cast<const chre::fbs::BtSocketClose *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::BtSocketCloseResponse: { + auto ptr = reinterpret_cast<const chre::fbs::BtSocketCloseResponse *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::GetMessageHubsAndEndpointsRequest: { + auto ptr = reinterpret_cast<const chre::fbs::GetMessageHubsAndEndpointsRequest *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::GetMessageHubsAndEndpointsResponse: { + auto ptr = reinterpret_cast<const chre::fbs::GetMessageHubsAndEndpointsResponse *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::RegisterMessageHub: { + auto ptr = reinterpret_cast<const chre::fbs::RegisterMessageHub *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::UnregisterMessageHub: { + auto ptr = reinterpret_cast<const chre::fbs::UnregisterMessageHub *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::RegisterEndpoint: { + auto ptr = reinterpret_cast<const chre::fbs::RegisterEndpoint *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::UnregisterEndpoint: { + auto ptr = reinterpret_cast<const chre::fbs::UnregisterEndpoint *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::OpenEndpointSessionRequest: { + auto ptr = reinterpret_cast<const chre::fbs::OpenEndpointSessionRequest *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::EndpointSessionOpened: { + auto ptr = reinterpret_cast<const chre::fbs::EndpointSessionOpened *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::EndpointSessionClosed: { + auto ptr = reinterpret_cast<const chre::fbs::EndpointSessionClosed *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::EndpointSessionMessage: { + auto ptr = reinterpret_cast<const chre::fbs::EndpointSessionMessage *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::EndpointSessionMessageDeliveryStatus: { + auto ptr = reinterpret_cast<const chre::fbs::EndpointSessionMessageDeliveryStatus *>(obj); + return verifier.VerifyTable(ptr); + } default: return true; } } @@ -5528,6 +9204,66 @@ auto ptr = reinterpret_cast<const chre::fbs::MessageDeliveryStatus *>(obj); return ptr->UnPack(resolver); } + case ChreMessage::BtSocketOpen: { + auto ptr = reinterpret_cast<const chre::fbs::BtSocketOpen *>(obj); + return ptr->UnPack(resolver); + } + case ChreMessage::BtSocketOpenResponse: { + auto ptr = reinterpret_cast<const chre::fbs::BtSocketOpenResponse *>(obj); + return ptr->UnPack(resolver); + } + case ChreMessage::BtSocketClose: { + auto ptr = reinterpret_cast<const chre::fbs::BtSocketClose *>(obj); + return ptr->UnPack(resolver); + } + case ChreMessage::BtSocketCloseResponse: { + auto ptr = reinterpret_cast<const chre::fbs::BtSocketCloseResponse *>(obj); + return ptr->UnPack(resolver); + } + case ChreMessage::GetMessageHubsAndEndpointsRequest: { + auto ptr = reinterpret_cast<const chre::fbs::GetMessageHubsAndEndpointsRequest *>(obj); + return ptr->UnPack(resolver); + } + case ChreMessage::GetMessageHubsAndEndpointsResponse: { + auto ptr = reinterpret_cast<const chre::fbs::GetMessageHubsAndEndpointsResponse *>(obj); + return ptr->UnPack(resolver); + } + case ChreMessage::RegisterMessageHub: { + auto ptr = reinterpret_cast<const chre::fbs::RegisterMessageHub *>(obj); + return ptr->UnPack(resolver); + } + case ChreMessage::UnregisterMessageHub: { + auto ptr = reinterpret_cast<const chre::fbs::UnregisterMessageHub *>(obj); + return ptr->UnPack(resolver); + } + case ChreMessage::RegisterEndpoint: { + auto ptr = reinterpret_cast<const chre::fbs::RegisterEndpoint *>(obj); + return ptr->UnPack(resolver); + } + case ChreMessage::UnregisterEndpoint: { + auto ptr = reinterpret_cast<const chre::fbs::UnregisterEndpoint *>(obj); + return ptr->UnPack(resolver); + } + case ChreMessage::OpenEndpointSessionRequest: { + auto ptr = reinterpret_cast<const chre::fbs::OpenEndpointSessionRequest *>(obj); + return ptr->UnPack(resolver); + } + case ChreMessage::EndpointSessionOpened: { + auto ptr = reinterpret_cast<const chre::fbs::EndpointSessionOpened *>(obj); + return ptr->UnPack(resolver); + } + case ChreMessage::EndpointSessionClosed: { + auto ptr = reinterpret_cast<const chre::fbs::EndpointSessionClosed *>(obj); + return ptr->UnPack(resolver); + } + case ChreMessage::EndpointSessionMessage: { + auto ptr = reinterpret_cast<const chre::fbs::EndpointSessionMessage *>(obj); + return ptr->UnPack(resolver); + } + case ChreMessage::EndpointSessionMessageDeliveryStatus: { + auto ptr = reinterpret_cast<const chre::fbs::EndpointSessionMessageDeliveryStatus *>(obj); + return ptr->UnPack(resolver); + } default: return nullptr; } } @@ -5662,6 +9398,66 @@ auto ptr = reinterpret_cast<const chre::fbs::MessageDeliveryStatusT *>(value); return CreateMessageDeliveryStatus(_fbb, ptr, _rehasher).Union(); } + case ChreMessage::BtSocketOpen: { + auto ptr = reinterpret_cast<const chre::fbs::BtSocketOpenT *>(value); + return CreateBtSocketOpen(_fbb, ptr, _rehasher).Union(); + } + case ChreMessage::BtSocketOpenResponse: { + auto ptr = reinterpret_cast<const chre::fbs::BtSocketOpenResponseT *>(value); + return CreateBtSocketOpenResponse(_fbb, ptr, _rehasher).Union(); + } + case ChreMessage::BtSocketClose: { + auto ptr = reinterpret_cast<const chre::fbs::BtSocketCloseT *>(value); + return CreateBtSocketClose(_fbb, ptr, _rehasher).Union(); + } + case ChreMessage::BtSocketCloseResponse: { + auto ptr = reinterpret_cast<const chre::fbs::BtSocketCloseResponseT *>(value); + return CreateBtSocketCloseResponse(_fbb, ptr, _rehasher).Union(); + } + case ChreMessage::GetMessageHubsAndEndpointsRequest: { + auto ptr = reinterpret_cast<const chre::fbs::GetMessageHubsAndEndpointsRequestT *>(value); + return CreateGetMessageHubsAndEndpointsRequest(_fbb, ptr, _rehasher).Union(); + } + case ChreMessage::GetMessageHubsAndEndpointsResponse: { + auto ptr = reinterpret_cast<const chre::fbs::GetMessageHubsAndEndpointsResponseT *>(value); + return CreateGetMessageHubsAndEndpointsResponse(_fbb, ptr, _rehasher).Union(); + } + case ChreMessage::RegisterMessageHub: { + auto ptr = reinterpret_cast<const chre::fbs::RegisterMessageHubT *>(value); + return CreateRegisterMessageHub(_fbb, ptr, _rehasher).Union(); + } + case ChreMessage::UnregisterMessageHub: { + auto ptr = reinterpret_cast<const chre::fbs::UnregisterMessageHubT *>(value); + return CreateUnregisterMessageHub(_fbb, ptr, _rehasher).Union(); + } + case ChreMessage::RegisterEndpoint: { + auto ptr = reinterpret_cast<const chre::fbs::RegisterEndpointT *>(value); + return CreateRegisterEndpoint(_fbb, ptr, _rehasher).Union(); + } + case ChreMessage::UnregisterEndpoint: { + auto ptr = reinterpret_cast<const chre::fbs::UnregisterEndpointT *>(value); + return CreateUnregisterEndpoint(_fbb, ptr, _rehasher).Union(); + } + case ChreMessage::OpenEndpointSessionRequest: { + auto ptr = reinterpret_cast<const chre::fbs::OpenEndpointSessionRequestT *>(value); + return CreateOpenEndpointSessionRequest(_fbb, ptr, _rehasher).Union(); + } + case ChreMessage::EndpointSessionOpened: { + auto ptr = reinterpret_cast<const chre::fbs::EndpointSessionOpenedT *>(value); + return CreateEndpointSessionOpened(_fbb, ptr, _rehasher).Union(); + } + case ChreMessage::EndpointSessionClosed: { + auto ptr = reinterpret_cast<const chre::fbs::EndpointSessionClosedT *>(value); + return CreateEndpointSessionClosed(_fbb, ptr, _rehasher).Union(); + } + case ChreMessage::EndpointSessionMessage: { + auto ptr = reinterpret_cast<const chre::fbs::EndpointSessionMessageT *>(value); + return CreateEndpointSessionMessage(_fbb, ptr, _rehasher).Union(); + } + case ChreMessage::EndpointSessionMessageDeliveryStatus: { + auto ptr = reinterpret_cast<const chre::fbs::EndpointSessionMessageDeliveryStatusT *>(value); + return CreateEndpointSessionMessageDeliveryStatus(_fbb, ptr, _rehasher).Union(); + } default: return 0; } } @@ -5796,6 +9592,66 @@ value = new chre::fbs::MessageDeliveryStatusT(*reinterpret_cast<chre::fbs::MessageDeliveryStatusT *>(u.value)); break; } + case ChreMessage::BtSocketOpen: { + value = new chre::fbs::BtSocketOpenT(*reinterpret_cast<chre::fbs::BtSocketOpenT *>(u.value)); + break; + } + case ChreMessage::BtSocketOpenResponse: { + value = new chre::fbs::BtSocketOpenResponseT(*reinterpret_cast<chre::fbs::BtSocketOpenResponseT *>(u.value)); + break; + } + case ChreMessage::BtSocketClose: { + value = new chre::fbs::BtSocketCloseT(*reinterpret_cast<chre::fbs::BtSocketCloseT *>(u.value)); + break; + } + case ChreMessage::BtSocketCloseResponse: { + value = new chre::fbs::BtSocketCloseResponseT(*reinterpret_cast<chre::fbs::BtSocketCloseResponseT *>(u.value)); + break; + } + case ChreMessage::GetMessageHubsAndEndpointsRequest: { + value = new chre::fbs::GetMessageHubsAndEndpointsRequestT(*reinterpret_cast<chre::fbs::GetMessageHubsAndEndpointsRequestT *>(u.value)); + break; + } + case ChreMessage::GetMessageHubsAndEndpointsResponse: { + FLATBUFFERS_ASSERT(false); // chre::fbs::GetMessageHubsAndEndpointsResponseT not copyable. + break; + } + case ChreMessage::RegisterMessageHub: { + FLATBUFFERS_ASSERT(false); // chre::fbs::RegisterMessageHubT not copyable. + break; + } + case ChreMessage::UnregisterMessageHub: { + value = new chre::fbs::UnregisterMessageHubT(*reinterpret_cast<chre::fbs::UnregisterMessageHubT *>(u.value)); + break; + } + case ChreMessage::RegisterEndpoint: { + FLATBUFFERS_ASSERT(false); // chre::fbs::RegisterEndpointT not copyable. + break; + } + case ChreMessage::UnregisterEndpoint: { + FLATBUFFERS_ASSERT(false); // chre::fbs::UnregisterEndpointT not copyable. + break; + } + case ChreMessage::OpenEndpointSessionRequest: { + FLATBUFFERS_ASSERT(false); // chre::fbs::OpenEndpointSessionRequestT not copyable. + break; + } + case ChreMessage::EndpointSessionOpened: { + value = new chre::fbs::EndpointSessionOpenedT(*reinterpret_cast<chre::fbs::EndpointSessionOpenedT *>(u.value)); + break; + } + case ChreMessage::EndpointSessionClosed: { + value = new chre::fbs::EndpointSessionClosedT(*reinterpret_cast<chre::fbs::EndpointSessionClosedT *>(u.value)); + break; + } + case ChreMessage::EndpointSessionMessage: { + value = new chre::fbs::EndpointSessionMessageT(*reinterpret_cast<chre::fbs::EndpointSessionMessageT *>(u.value)); + break; + } + case ChreMessage::EndpointSessionMessageDeliveryStatus: { + FLATBUFFERS_ASSERT(false); // chre::fbs::EndpointSessionMessageDeliveryStatusT not copyable. + break; + } default: break; } @@ -5963,6 +9819,81 @@ delete ptr; break; } + case ChreMessage::BtSocketOpen: { + auto ptr = reinterpret_cast<chre::fbs::BtSocketOpenT *>(value); + delete ptr; + break; + } + case ChreMessage::BtSocketOpenResponse: { + auto ptr = reinterpret_cast<chre::fbs::BtSocketOpenResponseT *>(value); + delete ptr; + break; + } + case ChreMessage::BtSocketClose: { + auto ptr = reinterpret_cast<chre::fbs::BtSocketCloseT *>(value); + delete ptr; + break; + } + case ChreMessage::BtSocketCloseResponse: { + auto ptr = reinterpret_cast<chre::fbs::BtSocketCloseResponseT *>(value); + delete ptr; + break; + } + case ChreMessage::GetMessageHubsAndEndpointsRequest: { + auto ptr = reinterpret_cast<chre::fbs::GetMessageHubsAndEndpointsRequestT *>(value); + delete ptr; + break; + } + case ChreMessage::GetMessageHubsAndEndpointsResponse: { + auto ptr = reinterpret_cast<chre::fbs::GetMessageHubsAndEndpointsResponseT *>(value); + delete ptr; + break; + } + case ChreMessage::RegisterMessageHub: { + auto ptr = reinterpret_cast<chre::fbs::RegisterMessageHubT *>(value); + delete ptr; + break; + } + case ChreMessage::UnregisterMessageHub: { + auto ptr = reinterpret_cast<chre::fbs::UnregisterMessageHubT *>(value); + delete ptr; + break; + } + case ChreMessage::RegisterEndpoint: { + auto ptr = reinterpret_cast<chre::fbs::RegisterEndpointT *>(value); + delete ptr; + break; + } + case ChreMessage::UnregisterEndpoint: { + auto ptr = reinterpret_cast<chre::fbs::UnregisterEndpointT *>(value); + delete ptr; + break; + } + case ChreMessage::OpenEndpointSessionRequest: { + auto ptr = reinterpret_cast<chre::fbs::OpenEndpointSessionRequestT *>(value); + delete ptr; + break; + } + case ChreMessage::EndpointSessionOpened: { + auto ptr = reinterpret_cast<chre::fbs::EndpointSessionOpenedT *>(value); + delete ptr; + break; + } + case ChreMessage::EndpointSessionClosed: { + auto ptr = reinterpret_cast<chre::fbs::EndpointSessionClosedT *>(value); + delete ptr; + break; + } + case ChreMessage::EndpointSessionMessage: { + auto ptr = reinterpret_cast<chre::fbs::EndpointSessionMessageT *>(value); + delete ptr; + break; + } + case ChreMessage::EndpointSessionMessageDeliveryStatus: { + auto ptr = reinterpret_cast<chre::fbs::EndpointSessionMessageDeliveryStatusT *>(value); + delete ptr; + break; + } default: break; } value = nullptr;
diff --git a/host/common/include/chre_host/hal_error.h b/host/common/include/chre_host/hal_error.h index 987ab40..9b3100d 100644 --- a/host/common/include/chre_host/hal_error.h +++ b/host/common/include/chre_host/hal_error.h
@@ -28,6 +28,7 @@ OPERATION_FAILED = -1, INVALID_RESULT = -2, INVALID_ARGUMENT = -3, + CHRE_NOT_READY = -4, // Hal client errors BINDER_CONNECTION_FAILED = -100,
diff --git a/host/common/include/chre_host/host_protocol_host.h b/host/common/include/chre_host/host_protocol_host.h index 35f1ced..80c0b04 100644 --- a/host/common/include/chre_host/host_protocol_host.h +++ b/host/common/include/chre_host/host_protocol_host.h
@@ -74,6 +74,11 @@ virtual void handleSelfTestResponse( const ::chre::fbs::SelfTestResponseT & /*response*/){}; + + virtual bool handleContextHubV4Message( + const ::chre::fbs::ChreMessageUnion & /*msg*/) { + return false; + }; }; /**
diff --git a/host/common/include/chre_host/preloaded_nanoapp_loader.h b/host/common/include/chre_host/preloaded_nanoapp_loader.h index e2c83bf..c830178 100644 --- a/host/common/include/chre_host/preloaded_nanoapp_loader.h +++ b/host/common/include/chre_host/preloaded_nanoapp_loader.h
@@ -101,6 +101,13 @@ size_t fragmentId; }; + /** The possible results of verification of a fragment load response. */ + enum class ResponseVerificationResult { + SUCCESS = 0, + FAILURE = 1, + IGNORED = 2, + }; + /** * Loads a preloaded nanoapp. * @@ -130,10 +137,11 @@ const FragmentedLoadRequest &request); /** Verifies the response of a loading request. */ - [[nodiscard]] bool verifyFragmentLoadResponse( + [[nodiscard]] ResponseVerificationResult verifyFragmentLoadResponse( const ::chre::fbs::LoadNanoappResponseT &response) const; - Transaction mPreloadedNanoappPendingTransaction{0, 0}; + Transaction mPendingTransaction{/* transactionId= */ 0, + /* fragmentId= */ 0}; /** The value of this promise carries the result in the load response. */ std::optional<std::promise<bool>> mFragmentedLoadPromise = std::nullopt;
diff --git a/host/common/include/chre_host/wifi_ext_hal_handler.h b/host/common/include/chre_host/wifi_ext_hal_handler.h index d83a625..ee0f6e9 100644 --- a/host/common/include/chre_host/wifi_ext_hal_handler.h +++ b/host/common/include/chre_host/wifi_ext_hal_handler.h
@@ -28,7 +28,6 @@ #include <string> #include <thread> -#include <aidl/android/hardware/wifi/WifiStatusCode.h> #include <aidl/vendor/google/wifi_ext/BnWifiExtChreCallback.h> #include <aidl/vendor/google/wifi_ext/IWifiExt.h> #include <android/binder_manager.h> @@ -44,7 +43,6 @@ */ class WifiExtHalHandler { public: - using WifiStatusCode = aidl::android::hardware::wifi::WifiStatusCode; using IWifiExt = aidl::vendor::google::wifi_ext::IWifiExt; using BnWifiExtChreNanCallback = aidl::vendor::google::wifi_ext::BnWifiExtChreCallback;
diff --git a/host/common/log_message_parser.cc b/host/common/log_message_parser.cc index 2499123..8477157 100644 --- a/host/common/log_message_parser.cc +++ b/host/common/log_message_parser.cc
@@ -268,7 +268,7 @@ size_t bufferIndex = 0; const LogMessageV2 *message = nullptr; size_t maxLogMessageLen = 0; - while (bufferIndex + kLogHeaderSize <= logBufferSize) { + while (bufferIndex + kLogHeaderSize < logBufferSize) { message = reinterpret_cast<const LogMessageV2 *>(&logBuffer[bufferIndex]); maxLogMessageLen = (logBufferSize - bufferIndex) - kLogHeaderSize; logMessageSize = std::nullopt;
diff --git a/host/common/preloaded_nanoapp_loader.cc b/host/common/preloaded_nanoapp_loader.cc index 7d198a5..5e5d89f 100644 --- a/host/common/preloaded_nanoapp_loader.cc +++ b/host/common/preloaded_nanoapp_loader.cc
@@ -197,21 +197,35 @@ return success; } -bool PreloadedNanoappLoader::verifyFragmentLoadResponse( +PreloadedNanoappLoader::ResponseVerificationResult +PreloadedNanoappLoader::verifyFragmentLoadResponse( const ::chre::fbs::LoadNanoappResponseT &response) const { - if (!response.success) { - LOGE("Loading nanoapp binary fragment %d of transaction %u failed.", - response.fragment_id, response.transaction_id); - return false; + // Allow seen fragment ids to be ignored to tolerate duplicated responses. + if (response.fragment_id >= 0 && + response.fragment_id < mPendingTransaction.fragmentId) { + LOGW( + "Fragmented load response has a fragment id %u while %zu is expected. " + "Ignored", + response.fragment_id, mPendingTransaction.fragmentId); + return ResponseVerificationResult::IGNORED; } - if (mPreloadedNanoappPendingTransaction.fragmentId != response.fragment_id) { + + // Future or negative fragment ids are not acceptable. + if (response.fragment_id != mPendingTransaction.fragmentId) { LOGE( "Fragmented load response with unexpected fragment id %u while " "%zu is expected", - response.fragment_id, mPreloadedNanoappPendingTransaction.fragmentId); - return false; + response.fragment_id, mPendingTransaction.fragmentId); + return ResponseVerificationResult::FAILURE; } - return true; + + // Once fragment id is matched the result is taken. + if (!response.success) { + LOGE("Loading nanoapp binary fragment %d of transaction %u failed.", + response.fragment_id, response.transaction_id); + return ResponseVerificationResult::FAILURE; + } + return ResponseVerificationResult::SUCCESS; } bool PreloadedNanoappLoader::onLoadNanoappResponse( @@ -225,19 +239,23 @@ response.transaction_id, response.fragment_id); return false; } - if (mPreloadedNanoappPendingTransaction.transactionId != - response.transaction_id) { + if (mPendingTransaction.transactionId != response.transaction_id) { LOGE( "Fragmented load response with transactionId %u but transactionId " "%u is expected. Ignored.", - response.transaction_id, - mPreloadedNanoappPendingTransaction.transactionId); + response.transaction_id, mPendingTransaction.transactionId); return false; } + // set value for the future instance. - mFragmentedLoadPromise->set_value(verifyFragmentLoadResponse(response)); - // reset the promise as the value can only be retrieved once from it. - mFragmentedLoadPromise = std::nullopt; + ResponseVerificationResult result = verifyFragmentLoadResponse(response); + if (result != ResponseVerificationResult::IGNORED) { + mFragmentedLoadPromise->set_value(result == + ResponseVerificationResult::SUCCESS); + // reset the promise as the value can only be retrieved once from it. + mFragmentedLoadPromise = std::nullopt; + } + return true; } @@ -257,7 +275,7 @@ // Returns an invalid future to indicate the failure return std::future<bool>{}; } - mPreloadedNanoappPendingTransaction = { + mPendingTransaction = { .transactionId = request.transactionId, .fragmentId = request.fragmentId, };
diff --git a/host/hal_generic/Android.bp b/host/hal_generic/Android.bp index f844ec2..b9edabd 100644 --- a/host/hal_generic/Android.bp +++ b/host/hal_generic/Android.bp
@@ -31,10 +31,7 @@ defaults: ["chre_aidl_hal_generic_defaults"], vendor: true, relative_install_path: "hw", - srcs: [ - ":hal_aidl_generic_srcs", - "aidl/service.cc", - ], + srcs: ["aidl/service.cc"], init_rc: ["aidl/android.hardware.contexthub-service.generic.rc"], vintf_fragments: ["aidl/android.hardware.contexthub-service.generic.xml"], visibility: ["//visibility:public"], @@ -51,42 +48,22 @@ cc_defaults { name: "chre_aidl_hal_generic_defaults", + defaults: [ + "//system/chre:contexthub_hal_defaults", + "//system/chre:pw_rpc_cflags_chre", + "//system/chre:pw_rpc_nanopb_lib_dependencies", + ], vendor: true, - include_dirs: [ - "system/chre/host/hal_generic/common/", - "system/chre/util/include", + srcs: [ + "//system/chre/host/hal_generic:hal_aidl_generic_srcs", + "//system/chre:contexthub_hal_client_srcs", ], cflags: [ "-DCHRE_HAL_SOCKET_METRICS_ENABLED", - "-DCHRE_IS_HOST_BUILD", - "-DCHRE_MESSAGE_TO_HOST_MAX_SIZE=4000", // Needed to import CHRE APIs. - "-Wall", - "-Werror", - ], - header_libs: [ - "chre_api", - ], - shared_libs: [ - "android.frameworks.stats-V2-ndk", - "android.hardware.contexthub-V3-ndk", - "chre_atoms_log", - "chremetrics-cpp", - "libbase", - "libbinder_ndk", - "libcutils", - "libjsoncpp", - "liblog", - "libprotobuf-cpp-lite", - "libutils", - "server_configurable_flags", - "libaconfig_storage_read_api_cc", + "-Wthread-safety", // Need to be explicitly set ], static_libs: [ - "chre_client", "chre_config_util", - "chre_flags_c_lib", - "chre_metrics_reporter", - "event_logger", ], }
diff --git a/host/hal_generic/aidl/android.hardware.contexthub-service.generic.xml b/host/hal_generic/aidl/android.hardware.contexthub-service.generic.xml index 2f8ddc8..359bb0a 100644 --- a/host/hal_generic/aidl/android.hardware.contexthub-service.generic.xml +++ b/host/hal_generic/aidl/android.hardware.contexthub-service.generic.xml
@@ -1,7 +1,7 @@ <manifest version="1.0" type="device"> <hal format="aidl"> <name>android.hardware.contexthub</name> - <version>3</version> + <version>4</version> <interface> <name>IContextHub</name> <instance>default</instance>
diff --git a/host/hal_generic/aidl/generic_context_hub_aidl.cc b/host/hal_generic/aidl/generic_context_hub_aidl.cc index de13bc0..e72e3ed 100644 --- a/host/hal_generic/aidl/generic_context_hub_aidl.cc +++ b/host/hal_generic/aidl/generic_context_hub_aidl.cc
@@ -351,6 +351,73 @@ return ndk::ScopedAStatus::ok(); } +ScopedAStatus ContextHub::getHubs(std::vector<HubInfo> *hubs) { + if (mV4Impl) return mV4Impl->getHubs(hubs); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus ContextHub::getEndpoints(std::vector<EndpointInfo> *endpoints) { + if (mV4Impl) return mV4Impl->getEndpoints(endpoints); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus ContextHub::registerEndpoint(const EndpointInfo &endpoint) { + if (mV4Impl) return mV4Impl->registerEndpoint(endpoint); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus ContextHub::unregisterEndpoint(const EndpointInfo &endpoint) { + if (mV4Impl) return mV4Impl->unregisterEndpoint(endpoint); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus ContextHub::registerEndpointCallback( + const std::shared_ptr<IEndpointCallback> &callback) { + if (mV4Impl) return mV4Impl->registerEndpointCallback(callback); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus ContextHub::requestSessionIdRange(int32_t size, + std::vector<int32_t> *ids) { + if (mV4Impl) return mV4Impl->requestSessionIdRange(size, ids); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus ContextHub::openEndpointSession( + int32_t sessionId, const EndpointId &destination, + const EndpointId &initiator, + const std::optional<std::string> &serviceDescriptor) { + if (mV4Impl) { + return mV4Impl->openEndpointSession(sessionId, destination, initiator, + serviceDescriptor); + } + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus ContextHub::sendMessageToEndpoint(int32_t sessionId, + const Message &msg) { + if (mV4Impl) return mV4Impl->sendMessageToEndpoint(sessionId, msg); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus ContextHub::sendMessageDeliveryStatusToEndpoint( + int32_t sessionId, const MessageDeliveryStatus &msgStatus) { + if (mV4Impl) + return mV4Impl->sendMessageDeliveryStatusToEndpoint(sessionId, msgStatus); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus ContextHub::closeEndpointSession(int32_t sessionId, + Reason reason) { + if (mV4Impl) return mV4Impl->closeEndpointSession(sessionId, reason); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus ContextHub::endpointSessionOpenComplete(int32_t sessionId) { + if (mV4Impl) return mV4Impl->endpointSessionOpenComplete(sessionId); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + void ContextHub::onNanoappMessage(const ::chre::fbs::NanoappMessageT &message) { std::lock_guard<std::mutex> lock(mCallbackMutex); if (mCallback != nullptr) { @@ -461,6 +528,12 @@ debugDumpComplete(); } +bool ContextHub::onContextHubV4Message( + const ::chre::fbs::ChreMessageUnion &message) { + if (mV4Impl) return mV4Impl->handleMessageFromChre(message); + return false; +} + void ContextHub::handleServiceDeath() { LOGI("Context Hub Service died ..."); {
diff --git a/host/hal_generic/aidl/generic_context_hub_aidl.h b/host/hal_generic/aidl/generic_context_hub_aidl.h index 024cb1e..7dd85b0 100644 --- a/host/hal_generic/aidl/generic_context_hub_aidl.h +++ b/host/hal_generic/aidl/generic_context_hub_aidl.h
@@ -18,8 +18,10 @@ #define ANDROID_HARDWARE_CONTEXTHUB_AIDL_CONTEXTHUB_H #include <aidl/android/hardware/contexthub/BnContextHub.h> +#include <android_chre_flags.h> #include <log/log.h> #include <atomic> +#include <functional> #include <future> #include <map> #include <mutex> @@ -27,6 +29,7 @@ #include <unordered_set> #include "chre_host/napp_header.h" +#include "context_hub_v4_impl.h" #include "debug_dump_helper.h" #include "event_logger.h" #include "hal_chre_socket_connection.h" @@ -56,7 +59,13 @@ public: ContextHub() : mDeathRecipient( - AIBinder_DeathRecipient_new(ContextHub::onServiceDied)) {} + AIBinder_DeathRecipient_new(ContextHub::onServiceDied)) { + if (::android::chre::flags::offload_implementation()) { + mV4Impl.emplace([this](uint8_t *data, size_t size) { + return mConnection.sendRawMessage(data, size); + }); + } + } ::ndk::ScopedAStatus getContextHubs( std::vector<ContextHubInfo> *out_contextHubInfos) override; ::ndk::ScopedAStatus loadNanoapp(int32_t contextHubId, @@ -88,6 +97,27 @@ char16_t in_hostEndpointId) override; ::ndk::ScopedAStatus onNanSessionStateChanged( const NanSessionStateUpdate &in_update) override; + ::ndk::ScopedAStatus getHubs(std::vector<HubInfo> *hubs) override; + ::ndk::ScopedAStatus getEndpoints( + std::vector<EndpointInfo> *endpoints) override; + ::ndk::ScopedAStatus registerEndpoint(const EndpointInfo &endpoint) override; + ::ndk::ScopedAStatus unregisterEndpoint( + const EndpointInfo &endpoint) override; + ::ndk::ScopedAStatus registerEndpointCallback( + const std::shared_ptr<IEndpointCallback> &callback) override; + ::ndk::ScopedAStatus requestSessionIdRange( + int32_t size, std::vector<int32_t> *ids) override; + ::ndk::ScopedAStatus openEndpointSession( + int32_t sessionId, const EndpointId &destination, + const EndpointId &initiator, + const std::optional<std::string> &serviceDescriptor) override; + ::ndk::ScopedAStatus sendMessageToEndpoint(int32_t sessionId, + const Message &msg) override; + ::ndk::ScopedAStatus sendMessageDeliveryStatusToEndpoint( + int32_t sessionId, const MessageDeliveryStatus &msgStatus) override; + ::ndk::ScopedAStatus closeEndpointSession(int32_t sessionId, + Reason reason) override; + ::ndk::ScopedAStatus endpointSessionOpenComplete(int32_t sessionId) override; void onNanoappMessage(const ::chre::fbs::NanoappMessageT &message) override; @@ -103,6 +133,9 @@ void onDebugDumpComplete( const ::chre::fbs::DebugDumpResponseT &response) override; + bool onContextHubV4Message( + const ::chre::fbs::ChreMessageUnion &message) override; + void handleServiceDeath(); static void onServiceDied(void *cookie); @@ -238,6 +271,11 @@ ndk::ScopedAIBinder_DeathRecipient mDeathRecipient; + // Implementation of the V4 API. + std::optional< + ::android::hardware::contexthub::common::implementation::ContextHubV4Impl> + mV4Impl{}; + std::map<Setting, bool> mSettingEnabled; std::optional<bool> mIsWifiAvailable; std::optional<bool> mIsBleAvailable;
diff --git a/host/hal_generic/common/chre_connection_callback.h b/host/hal_generic/common/chre_connection_callback.h index e751db6..b318836 100644 --- a/host/hal_generic/common/chre_connection_callback.h +++ b/host/hal_generic/common/chre_connection_callback.h
@@ -32,7 +32,10 @@ /** This method should be called when CHRE is reconnected to HAL and ready to * accept new messages. */ - virtual void onChreRestarted(){}; + virtual void onChreRestarted() {}; + + /** This method should be called when CHRE is disconnected from HAL. */ + virtual void onChreDisconnected() {}; }; } // namespace android::hardware::contexthub::common::implementation #endif // ANDROID_HARDWARE_CONTEXTHUB_COMMON_CHRE_CONNECTION_CALLBACK_H_ \ No newline at end of file
diff --git a/host/hal_generic/common/context_hub_v4_impl.cc b/host/hal_generic/common/context_hub_v4_impl.cc new file mode 100644 index 0000000..91fdde6 --- /dev/null +++ b/host/hal_generic/common/context_hub_v4_impl.cc
@@ -0,0 +1,444 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "context_hub_v4_impl.h" + +#include <assert.h> +#include <inttypes.h> + +#include <functional> +#include <optional> +#include <string> +#include <vector> + +#include <aidl/android/hardware/contexthub/BnContextHub.h> +#include <chre_host/generated/host_messages_generated.h> +#include <chre_host/log.h> + +namespace android::hardware::contexthub::common::implementation { + +using ::aidl::android::hardware::contexthub::BnContextHub; +using ::chre::fbs::ChreMessage; +using HostHub = MessageHubManager::HostHub; + +void ContextHubV4Impl::init() { + // TODO(b/378545373): Send message to get hubs/endpoints state dump to + // initialize mManager. +} + +namespace { + +ScopedAStatus fromPwStatus(pw::Status status) { + switch (status.code()) { + case PW_STATUS_OK: + return ScopedAStatus::ok(); + case PW_STATUS_NOT_FOUND: + [[fallthrough]]; + case PW_STATUS_ALREADY_EXISTS: + [[fallthrough]]; + case PW_STATUS_OUT_OF_RANGE: + [[fallthrough]]; + case PW_STATUS_PERMISSION_DENIED: + [[fallthrough]]; + case PW_STATUS_INVALID_ARGUMENT: + return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + case PW_STATUS_UNIMPLEMENTED: + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + default: + return ScopedAStatus::fromServiceSpecificError( + BnContextHub::EX_CONTEXT_HUB_UNSPECIFIED); + } +} + +} // namespace + +ScopedAStatus ContextHubV4Impl::getHubs(std::vector<HubInfo> *hubs) { + *hubs = mManager.getEmbeddedHubs(); + return ScopedAStatus::ok(); +} + +ScopedAStatus ContextHubV4Impl::getEndpoints( + std::vector<EndpointInfo> *endpoints) { + *endpoints = mManager.getEmbeddedEndpoints(); + return ScopedAStatus::ok(); +} + +ScopedAStatus ContextHubV4Impl::registerEndpoint(const EndpointInfo &endpoint) { + std::shared_ptr<HostHub> hub = + mManager.getHostHubByPid(AIBinder_getCallingPid()); + assert(hub != nullptr); + if (auto status = hub->addEndpoint(hub, endpoint); !status.ok()) { + LOGE("Failed to register endpoint %" PRId64 " on hub %" PRId64 + " with %" PRId32, + endpoint.id.id, hub->id(), status.code()); + return fromPwStatus(status); + } + // TODO(b/378545373): Send the endpoint info to CHRE. + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus ContextHubV4Impl::unregisterEndpoint( + const EndpointInfo &endpoint) { + std::shared_ptr<HostHub> hub = + mManager.getHostHubByPid(AIBinder_getCallingPid()); + assert(hub != nullptr); + if (auto status = hub->removeEndpoint(endpoint.id); !status.ok()) { + LOGE("Failed to unregister endpoint %" PRId32 " on hub %" PRId32 + " with %" PRId32, + endpoint.id.id, hub->id(), status.code()); + return fromPwStatus(status); + } + // TODO(b/378545373): Send the endpoint info to CHRE. + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus ContextHubV4Impl::registerEndpointCallback( + const std::shared_ptr<IEndpointCallback> &callback) { + std::shared_ptr<HostHub> hub = + mManager.getHostHubByPid(AIBinder_getCallingPid()); + assert(hub != nullptr); + return fromPwStatus(hub->setCallback(callback)); +} + +ScopedAStatus ContextHubV4Impl::requestSessionIdRange( + int32_t size, std::vector<int32_t> *ids) { + std::shared_ptr<HostHub> hub = + mManager.getHostHubByPid(AIBinder_getCallingPid()); + assert(hub != nullptr); + auto statusOrRange = hub->reserveSessionIdRange(size); + if (!statusOrRange.ok()) { + LOGE("Failed to reserve %" PRId32 " session ids on hub %" PRId64 + " with %" PRId32, + size, hub->id(), statusOrRange.status().code()); + return fromPwStatus(statusOrRange.status()); + } + ids->resize(2); + (*ids)[0] = statusOrRange->first; + (*ids)[1] = statusOrRange->second; + return ScopedAStatus::ok(); +} + +ScopedAStatus ContextHubV4Impl::openEndpointSession( + int32_t sessionId, const EndpointId &destination, + const EndpointId &initiator, + const std::optional<std::string> & /*serviceDescriptor*/) { + std::shared_ptr<HostHub> hub = + mManager.getHostHubByPid(AIBinder_getCallingPid()); + assert(hub != nullptr); + pw::Result<std::shared_ptr<HostHub>> statusOrPruneHub = + hub->openSession(hub, initiator, destination, sessionId); + if (!statusOrPruneHub.ok()) { + LOGE("Failed to open session %" PRId32 " from (%" PRId64 ", %" PRId64 + ") to (%" PRId64 ", %" PRId64 ") with %" PRId32, + sessionId, initiator.hubId, initiator.id, destination.hubId, + destination.id, statusOrPruneHub.status().code()); + return fromPwStatus(statusOrPruneHub.status()); + } else if (*statusOrPruneHub) { + // Send a closed session notification on the hub that hosted the pruned + // session. + auto status = (*statusOrPruneHub)->closeSession(sessionId); + LOGD("Pruning session %" PRIu16 " with status %" PRId32, sessionId, + status.code()); + } + // TODO(b/378545373): Send the session open request to CHRE. + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus ContextHubV4Impl::sendMessageToEndpoint(int32_t sessionId, + const Message & /*msg*/) { + std::shared_ptr<HostHub> hub = + mManager.getHostHubByPid(AIBinder_getCallingPid()); + assert(hub != nullptr); + if (auto status = hub->checkSessionOpen(sessionId); !status.ok()) { + if (status.IsUnavailable()) { + hub->getCallback()->onCloseEndpointSession(sessionId, + Reason::ENDPOINT_GONE); + } else { + LOGE("Failed to verify session %" PRId32 " on hub %" PRId64 + " with %" PRId32, + sessionId, hub->id(), status.code()); + } + return fromPwStatus(status); + } + // TODO(b/378545373): Handle reliable messages. + // TODO(b/378545373): Send the message to CHRE. + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus ContextHubV4Impl::sendMessageDeliveryStatusToEndpoint( + int32_t sessionId, const MessageDeliveryStatus & /*msgStatus*/) { + std::shared_ptr<HostHub> hub = + mManager.getHostHubByPid(AIBinder_getCallingPid()); + assert(hub != nullptr); + if (auto status = hub->checkSessionOpen(sessionId); !status.ok()) { + if (status.IsUnavailable()) { + hub->getCallback()->onCloseEndpointSession(sessionId, + Reason::ENDPOINT_GONE); + } else { + LOGE("Failed to verify session %" PRId32 " on hub %" PRId64 + " with %" PRId32, + sessionId, hub->id(), status.code()); + } + return fromPwStatus(status); + } + // TODO(b/378545373): Send the message to CHRE. + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus ContextHubV4Impl::closeEndpointSession(int32_t sessionId, + Reason /*reason*/) { + std::shared_ptr<HostHub> hub = + mManager.getHostHubByPid(AIBinder_getCallingPid()); + assert(hub != nullptr); + if (auto status = hub->closeSession(sessionId); !status.ok()) { + LOGE("Failed to close session %" PRId32 " on hub %" PRId64 " with %" PRId32, + sessionId, hub->id(), status.code()); + return fromPwStatus(status); + } + hub->getCallback()->onCloseEndpointSession( + sessionId, Reason::CLOSE_ENDPOINT_SESSION_REQUESTED); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus ContextHubV4Impl::endpointSessionOpenComplete(int32_t sessionId) { + std::shared_ptr<HostHub> hub = + mManager.getHostHubByPid(AIBinder_getCallingPid()); + assert(hub != nullptr); + if (auto status = hub->ackSession(sessionId); !status.ok()) { + if (status.IsUnavailable()) { + hub->getCallback()->onCloseEndpointSession(sessionId, + Reason::ENDPOINT_GONE); + } else { + LOGE("Failed to verify session %" PRId32 " on hub %" PRId64 + " with %" PRId32, + sessionId, hub->id(), status.code()); + } + return fromPwStatus(status); + } + // TODO(b/378545373): Send the session id to CHRE. + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +bool ContextHubV4Impl::handleMessageFromChre( + const ::chre::fbs::ChreMessageUnion &message) { + switch (message.type) { + case ChreMessage::GetMessageHubsAndEndpointsResponse: + onGetMessageHubsAndEndpointsResponse( + *message.AsGetMessageHubsAndEndpointsResponse()); + break; + case ChreMessage::RegisterMessageHub: + onRegisterMessageHub(*message.AsRegisterMessageHub()); + break; + case ChreMessage::UnregisterMessageHub: + onUnregisterMessageHub(*message.AsUnregisterMessageHub()); + break; + case ChreMessage::RegisterEndpoint: + onRegisterEndpoint(*message.AsRegisterEndpoint()); + break; + case ChreMessage::OpenEndpointSessionRequest: + onOpenEndpointSessionRequest(*message.AsOpenEndpointSessionRequest()); + break; + case ChreMessage::EndpointSessionOpened: + onEndpointSessionOpened(*message.AsEndpointSessionOpened()); + break; + case ChreMessage::EndpointSessionClosed: + onEndpointSessionClosed(*message.AsEndpointSessionClosed()); + break; + case ChreMessage::EndpointSessionMessage: + onEndpointSessionMessage(*message.AsEndpointSessionMessage()); + break; + case ChreMessage::EndpointSessionMessageDeliveryStatus: + onEndpointSessionMessageDeliveryStatus( + *message.AsEndpointSessionMessageDeliveryStatus()); + break; + default: + LOGW("Got unexpected message type %" PRIu8, + static_cast<uint8_t>(message.type)); + return false; + } + return true; +} + +void ContextHubV4Impl::onGetMessageHubsAndEndpointsResponse( + const ::chre::fbs::GetMessageHubsAndEndpointsResponseT & /*msg*/) { + // TODO(b/378545373): Parse flatbuffer message + std::vector<HubInfo> hubs; + std::vector<EndpointInfo> endpoints; + LOGI("Initializing embedded message hub cache"); + mManager.initEmbeddedHubsAndEndpoints(hubs, endpoints); +} + +void ContextHubV4Impl::onRegisterMessageHub( + const ::chre::fbs::RegisterMessageHubT & /*msg*/) { + // TODO(b/378545373): Parse flatbuffer message + HubInfo hub; + LOGI("Embedded message hub %" PRId64 " registered", hub.hubId); + mManager.addEmbeddedHub(hub); +} + +void ContextHubV4Impl::onUnregisterMessageHub( + const ::chre::fbs::UnregisterMessageHubT & /*msg*/) { + // TODO(b/378545373): Parse flatbuffer message + int64_t id = 0; + LOGI("Embedded message hub %" PRId64 " unregistered", id); + std::vector<EndpointId> endpoints = mManager.removeEmbeddedHub(id); + if (!endpoints.empty()) { + mManager.forEachHostHub([&endpoints](HostHub &hub) { + hub.getCallback()->onEndpointStopped(endpoints, Reason::HUB_RESET); + }); + } +} + +void ContextHubV4Impl::onRegisterEndpoint( + const ::chre::fbs::RegisterEndpointT & /*msg*/) { + // TODO(b/378545373): Parse flatbuffer message + EndpointInfo endpoint; + LOGI("Adding embedded endpoint (%" PRId64 ", %" PRId64 ")", endpoint.id.hubId, + endpoint.id.id); + mManager.addEmbeddedEndpoint(endpoint); + mManager.forEachHostHub([&endpoint](HostHub &hub) { + hub.getCallback()->onEndpointStarted({endpoint}); + }); +} + +void ContextHubV4Impl::onUnregisterEndpoint( + const ::chre::fbs::UnregisterEndpointT & /*msg*/) { + // TODO(b/378545373): Parse flatbuffer message + EndpointId endpoint; + LOGI("Removing embedded endpoint (%" PRId64 ", %" PRId64 ")", endpoint.hubId, + endpoint.id); + mManager.removeEmbeddedEndpoint(endpoint); + mManager.forEachHostHub([&endpoint](HostHub &hub) { + hub.getCallback()->onEndpointStopped({endpoint}, Reason::ENDPOINT_GONE); + }); +} + +void ContextHubV4Impl::onOpenEndpointSessionRequest( + const ::chre::fbs::OpenEndpointSessionRequestT & /*msg*/) { + // TODO(b/378545373): Parse flatbuffer message + std::optional<std::string> serviceDescriptor; + EndpointId local, remote; + uint16_t sessionId = 0; + LOGD("New session (%" PRIu16 ") request from (%" PRId64 ", %" PRId64 + ") to " + "(%" PRId64 ", %" PRId64 ")", + sessionId, remote.hubId, remote.id, local.hubId, local.id); + + // Look up the host hub based on the host endpoint. + std::shared_ptr<HostHub> hub = mManager.getHostHubByEndpointId(local); + if (!hub) { + LOGW("Unable to find host hub"); + return; + } + + // Record the open session request and pass it on to the appropriate client. + auto statusOrPruneHub = hub->openSession(hub, local, remote, sessionId); + if (!statusOrPruneHub.ok()) { + LOGE("Failed to request session %" PRIu16 " with %" PRId32, sessionId, + statusOrPruneHub.status().code()); + return; + } else if (*statusOrPruneHub) { + // Send a closed session notification on the hub that hosted the pruned + // session. + auto status = (*statusOrPruneHub)->closeSession(sessionId); + LOGD("Pruning session %" PRIu16 " with status %" PRId32, sessionId, + status.code()); + } + hub->getCallback()->onEndpointSessionOpenRequest( + sessionId, local, remote, std::move(serviceDescriptor)); +} + +namespace { + +void logGetHubFailure(pw::Status status, int32_t sessionId) { + if (status.IsUnavailable()) { + LOGD("Session %" PRId32 " was pruned.", sessionId); + } else { + LOGE("Failed to operate on session %" PRId32 " with %" PRId32, sessionId, + status.code()); + } +} + +} // namespace + +void ContextHubV4Impl::onEndpointSessionOpened( + const ::chre::fbs::EndpointSessionOpenedT & /*msg*/) { + // TODO(b/378545373): Parse flatbuffer message + int32_t id = 0; + LOGD("New session ack for id %" PRId32, id); + auto statusOrHub = mManager.ackSessionAndGetHostHub(id); + if (!statusOrHub.ok()) { + logGetHubFailure(statusOrHub.status(), id); + // TODO(b/378545373): Send a notification back to CHRE. + return; + } + + // Only send a session open complete message to the host hub client if it was + // the initiator. + if (static_cast<uint16_t>(id) >= MessageHubManager::kHostSessionIdBase) + (*statusOrHub)->getCallback()->onEndpointSessionOpenComplete(id); +} + +void ContextHubV4Impl::onEndpointSessionClosed( + const ::chre::fbs::EndpointSessionClosedT & /*msg*/) { + // TODO(b/378545373): Parse flatbuffer message + int32_t id = 0; + Reason reason = Reason::UNSPECIFIED; + LOGD("Closing session id %" PRId32 " for %" PRIu8, id, reason); + auto statusOrHub = mManager.checkSessionOpenAndGetHostHub(id); + if (!statusOrHub.ok()) { + logGetHubFailure(statusOrHub.status(), id); + return; + } + (*statusOrHub)->getCallback()->onCloseEndpointSession(id, reason); +} + +void ContextHubV4Impl::onEndpointSessionMessage( + const ::chre::fbs::EndpointSessionMessageT & /*msg*/) { + // TODO(b/378545373): Parse flatbuffer message + Message message; + int32_t sessionId = 0; + auto statusOrHub = mManager.checkSessionOpenAndGetHostHub(sessionId); + if (!statusOrHub.ok()) { + logGetHubFailure(statusOrHub.status(), sessionId); + // TODO(b/378545373): Send a notification back to CHRE. + return; + } + (*statusOrHub)->getCallback()->onMessageReceived(sessionId, message); +} + +void ContextHubV4Impl::onEndpointSessionMessageDeliveryStatus( + const ::chre::fbs::EndpointSessionMessageDeliveryStatusT & /*msg*/) { + // TODO(b/378545373): Parse flatbuffer message + MessageDeliveryStatus status; + int32_t sessionId = 0; + auto statusOrHub = mManager.checkSessionOpenAndGetHostHub(sessionId); + if (!statusOrHub.ok()) { + logGetHubFailure(statusOrHub.status(), sessionId); + // TODO(b/378545373): Send a notification back to CHRE. + return; + } + // TODO(b/378545373): Handle reliable messages. + (*statusOrHub) + ->getCallback() + ->onMessageDeliveryStatusReceived(sessionId, status); +} + +void ContextHubV4Impl::onHostHubDown(int64_t /*id*/) { + // TODO(b/378545373): Send an UnregisterMessageHub message to CHRE with id. +} + +} // namespace android::hardware::contexthub::common::implementation
diff --git a/host/hal_generic/common/context_hub_v4_impl.h b/host/hal_generic/common/context_hub_v4_impl.h new file mode 100644 index 0000000..b07dc34 --- /dev/null +++ b/host/hal_generic/common/context_hub_v4_impl.h
@@ -0,0 +1,107 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <functional> +#include <optional> +#include <string> +#include <vector> + +#include <aidl/android/hardware/contexthub/BnContextHub.h> +#include <chre_host/generated/host_messages_generated.h> + +#include "message_hub_manager.h" + +namespace android::hardware::contexthub::common::implementation { + +using ::aidl::android::hardware::contexthub::EndpointId; +using ::aidl::android::hardware::contexthub::EndpointInfo; +using ::aidl::android::hardware::contexthub::HubInfo; +using ::aidl::android::hardware::contexthub::IEndpointCallback; +using ::aidl::android::hardware::contexthub::Message; +using ::aidl::android::hardware::contexthub::MessageDeliveryStatus; +using ::aidl::android::hardware::contexthub::Reason; +using ::ndk::ScopedAStatus; + +class ContextHubV4Impl { + public: + using SendMessageFn = std::function<bool(uint8_t *data, size_t size)>; + + explicit ContextHubV4Impl(SendMessageFn sendMessageFn) + : mManager([this](int64_t id) { onHostHubDown(id); }), + mSendMessageFn(std::move(sendMessageFn)) {} + ~ContextHubV4Impl() = default; + + /** + * Initializes the implementation. + * + * This should be called once a connection with CHRE has been established. + * Requests a dump of embedded hubs and endpoints from CHRE. + */ + void init(); + + // ContextHub V4 API implementation. + ScopedAStatus getHubs(std::vector<HubInfo> *hubs); + ScopedAStatus getEndpoints(std::vector<EndpointInfo> *endpoints); + ScopedAStatus registerEndpoint(const EndpointInfo &endpoint); + ScopedAStatus unregisterEndpoint(const EndpointInfo &endpoint); + ScopedAStatus registerEndpointCallback( + const std::shared_ptr<IEndpointCallback> &callback); + ScopedAStatus requestSessionIdRange(int32_t size, std::vector<int32_t> *ids); + ScopedAStatus openEndpointSession( + int32_t sessionId, const EndpointId &destination, + const EndpointId &initiator, + const std::optional<std::string> &serviceDescriptor); + ScopedAStatus sendMessageToEndpoint(int32_t sessionId, const Message &msg); + ScopedAStatus sendMessageDeliveryStatusToEndpoint( + int32_t sessionId, const MessageDeliveryStatus &msgStatus); + ScopedAStatus closeEndpointSession(int32_t sessionId, Reason reason); + ScopedAStatus endpointSessionOpenComplete(int32_t sessionId); + + /** + * Handles a CHRE message that is part of the V4 implementation. + * + * @param message Validated union of the various message types. + * @return true if the message could be handled + */ + bool handleMessageFromChre(const ::chre::fbs::ChreMessageUnion &message); + + private: + // Callbacks for each message type from CHRE. + void onGetMessageHubsAndEndpointsResponse( + const ::chre::fbs::GetMessageHubsAndEndpointsResponseT &msg); + void onRegisterMessageHub(const ::chre::fbs::RegisterMessageHubT &msg); + void onUnregisterMessageHub(const ::chre::fbs::UnregisterMessageHubT &msg); + void onRegisterEndpoint(const ::chre::fbs::RegisterEndpointT &msg); + void onUnregisterEndpoint(const ::chre::fbs::UnregisterEndpointT &msg); + void onOpenEndpointSessionRequest( + const ::chre::fbs::OpenEndpointSessionRequestT &msg); + void onEndpointSessionOpened(const ::chre::fbs::EndpointSessionOpenedT &msg); + void onEndpointSessionClosed(const ::chre::fbs::EndpointSessionClosedT &msg); + void onEndpointSessionMessage( + const ::chre::fbs::EndpointSessionMessageT &msg); + void onEndpointSessionMessageDeliveryStatus( + const ::chre::fbs::EndpointSessionMessageDeliveryStatusT &msg); + + // Callback invoked when a HAL client associated with a host hub goes down. + void onHostHubDown(int64_t id); + + MessageHubManager mManager; + SendMessageFn mSendMessageFn; +}; + +} // namespace android::hardware::contexthub::common::implementation
diff --git a/host/hal_generic/common/generic_context_hub_base.h b/host/hal_generic/common/generic_context_hub_base.h index 64b4a24..b7513d5 100644 --- a/host/hal_generic/common/generic_context_hub_base.h +++ b/host/hal_generic/common/generic_context_hub_base.h
@@ -350,6 +350,11 @@ debugDumpComplete(); } + bool onContextHubV4Message( + const ::chre::fbs::ChreMessageUnion & /* message */) override { + return false; + } + // Write a string to the debug file. void writeToDebugFile(const char *str) override { if (checkDebugFd()) {
diff --git a/host/hal_generic/common/hal_chre_socket_connection.cc b/host/hal_generic/common/hal_chre_socket_connection.cc index 4d6b7b7..1c72bde 100644 --- a/host/hal_generic/common/hal_chre_socket_connection.cc +++ b/host/hal_generic/common/hal_chre_socket_connection.cc
@@ -146,6 +146,10 @@ return mClient.sendMessage(builder.GetBufferPointer(), builder.GetSize()); } +bool HalChreSocketConnection::sendRawMessage(uint8_t *data, size_t size) { + return mClient.sendMessage(data, size); +} + bool HalChreSocketConnection::sendSettingChangedNotification( ::chre::fbs::Setting fbsSetting, ::chre::fbs::SettingState fbsState) { FlatBufferBuilder builder(64); @@ -312,6 +316,11 @@ mCallback->onDebugDumpComplete(response); } +bool HalChreSocketConnection::SocketCallbacks::handleContextHubV4Message( + const ::chre::fbs::ChreMessageUnion &message) { + return mCallback->onContextHubV4Message(message); +} + bool HalChreSocketConnection::isExpectedLoadResponseLocked( const ::chre::fbs::LoadNanoappResponseT &response) { return mPendingLoadTransaction.has_value() &&
diff --git a/host/hal_generic/common/hal_chre_socket_connection.h b/host/hal_generic/common/hal_chre_socket_connection.h index 5a3be43..a62ced8 100644 --- a/host/hal_generic/common/hal_chre_socket_connection.h +++ b/host/hal_generic/common/hal_chre_socket_connection.h
@@ -89,6 +89,15 @@ */ virtual void onDebugDumpComplete( const ::chre::fbs::DebugDumpResponseT &response) = 0; + + /** + * Handles a ContextHub V4+ message or returns false. + * + * @param message The union of possible messages. + * @return true on successful handling + */ + virtual bool onContextHubV4Message( + const ::chre::fbs::ChreMessageUnion &message) = 0; }; /** @@ -117,6 +126,8 @@ bool sendSettingChangedNotification(::chre::fbs::Setting fbsSetting, ::chre::fbs::SettingState fbsState); + bool sendRawMessage(uint8_t *data, size_t size); + bool onHostEndpointConnected(uint16_t hostEndpointId, uint8_t type, const std::string &package_name, const std::string &attribution_tag); @@ -155,6 +166,8 @@ void handleDebugDumpData(const ::chre::fbs::DebugDumpDataT &data) override; void handleDebugDumpResponse( const ::chre::fbs::DebugDumpResponseT &response) override; + bool handleContextHubV4Message( + const ::chre::fbs::ChreMessageUnion &message) override; private: HalChreSocketConnection &mParent;
diff --git a/host/hal_generic/common/hal_client_manager.cc b/host/hal_generic/common/hal_client_manager.cc index ec75fdc..f300cde 100644 --- a/host/hal_generic/common/hal_client_manager.cc +++ b/host/hal_generic/common/hal_client_manager.cc
@@ -554,13 +554,20 @@ } void HalClientManager::handleChreRestart() { + const std::lock_guard<std::mutex> lock(mLock); + mPendingLoadTransaction.reset(); + mPendingUnloadTransaction.reset(); + for (Client &client : mClients) { + client.endpointIds.clear(); + } +} + +std::vector<std::shared_ptr<IContextHubCallback>> +HalClientManager::getCallbacks() { std::vector<std::shared_ptr<IContextHubCallback>> callbacks; { const std::lock_guard<std::mutex> lock(mLock); - mPendingLoadTransaction.reset(); - mPendingUnloadTransaction.reset(); for (Client &client : mClients) { - client.endpointIds.clear(); if (client.callback != nullptr) { // Create a copy of the callback and call it later without holding the // lock to avoid deadlocks. @@ -568,10 +575,7 @@ } } } - - for (const auto &callback : callbacks) { - callback->handleContextHubAsyncEvent(AsyncEventType::RESTARTED); - } + return callbacks; } void HalClientManager::updateClientIdMappingFile() {
diff --git a/host/hal_generic/common/hal_client_manager.h b/host/hal_generic/common/hal_client_manager.h index 0073da2..5dec2e3 100644 --- a/host/hal_generic/common/hal_client_manager.h +++ b/host/hal_generic/common/hal_client_manager.h
@@ -65,7 +65,7 @@ * identifies a host app that communicates with a HAL client. * * For a host endpoint connected to ContextHubService, its endpoint id is kept - *in the form below during the communication with CHRE. + * in the form below during the communication with CHRE. * * 0 1 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 @@ -182,6 +182,13 @@ std::shared_ptr<IContextHubCallback> getCallback(HalClientId clientId); /** + * Gets all the callbacks and postpone any API calls to the caller. + * + * @return all the non-null callback pointers + */ + std::vector<std::shared_ptr<IContextHubCallback>> getCallbacks(); + + /** * Registers a IContextHubCallback function mapped to the current client's * client id. @p deathRecipient and @p deathRecipientCookie are used to unlink * the previous registered callback for the same client, if any.
diff --git a/host/hal_generic/common/message_hub_manager.cc b/host/hal_generic/common/message_hub_manager.cc new file mode 100644 index 0000000..6306eca --- /dev/null +++ b/host/hal_generic/common/message_hub_manager.cc
@@ -0,0 +1,444 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "message_hub_manager.h" + +#include <unistd.h> + +#include <cstdint> +#include <functional> +#include <list> +#include <memory> +#include <optional> +#include <string> +#include <unordered_map> +#include <utility> +#include <vector> + +#include <aidl/android/hardware/contexthub/BnContextHub.h> + +#include "chre_host/log.h" +#include "pw_result/result.h" +#include "pw_status/status.h" +#include "pw_status/try.h" + +namespace android::hardware::contexthub::common::implementation { + +using HostHub = MessageHubManager::HostHub; + +HostHub::~HostHub() { + std::lock_guard lock(mManager.mLock); + unlinkCallbackIfNecessaryLocked(); +} + +pw::Status HostHub::setCallback(std::shared_ptr<IEndpointCallback> callback) { + std::lock_guard lock(mManager.mLock); + auto *cookie = new DeathRecipientCookie{&mManager, kPid}; + if (AIBinder_linkToDeath(callback->asBinder().get(), + mManager.mDeathRecipient.get(), + cookie) != STATUS_OK) { + LOGE("Failed to link callback for hub %ld (pid %d) to death recipient", kId, + kPid); + delete cookie; + return pw::Status::Internal(); + } + unlinkCallbackIfNecessaryLocked(); + mCallback = std::move(callback); + mCookie = cookie; + return pw::OkStatus(); +} + +std::shared_ptr<IEndpointCallback> HostHub::getCallback() const { + std::lock_guard lock(mManager.mLock); + return mCallback; +} + +pw::Status HostHub::addEndpoint(std::weak_ptr<HostHub> self, + const EndpointInfo &info) { + std::lock_guard lock(mManager.mLock); + PW_TRY(checkValidLocked()); + int64_t id = info.id.id; + if (auto it = mIdToEndpoint.find(id); it != mIdToEndpoint.end()) { + LOGE("Endpoint %ld already exists in hub %ld (pid %d)", id, kId, kPid); + return pw::Status::AlreadyExists(); + } + if (kId == kHubIdInvalid) { + // If this is the hub's first endpoint, store its hub id and register it + // with the manager. + if (info.id.hubId == kContextHubServiceHubId && + AIBinder_getCallingUid() != kSystemServerUid) { + LOGW( + "Non-systemserver client (pid %d) trying to register as " + "ContextHubService", + kPid); + return pw::Status::InvalidArgument(); + } + kId = info.id.hubId; + mManager.mIdToHostHub.insert({kId, self}); + } + mIdToEndpoint.insert({id, std::make_unique<EndpointInfo>(info)}); + return pw::OkStatus(); +} + +pw::Status HostHub::removeEndpoint(const EndpointId &id) { + std::lock_guard lock(mManager.mLock); + PW_TRY(checkValidLocked()); + if (auto it = mIdToEndpoint.find(id.id); it != mIdToEndpoint.end()) { + mIdToEndpoint.erase(it); + return pw::OkStatus(); + } + LOGE("Client (hub %ld, pid %d) tried to remove unknown endpoint %ld", kId, + kPid, id.id); + return pw::Status::NotFound(); +} + +pw::Result<std::pair<uint16_t, uint16_t>> HostHub::reserveSessionIdRange( + uint16_t size) { + std::lock_guard lock(mManager.mLock); + PW_TRY(checkValidLocked()); + if (!size || size > kSessionIdMaxRange) { + LOGE("Client (hub %ld, pid %d) tried to allocate %hu session ids", kId, + kPid, size); + return pw::Status::InvalidArgument(); + } + if (USHRT_MAX - mManager.mNextSessionId + 1 < size) { + LOGW("Could not allocate %hu session ids, ids exhausted", size); + return pw::Status::ResourceExhausted(); + } + mSessionIdRanges.push_back( + {mManager.mNextSessionId, mManager.mNextSessionId + size - 1}); + mManager.mNextSessionId += size; + return mSessionIdRanges.back(); +} + +pw::Result<std::shared_ptr<HostHub>> HostHub::openSession( + std::weak_ptr<HostHub> self, const EndpointId &localId, + const EndpointId &remoteId, uint16_t sessionId) { + std::lock_guard lock(mManager.mLock); + PW_TRY(checkValidLocked()); + + // Lookup the endpoints. + PW_TRY_ASSIGN(std::shared_ptr<EndpointInfo> local, + getEndpointLocked(localId)); + PW_TRY_ASSIGN(std::shared_ptr<EndpointInfo> remote, + mManager.getEmbeddedEndpointLocked(remoteId)); + + // Validate the session id. + bool hostInitiated = AIBinder_isHandlingTransaction(); + if (hostInitiated) { + if (!sessionIdInRangeLocked(sessionId)) { + LOGE("Session id %hu out of range for hub %ld", sessionId, kId); + return pw::Status::OutOfRange(); + } + } else if (sessionId >= kHostSessionIdBase) { + LOGE( + "Remote endpoint (%ld, %ld) attempting to start session with " + "invalid id %hu", + remoteId.hubId, remoteId.id, sessionId); + return pw::Status::InvalidArgument(); + } + + // Prune a stale session with this id if present. + std::shared_ptr<HostHub> prunedHostHub; + if (auto it = mManager.mIdToSession.find(sessionId); + it != mManager.mIdToSession.end()) { + SessionStrongRef session(it->second); + if (session) { + // If the session is in a valid state, prune it if it was not host + // initiated and is pending a final ack from message router. + if (!hostInitiated && !session.pendingDestination && + session.pendingMessageRouter) { + prunedHostHub = std::move(session.hub); + } else if (hostInitiated && session.local->id == localId) { + LOGE("Hub %ld trying to override its own session %hu", kId, sessionId); + return pw::Status::InvalidArgument(); + } else { + LOGE("(host? %d) trying to override session id %hu, hub %ld", + hostInitiated, sessionId, kId); + return pw::Status::AlreadyExists(); + } + } + mManager.mIdToSession.erase(it); + } + + // Create and map the new session. + mManager.mIdToSession.emplace( + std::piecewise_construct, std::forward_as_tuple(sessionId), + std::forward_as_tuple(self, local, remote, hostInitiated)); + return prunedHostHub; +} + +pw::Status HostHub::closeSession(uint16_t id) { + std::lock_guard lock(mManager.mLock); + PW_TRY(checkValidLocked()); + auto it = mManager.mIdToSession.find(id); + if (it == mManager.mIdToSession.end()) { + LOGE("Closing unopened session %hu", id); + return pw::Status::NotFound(); + } + SessionStrongRef session(it->second); + if (session && session.hub->kPid != kPid) { + LOGE("Trying to close session %hu for client %d from client %d (hub %ld)", + id, session.hub->kPid, kPid, kId); + return pw::Status::PermissionDenied(); + } + mManager.mIdToSession.erase(it); + return pw::OkStatus(); +} + +pw::Status HostHub::ackSession(uint16_t id) { + return mManager.ackSessionAndGetHostHub(id).status(); +} + +pw::Status HostHub::checkSessionOpen(uint16_t id) { + return mManager.checkSessionOpenAndGetHostHub(id).status(); +} + +int64_t HostHub::id() const { + std::lock_guard lock(mManager.mLock); + return kId; +} + +int64_t MessageHubManager::HostHub::unlinkFromManager() { + std::lock_guard lock(mManager.mLock); + // TODO(b/378545373): Release the session id range. + if (kId != kHubIdInvalid) mManager.mIdToHostHub.erase(kId); + mManager.mPidToHostHub.erase(kPid); + mUnlinked = true; + return kId; +} + +void HostHub::unlinkCallbackIfNecessaryLocked() { + if (!mCallback) return; + if (AIBinder_unlinkToDeath(mCallback->asBinder().get(), + mManager.mDeathRecipient.get(), + mCookie) != STATUS_OK) { + LOGW("Failed to unlink client (pid: %d, hub id: %ld)", kPid, kId); + } + mCallback.reset(); + mCookie = nullptr; +} + +pw::Status HostHub::checkValidLocked() { + if (!mCallback) { + ALOGW("Endpoint APIs invoked by client %d before callback registered", + kPid); + return pw::Status::FailedPrecondition(); + } else if (mUnlinked) { + ALOGW("Client %d went down mid-operation", kPid); + return pw::Status::Aborted(); + } + return pw::OkStatus(); +} + +pw::Result<std::shared_ptr<EndpointInfo>> HostHub::getEndpointLocked( + const EndpointId &id) { + if (id.hubId != kId) { + LOGE("Rejecting lookup on unowned endpoint (%ld, %ld) from hub %ld", + id.hubId, id.id, kId); + return pw::Status::InvalidArgument(); + } + if (auto it = mIdToEndpoint.find(id.id); it != mIdToEndpoint.end()) + return it->second; + return pw::Status::NotFound(); +} + +bool HostHub::sessionIdInRangeLocked(uint16_t id) { + for (auto range : mSessionIdRanges) { + if (id >= range.first && id <= range.second) return true; + } + return false; +} + +MessageHubManager::MessageHubManager(HostHubDownCb cb) + : mHostHubDownCb(std::move(cb)) { + mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient( + AIBinder_DeathRecipient_new(onClientDeath)); + AIBinder_DeathRecipient_setOnUnlinked( + mDeathRecipient.get(), /*onUnlinked= */ [](void *cookie) { + LOGI("Callback is unlinked. Releasing the death recipient cookie."); + delete static_cast<HostHub::DeathRecipientCookie *>(cookie); + }); +} + +std::shared_ptr<HostHub> MessageHubManager::getHostHubByPid(pid_t pid) { + std::lock_guard lock(mLock); + if (auto it = mPidToHostHub.find(pid); it != mPidToHostHub.end()) + return it->second; + std::shared_ptr<HostHub> hub(new HostHub(*this, pid)); + mPidToHostHub.insert({pid, hub}); + return hub; +} + +std::shared_ptr<HostHub> MessageHubManager::getHostHubByEndpointId( + const EndpointId &id) { + std::lock_guard lock(mLock); + if (auto it = mIdToHostHub.find(id.hubId); it != mIdToHostHub.end()) + return it->second.lock(); + return {}; +} + +pw::Result<std::shared_ptr<HostHub>> +MessageHubManager::checkSessionOpenAndGetHostHub(uint16_t id) { + std::lock_guard lock(mLock); + PW_TRY_ASSIGN(SessionStrongRef session, checkSessionLocked(id)); + if (AIBinder_getCallingPid() != session.hub->kPid) { + LOGE("Trying to check unowned session %hu", id); + return pw::Status::PermissionDenied(); + } + if (!session.pendingDestination && !session.pendingMessageRouter) + return std::move(session.hub); + LOGE("Session %hu is pending", id); + return pw::Status::FailedPrecondition(); +} + +pw::Result<std::shared_ptr<HostHub>> MessageHubManager::ackSessionAndGetHostHub( + uint16_t id) { + std::lock_guard lock(mLock); + PW_TRY_ASSIGN(SessionStrongRef session, checkSessionLocked(id)); + bool isBinderCall = AIBinder_isHandlingTransaction(); + bool isHostSession = id >= kHostSessionIdBase; + if (isBinderCall && AIBinder_getCallingPid() != session.hub->kPid) { + LOGE("Trying to ack unowned session %hu", id); + return pw::Status::PermissionDenied(); + } else if (session.pendingDestination) { + if (isHostSession == isBinderCall) { + LOGE("Session %hu must be acked by other side (host? %d)", id, + !isBinderCall); + return pw::Status::PermissionDenied(); + } + session.pendingDestination = false; + } else if (session.pendingMessageRouter) { + if (isBinderCall) { + LOGE("Message router must ack session %hu", id); + return pw::Status::PermissionDenied(); + } + session.pendingMessageRouter = false; + } else { + LOGE("Received unexpected ack on session %hu, host: %d", id, isBinderCall); + } + return std::move(session.hub); +} + +void MessageHubManager::forEachHostHub(std::function<void(HostHub &hub)> fn) { + std::list<std::shared_ptr<HostHub>> hubs; + { + std::lock_guard lock(mLock); + for (auto &[pid, hub] : mPidToHostHub) hubs.push_back(hub); + } + for (auto &hub : hubs) fn(*hub); +} + +pw::Result<MessageHubManager::SessionStrongRef> +MessageHubManager::checkSessionLocked(uint16_t id) { + auto sessionIt = mIdToSession.find(id); + if (sessionIt == mIdToSession.end()) { + LOGE("Did not find expected session %hu", id); + return pw::Status::NotFound(); + } + SessionStrongRef session(sessionIt->second); + if (!session) { + LOGD( + "Pruning session %hu due to one or more of host hub, host endpoint, " + "or embedded endpoint going down.", + id); + mIdToSession.erase(sessionIt); + return pw::Status::Unavailable(); + } + return std::move(session); +} + +void MessageHubManager::initEmbeddedHubsAndEndpoints( + const std::vector<HubInfo> &hubs, + const std::vector<EndpointInfo> &endpoints) { + std::lock_guard lock(mLock); + mIdToEmbeddedHub.clear(); + for (const auto &hub : hubs) mIdToEmbeddedHub[hub.hubId].info = hub; + for (const auto &endpoint : endpoints) addEmbeddedEndpointLocked(endpoint); +} + +void MessageHubManager::addEmbeddedHub(const HubInfo &hub) { + std::lock_guard lock(mLock); + if (mIdToEmbeddedHub.count(hub.hubId)) return; + mIdToEmbeddedHub[hub.hubId].info = hub; +} + +std::vector<EndpointId> MessageHubManager::removeEmbeddedHub(int64_t id) { + std::lock_guard lock(mLock); + std::vector<EndpointId> endpoints; + auto it = mIdToEmbeddedHub.find(id); + if (it != mIdToEmbeddedHub.end()) { + for (const auto &[endpointId, info] : it->second.idToEndpoint) + endpoints.push_back({.id = endpointId, .hubId = id}); + mIdToEmbeddedHub.erase(it); + } + return endpoints; +} + +std::vector<HubInfo> MessageHubManager::getEmbeddedHubs() const { + std::lock_guard lock(mLock); + std::vector<HubInfo> hubs; + for (const auto &[id, hub] : mIdToEmbeddedHub) hubs.push_back(hub.info); + return hubs; +} + +void MessageHubManager::addEmbeddedEndpoint(const EndpointInfo &endpoint) { + std::lock_guard lock(mLock); + addEmbeddedEndpointLocked(endpoint); +} + +std::vector<EndpointInfo> MessageHubManager::getEmbeddedEndpoints() const { + std::lock_guard lock(mLock); + std::vector<EndpointInfo> endpoints; + for (const auto &[id, hub] : mIdToEmbeddedHub) { + for (const auto &[endptId, endptInfo] : hub.idToEndpoint) + endpoints.push_back(*endptInfo); + } + return endpoints; +} + +void MessageHubManager::onClientDeath(void *cookie) { + auto *cookieData = reinterpret_cast<HostHub::DeathRecipientCookie *>(cookie); + MessageHubManager *manager = cookieData->manager; + std::shared_ptr<HostHub> hub = manager->getHostHubByPid(cookieData->pid); + LOGW("Hub %ld (pid %d) died", hub->id(), cookieData->pid); + manager->mHostHubDownCb(hub->unlinkFromManager()); +} + +void MessageHubManager::addEmbeddedEndpointLocked( + const EndpointInfo &endpoint) { + auto it = mIdToEmbeddedHub.find(endpoint.id.hubId); + if (it == mIdToEmbeddedHub.end()) { + LOGW("Could not find hub %ld for endpoint %ld", endpoint.id.hubId, + endpoint.id.id); + return; + } + it->second.idToEndpoint.insert( + {endpoint.id.id, std::make_shared<EndpointInfo>(endpoint)}); +} + +pw::Result<std::shared_ptr<EndpointInfo>> +MessageHubManager::getEmbeddedEndpointLocked(const EndpointId &id) { + auto hubIt = mIdToEmbeddedHub.find(id.hubId); + if (hubIt != mIdToEmbeddedHub.end()) { + auto it = hubIt->second.idToEndpoint.find(id.id); + if (it != hubIt->second.idToEndpoint.end()) return it->second; + } + LOGW("Could not find remote endpoint (%ld, %ld)", id.hubId, id.id); + return pw::Status::NotFound(); +} + +} // namespace android::hardware::contexthub::common::implementation
diff --git a/host/hal_generic/common/message_hub_manager.h b/host/hal_generic/common/message_hub_manager.h new file mode 100644 index 0000000..5353375 --- /dev/null +++ b/host/hal_generic/common/message_hub_manager.h
@@ -0,0 +1,447 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <unistd.h> + +#include <cstdint> +#include <functional> +#include <memory> +#include <mutex> +#include <optional> +#include <string> +#include <unordered_map> +#include <utility> +#include <vector> + +#include <aidl/android/hardware/contexthub/BnContextHub.h> +#include <android-base/thread_annotations.h> + +#include "pw_result/result.h" +#include "pw_status/status.h" + +namespace android::hardware::contexthub::common::implementation { + +using ::aidl::android::hardware::contexthub::EndpointId; +using ::aidl::android::hardware::contexthub::EndpointInfo; +using ::aidl::android::hardware::contexthub::HubInfo; +using ::aidl::android::hardware::contexthub::IEndpointCallback; + +/** + * Stores host and embedded MessageHub objects and maintains global mappings. + */ +class MessageHubManager { + public: + /** + * Represents a host-side MessageHub. Clients of the IContextHub (V4+) + * interface each get a HostHub instance. + */ + class HostHub { + public: + ~HostHub(); + + /** + * Sets the callback for sending endpoint events back to the HAL client + * + * @param callback The callback provided by the client + * @return pw::OkStatus() on success. + */ + pw::Status setCallback(std::shared_ptr<IEndpointCallback> callback) + EXCLUDES(mManager.mLock); + + /** + * Returns the callback registered in setCallback() + * + * @return The previously registered callback + */ + std::shared_ptr<IEndpointCallback> getCallback() const + EXCLUDES(mManager.mLock); + + /** + * Adds an endpoint to this message hub + * + * @param self Self-reference for mapping from hub id + * @param info Description of the endpoint + * @return pw::OkStatus() on success + */ + pw::Status addEndpoint(std::weak_ptr<HostHub> self, + const EndpointInfo &info) EXCLUDES(mManager.mLock); + + /** + * Removes an endpoint from this message hub + * + * @param info Id of endpoint to remove + * @return pw::OkStatus() on success + */ + pw::Status removeEndpoint(const EndpointId &info) EXCLUDES(mManager.mLock); + + /** + * Reserves a session id range to be used by this message hub + * + * @param size The size of this range, max 1024 + * @return A pair of the smallest and largest id in the range on success + */ + pw::Result<std::pair<uint16_t, uint16_t>> reserveSessionIdRange( + uint16_t size) EXCLUDES(mManager.mLock); + + /** + * Opens a session between the given endpoints with given session id + * + * The session is pending until updated by the destination endpoint. + * + * @param self Self-reference to be stored in session state + * @param localId The id of an endpoint hosted by this hub + * @param remoteId The id of the remote endpoint + * @param sessionId The id to be used for this session. Must be in the range + * allocated to this hub + * @return On success, returns a possibly null reference to the HostHub + * which hosted an endpoint on a pruned session with the same id. If not + * null, the HostHub should be notified that the session has been closed. + */ + pw::Result<std::shared_ptr<HostHub>> openSession( + std::weak_ptr<HostHub> self, const EndpointId &localId, + const EndpointId &remoteId, uint16_t sessionId) + EXCLUDES(mManager.mLock); + + /** + * Acks a pending session. + * + * @param id Session id + * @return pw::OkStatus() on success, pw::Status::Unavailable() if the + * session is gone due to an endpoint going down. + */ + pw::Status ackSession(uint16_t id) EXCLUDES(mManager.mLock); + + /** + * Checks that a session is open. + * + * @param id Session id + * @return pw::OkStatus() on success, pw::Status::Unavailable() if the + * session is gone due to an endpoint going down. + */ + pw::Status checkSessionOpen(uint16_t id) EXCLUDES(mManager.mLock); + + /** + * Removes the given session and any local and global mappings + * + * @param id The session id + * @return pw::OkStatus() on success + */ + pw::Status closeSession(uint16_t id) EXCLUDES(mManager.mLock); + + /** + * Returns the registered id of this message hub. + * + * @return kId + */ + int64_t id() const; + + private: + friend class MessageHubManager; + + // Cookie associated with each registered client callback. + struct DeathRecipientCookie { + MessageHubManager *manager; + pid_t pid; + }; + + static constexpr uint16_t kSessionIdMaxRange = 1024; + + static constexpr int64_t kHubIdInvalid = 0; + + HostHub(MessageHubManager &manager, pid_t pid) + : mManager(manager), kPid(pid) {} + + // Unlinks this hub from the manager, destroying internal references. + // Returns the id so that it can be propagated to CHRE. + int64_t unlinkFromManager() EXCLUDES(mManager.mLock); + + // Unlink the current callback from the manager's death recipient. + void unlinkCallbackIfNecessaryLocked() REQUIRES(mManager.mLock); + + // Returns pw::OkStatus() if the hub is in a valid state. + pw::Status checkValidLocked() REQUIRES(mManager.mLock); + + // Returns a shared_ptr to the given endpoint. + pw::Result<std::shared_ptr<EndpointInfo>> getEndpointLocked( + const EndpointId &id) REQUIRES(mManager.mLock); + + // Returns pw::OkStatus() if the session id is in range for this hub. + bool sessionIdInRangeLocked(uint16_t id) REQUIRES(mManager.mLock); + + MessageHubManager &mManager; + const pid_t kPid; + + // Hub id, set when the first endpoint is registered. + int64_t kId GUARDED_BY(mManager.mLock) = kHubIdInvalid; + + // Callback to HAL client. + std::shared_ptr<IEndpointCallback> mCallback GUARDED_BY(mManager.mLock); + + // Cookie associated with mCallback. + DeathRecipientCookie *mCookie GUARDED_BY(mManager.mLock); + + // Used to lookup a host endpoint. Owns the associated EndpointInfo. + std::unordered_map<int64_t, std::shared_ptr<EndpointInfo>> mIdToEndpoint + GUARDED_BY(mManager.mLock); + + // Session id ranges allocated to this HostHub. The ranges are stored as a + // pair of the lowest and highest id in the range. + std::vector<std::pair<uint16_t, uint16_t>> mSessionIdRanges + GUARDED_BY(mManager.mLock); + + // Set in unlinkFromManager(). + bool mUnlinked GUARDED_BY(mManager.mLock) = false; + }; + + // Callback registered to pass up the id of a host hub which disconnected. + using HostHubDownCb = std::function<void(int64_t hubId)>; + + // The base session id for sessions initiated from host endpoints. + static constexpr uint16_t kHostSessionIdBase = 0x8000; + + explicit MessageHubManager(HostHubDownCb cb); + ~MessageHubManager() = default; + + /** + * Retrieves the HostHub instance for the calling process + * + * This API should be used for any HostHub lookup coming from the + * IContextHub interface. The first call to this API by any client process + * will trigger the creation of a HostHub for that client. + * + * @param pid The caller's system process id + * @return shared_ptr to the HostHub instance + */ + std::shared_ptr<HostHub> getHostHubByPid(pid_t pid) EXCLUDES(mLock); + + /** + * Retrieves the HostHub instance for the given EndpointId + * + * @param id The endpoint id hosted by the returned hub + * @return shared_ptr to the HostHub instance + */ + std::shared_ptr<HostHub> getHostHubByEndpointId(const EndpointId &id) + EXCLUDES(mLock); + + /** + * Checks that a given session is open and returns its HostHub. + * + * @param id Session id + * @return A strong reference to the HostHub. pw::Status::Unavailable() + * indicates that the session has been pruned. + */ + pw::Result<std::shared_ptr<HostHub>> checkSessionOpenAndGetHostHub( + uint16_t id) EXCLUDES(mLock); + + /** + * Acks a session open request. + * + * This is called both when the destination endpoint approves and also when + * MessageRouter gives a final ack on a session initiated from an embedded + * endpoint. See the documentation on the Session class. + * + * @param id Session id + * @return A strong reference to the HostHub. pw::Status::Unavailable() + * indicates that the session has been pruned. + */ + pw::Result<std::shared_ptr<HostHub>> ackSessionAndGetHostHub(uint16_t id) + EXCLUDES(mLock); + + /** + * Apply the given function to each host hub. + * + * @param fn The function to apply. + */ + void forEachHostHub(std::function<void(HostHub &hub)> fn); + + /** + * Wipes and initializes the cache of embedded hubs and endpoints + * + * This should only be called once during startup as it invalidates session + * state (i.e. existing sessions will be pruned). + * + * @param hubs The list of message hubs + * @param endpoints The list of endpoints + */ + void initEmbeddedHubsAndEndpoints(const std::vector<HubInfo> &hubs, + const std::vector<EndpointInfo> &endpoints) + EXCLUDES(mLock); + + /** + * Adds the given hub to the cache + * + * Ignored if the hub already exists + * + * @param hub The hub to add + */ + void addEmbeddedHub(const HubInfo &hub) EXCLUDES(mLock); + + /** + * Removes the hub with given id from the cache + * + * @param id The id of the hub to remove + * @return The ids of all endpoints on the embedded hub + */ + std::vector<EndpointId> removeEmbeddedHub(int64_t id) EXCLUDES(mLock); + + /** + * Returns the cached list of embedded message hubs + * + * @return HubInfo for every embedded message hub + */ + std::vector<HubInfo> getEmbeddedHubs() const EXCLUDES(mLock); + + /** + * Adds an embedded endpoint to the cache + * + * Ignored if the endpoint already exists + * + * @param endpoint The endpoint to add + */ + void addEmbeddedEndpoint(const EndpointInfo &endpoint); + + /** + * Removes an embedded endpoint from the cache + * + * @param id The id of the endpoint to remove + */ + void removeEmbeddedEndpoint(const EndpointId &endpoint); + + /** + * Returns a list of embedded endpoints + * + * @return EndpointInfo for every embedded endpoint + */ + std::vector<EndpointInfo> getEmbeddedEndpoints() const EXCLUDES(mLock); + + private: + // Callback invoked when a client goes down. + using UnlinkToDeathFn = std::function<bool( + const std::shared_ptr<IEndpointCallback> &callback, void *cookie)>; + + // Represents an embedded MessageHub. Stores the hub details as well as a map + // of all endpoints hosted by the hub. + struct EmbeddedHub { + std::unordered_map<int64_t, std::shared_ptr<EndpointInfo>> idToEndpoint; + HubInfo info; + }; + + // Represents a session between a host and embedded endpoint. Only stores weak + // references to the endpoints and HostHub owning the host endpoint. Must be + // converted to a SessionStrongRef to temporarily access state. The weak + // references expire when the associated entity is unregistered. A + // SessionStrongRef cannot be created if any reference has expired. + // + // A Session is created on an openSession() request (triggered either by a + // local or remote endpoint) with mPendingDestination unset via a call to + // ackSession*() from the destination endpoint. For Sessions started by + // embedded endpoints, an additional ackSession*() must be received from the + // CHRE MessageRouter after passing it the ack from the destination host + // endpoint. This unsets mPendingMessageRouter. A session is only open for + // messages once both mPendingDestination and mPendingMessageRouter are unset. + struct SessionStrongRef; + class Session { + public: + Session(std::weak_ptr<HostHub> hub, std::weak_ptr<EndpointInfo> local, + std::weak_ptr<EndpointInfo> remote, bool hostInitiated) + : mHub(hub), + mLocal(local), + mRemote(remote), + mPendingMessageRouter(!hostInitiated) {} + + private: + friend struct SessionStrongRef; + + std::weak_ptr<HostHub> mHub; + std::weak_ptr<EndpointInfo> mLocal; + std::weak_ptr<EndpointInfo> mRemote; + bool mPendingDestination = true; + bool mPendingMessageRouter; + }; + + // A strong reference to a Session's underlying endpoints and HostHub as well + // as Session metadata. A SessionStrongRef should be created and destroyed + // within a single critical section. + struct SessionStrongRef { + std::shared_ptr<HostHub> hub; + std::shared_ptr<EndpointInfo> local; + std::shared_ptr<EndpointInfo> remote; + bool &pendingDestination; + bool &pendingMessageRouter; + + SessionStrongRef(Session &session) + : hub(session.mHub.lock()), + local(session.mLocal.lock()), + remote(session.mRemote.lock()), + pendingDestination(session.mPendingDestination), + pendingMessageRouter(session.mPendingMessageRouter) {} + operator bool() const { + return hub && local && remote; + } + }; + + // The hub id reserved for the ContextHub service. + static constexpr int64_t kContextHubServiceHubId = 0x416e64726f696400; + + // The Linux uid of the system_server. + static constexpr uid_t kSystemServerUid = 1000; + + // Invoked on client death. Cleans up references to the client. + static void onClientDeath(void *cookie); + + // Retrieves a strong reference to the session with given id. + pw::Result<SessionStrongRef> checkSessionLocked(uint16_t id) REQUIRES(mLock); + + // Adds an embedded endpoint to the cache. + void addEmbeddedEndpointLocked(const EndpointInfo &endpoint) REQUIRES(mLock); + + // Returns true if the embedded endpoint with given id is in the cache. + pw::Result<std::shared_ptr<EndpointInfo>> getEmbeddedEndpointLocked( + const EndpointId &id) REQUIRES(mLock); + + // Callback to pass up the id of a host hub for a client that disconnected. + HostHubDownCb mHostHubDownCb; + + // Death recipient handling clients' disconnections. + ndk::ScopedAIBinder_DeathRecipient mDeathRecipient; + + // Guards hub, endpoint, and session state. + mutable std::mutex mLock; + + // Map of EmbeddedHubs. + std::unordered_map<int64_t, EmbeddedHub> mIdToEmbeddedHub GUARDED_BY(mLock); + + // Used to look up the HostHub associated with the client on IContextHub + // calls. + std::unordered_map<pid_t, std::shared_ptr<HostHub>> mPidToHostHub + GUARDED_BY(mLock); + + // Used when an embedded endpoint wants to start a session with an endpoint + // hosted by a specific HostHub. + std::unordered_map<int64_t, std::weak_ptr<HostHub>> mIdToHostHub + GUARDED_BY(mLock); + + // Used to lookup the host endpoint to receive a message on an endpoint + // session. + std::unordered_map<uint16_t, Session> mIdToSession GUARDED_BY(mLock); + + // Next session id from which to allocate ranges. + uint16_t mNextSessionId GUARDED_BY(mLock) = kHostSessionIdBase; +}; + +} // namespace android::hardware::contexthub::common::implementation
diff --git a/host/hal_generic/common/multi_client_context_hub_base.cc b/host/hal_generic/common/multi_client_context_hub_base.cc index 8eb92eb..356de2a 100644 --- a/host/hal_generic/common/multi_client_context_hub_base.cc +++ b/host/hal_generic/common/multi_client_context_hub_base.cc
@@ -39,7 +39,6 @@ using ::android::chre::Atoms::ChreHalNanoappLoadFailed; using ::android::chre::flags::abort_if_no_context_hub_found; using ::android::chre::flags::bug_fix_hal_reliable_message_record; -using ::android::chre::flags::reliable_message_implementation; using ::ndk::ScopedAStatus; namespace fbs = ::chre::fbs; @@ -172,6 +171,12 @@ ScopedAStatus MultiClientContextHubBase::getContextHubs( std::vector<ContextHubInfo> *contextHubInfos) { + if (!mIsChreReady) { + LOGE("%s() can't be processed as CHRE is not ready", __func__); + // Return ok() here to not crash system server + return ScopedAStatus::ok(); + } + std::unique_lock<std::mutex> lock(mHubInfoMutex); if (mContextHubInfo == nullptr) { fbs::HubInfoResponseT response; @@ -200,10 +205,15 @@ ScopedAStatus MultiClientContextHubBase::loadNanoapp( int32_t contextHubId, const NanoappBinary &appBinary, int32_t transactionId) { + if (!mIsChreReady) { + LOGE("%s() can't be processed as CHRE is not ready", __func__); + return fromServiceError(HalError::CHRE_NOT_READY); + } if (!isValidContextHubId(contextHubId)) { return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } - LOGD("Loading nanoapp 0x%" PRIx64, appBinary.nanoappId); + LOGD("Loading nanoapp 0x%" PRIx64 ", transaction id=%" PRIi32, + appBinary.nanoappId, transactionId); uint32_t targetApiVersion = (appBinary.targetChreApiMajorVersion << 24) | (appBinary.targetChreApiMinorVersion << 16); auto nanoappBuffer = @@ -254,6 +264,10 @@ ScopedAStatus MultiClientContextHubBase::unloadNanoapp(int32_t contextHubId, int64_t appId, int32_t transactionId) { + if (!mIsChreReady) { + LOGE("%s() can't be processed as CHRE is not ready", __func__); + return fromServiceError(HalError::CHRE_NOT_READY); + } if (!isValidContextHubId(contextHubId)) { return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } @@ -296,6 +310,10 @@ ScopedAStatus MultiClientContextHubBase::onSettingChanged(Setting setting, bool enabled) { + if (!mIsChreReady) { + LOGE("%s() can't be processed as CHRE is not ready", __func__); + return fromServiceError(HalError::CHRE_NOT_READY); + } mSettingEnabled[setting] = enabled; fbs::Setting fbsSetting; bool isWifiOrBtSetting = @@ -346,6 +364,10 @@ } ScopedAStatus MultiClientContextHubBase::queryNanoapps(int32_t contextHubId) { + if (!mIsChreReady) { + LOGE("%s() can't be processed as CHRE is not ready", __func__); + return fromServiceError(HalError::CHRE_NOT_READY); + } if (!isValidContextHubId(contextHubId)) { return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } @@ -380,6 +402,8 @@ ScopedAStatus MultiClientContextHubBase::registerCallback( int32_t contextHubId, const std::shared_ptr<IContextHubCallback> &callback) { + // Even CHRE is not ready we should open this API to clients because it allows + // us to have a channel to report events back to them. if (!isValidContextHubId(contextHubId)) { return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } @@ -406,6 +430,10 @@ ScopedAStatus MultiClientContextHubBase::sendMessageToHub( int32_t contextHubId, const ContextHubMessage &message) { + if (!mIsChreReady) { + LOGE("%s() can't be processed as CHRE is not ready", __func__); + return fromServiceError(HalError::CHRE_NOT_READY); + } if (!isValidContextHubId(contextHubId)) { return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } @@ -416,7 +444,7 @@ return fromResult(false); } - if (reliable_message_implementation() && message.isReliable) { + if (message.isReliable) { if (bug_fix_hal_reliable_message_record()) { std::lock_guard<std::mutex> lock(mReliableMessageMutex); auto iter = std::find_if( @@ -439,19 +467,12 @@ } flatbuffers::FlatBufferBuilder builder(1024); - if (reliable_message_implementation()) { - HostProtocolHost::encodeNanoappMessage( - builder, message.nanoappId, message.messageType, hostEndpointId, - message.messageBody.data(), message.messageBody.size(), - /* permissions= */ 0, - /* messagePermissions= */ 0, - /* wokeHost= */ false, message.isReliable, - message.messageSequenceNumber); - } else { - HostProtocolHost::encodeNanoappMessage( - builder, message.nanoappId, message.messageType, hostEndpointId, - message.messageBody.data(), message.messageBody.size()); - } + HostProtocolHost::encodeNanoappMessage( + builder, message.nanoappId, message.messageType, hostEndpointId, + message.messageBody.data(), message.messageBody.size(), + /* permissions= */ 0, + /* messagePermissions= */ 0, + /* wokeHost= */ false, message.isReliable, message.messageSequenceNumber); bool success = mConnection->sendMessage(builder); mEventLogger.logMessageToNanoapp(message, success); @@ -460,6 +481,10 @@ ScopedAStatus MultiClientContextHubBase::onHostEndpointConnected( const HostEndpointInfo &info) { + if (!mIsChreReady) { + LOGE("%s() can't be processed as CHRE is not ready", __func__); + return fromServiceError(HalError::CHRE_NOT_READY); + } uint8_t type; switch (info.type) { case HostEndpointInfo::Type::APP: @@ -491,6 +516,10 @@ ScopedAStatus MultiClientContextHubBase::onHostEndpointDisconnected( char16_t in_hostEndpointId) { + if (!mIsChreReady) { + LOGE("%s() can't be processed as CHRE is not ready", __func__); + return fromServiceError(HalError::CHRE_NOT_READY); + } HostEndpointId hostEndpointId = in_hostEndpointId; pid_t pid = AIBinder_getCallingPid(); bool isSuccessful = false; @@ -509,11 +538,19 @@ ScopedAStatus MultiClientContextHubBase::onNanSessionStateChanged( const NanSessionStateUpdate & /*in_update*/) { + if (!mIsChreReady) { + LOGE("%s() can't be processed as CHRE is not ready", __func__); + return fromServiceError(HalError::CHRE_NOT_READY); + } // TODO(271471342): Add support for NAN session management. return ndk::ScopedAStatus::ok(); } ScopedAStatus MultiClientContextHubBase::setTestMode(bool enable) { + if (!mIsChreReady) { + LOGE("%s() can't be processed as CHRE is not ready", __func__); + return fromServiceError(HalError::CHRE_NOT_READY); + } if (enable) { return fromResult(enableTestMode()); } @@ -523,10 +560,10 @@ ScopedAStatus MultiClientContextHubBase::sendMessageDeliveryStatusToHub( int32_t contextHubId, const MessageDeliveryStatus &messageDeliveryStatus) { - if (!reliable_message_implementation()) { - return ScopedAStatus::ok(); + if (!mIsChreReady) { + LOGE("%s() can't be processed as CHRE is not ready", __func__); + return fromServiceError(HalError::CHRE_NOT_READY); } - if (!isValidContextHubId(contextHubId)) { return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } @@ -543,6 +580,77 @@ return fromResult(success); } +ScopedAStatus MultiClientContextHubBase::getHubs(std::vector<HubInfo> *hubs) { + if (mV4Impl) return mV4Impl->getHubs(hubs); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus MultiClientContextHubBase::getEndpoints( + std::vector<EndpointInfo> *endpoints) { + if (mV4Impl) return mV4Impl->getEndpoints(endpoints); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus MultiClientContextHubBase::registerEndpoint( + const EndpointInfo &endpoint) { + if (mV4Impl) return mV4Impl->registerEndpoint(endpoint); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus MultiClientContextHubBase::unregisterEndpoint( + const EndpointInfo &endpoint) { + if (mV4Impl) return mV4Impl->unregisterEndpoint(endpoint); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus MultiClientContextHubBase::registerEndpointCallback( + const std::shared_ptr<IEndpointCallback> &callback) { + if (mV4Impl) return mV4Impl->registerEndpointCallback(callback); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus MultiClientContextHubBase::requestSessionIdRange( + int32_t size, std::vector<int32_t> *ids) { + if (mV4Impl) return mV4Impl->requestSessionIdRange(size, ids); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus MultiClientContextHubBase::openEndpointSession( + int32_t sessionId, const EndpointId &destination, + const EndpointId &initiator, + const std::optional<std::string> &serviceDescriptor) { + if (mV4Impl) { + return mV4Impl->openEndpointSession(sessionId, destination, initiator, + serviceDescriptor); + } + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus MultiClientContextHubBase::sendMessageToEndpoint( + int32_t sessionId, const Message &msg) { + if (mV4Impl) return mV4Impl->sendMessageToEndpoint(sessionId, msg); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus MultiClientContextHubBase::sendMessageDeliveryStatusToEndpoint( + int32_t sessionId, const MessageDeliveryStatus &msgStatus) { + if (mV4Impl) + return mV4Impl->sendMessageDeliveryStatusToEndpoint(sessionId, msgStatus); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus MultiClientContextHubBase::closeEndpointSession(int32_t sessionId, + Reason reason) { + if (mV4Impl) return mV4Impl->closeEndpointSession(sessionId, reason); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ScopedAStatus MultiClientContextHubBase::endpointSessionOpenComplete( + int32_t sessionId) { + if (mV4Impl) return mV4Impl->endpointSessionOpenComplete(sessionId); + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + bool MultiClientContextHubBase::enableTestMode() { std::unique_lock<std::mutex> lock(mTestModeMutex); if (mIsTestModeEnabled) { @@ -688,8 +796,12 @@ break; } default: - LOGW("Got unexpected message type %" PRIu8, - static_cast<uint8_t>(message.type)); + if (mV4Impl) { + mV4Impl->handleMessageFromChre(message); + } else { + LOGW("Got unexpected message type %" PRIu8, + static_cast<uint8_t>(message.type)); + } } } @@ -711,7 +823,7 @@ mContextHubInfo->supportedPermissions = kSupportedPermissions; mContextHubInfo->supportsReliableMessages = - reliable_message_implementation() && response.supports_reliable_messages; + response.supports_reliable_messages; mHubInfoCondition.notify_all(); } @@ -889,14 +1001,8 @@ outMessage.messageType = message.message_type; outMessage.messageBody = message.message; outMessage.permissions = chreToAndroidPermissions(message.permissions); - - if (reliable_message_implementation()) { - outMessage.isReliable = message.is_reliable; - outMessage.messageSequenceNumber = message.message_sequence_number; - } else { - outMessage.isReliable = false; - outMessage.messageSequenceNumber = 0; - } + outMessage.isReliable = message.is_reliable; + outMessage.messageSequenceNumber = message.message_sequence_number; std::string messageSeq = "reliable message seq=" + std::to_string(outMessage.messageSequenceNumber); @@ -927,10 +1033,6 @@ void MultiClientContextHubBase::onMessageDeliveryStatus( const ::chre::fbs::MessageDeliveryStatusT &status) { - if (!reliable_message_implementation()) { - return; - } - HostEndpointId hostEndpointId; if (bug_fix_hal_reliable_message_record()) { { @@ -1007,6 +1109,15 @@ mIsWifiAvailable.reset(); mEventLogger.logContextHubRestart(); mHalClientManager->handleChreRestart(); + + // Unblock APIs BEFORE informing the clients that CHRE has restarted so that + // any API call triggered by handleContextHubAsyncEvent() can come through. + mIsChreReady = true; + std::vector<std::shared_ptr<IContextHubCallback>> callbacks = + mHalClientManager->getCallbacks(); + for (auto callback : callbacks) { + callback->handleContextHubAsyncEvent(AsyncEventType::RESTARTED); + } } binder_status_t MultiClientContextHubBase::dump(int fd,
diff --git a/host/hal_generic/common/multi_client_context_hub_base.h b/host/hal_generic/common/multi_client_context_hub_base.h index c596089..ea7b6f3 100644 --- a/host/hal_generic/common/multi_client_context_hub_base.h +++ b/host/hal_generic/common/multi_client_context_hub_base.h
@@ -26,6 +26,7 @@ #include "chre_host/napp_header.h" #include "chre_host/preloaded_nanoapp_loader.h" #include "chre_host/time_syncer.h" +#include "context_hub_v4_impl.h" #include "debug_dump_helper.h" #include "event_logger.h" #include "hal_client_id.h" @@ -33,9 +34,11 @@ #include <chrono> #include <deque> +#include <memory> #include <mutex> #include <optional> #include <unordered_map> +#include <vector> namespace android::hardware::contexthub::common::implementation { @@ -89,11 +92,32 @@ ScopedAStatus sendMessageDeliveryStatusToHub( int32_t contextHubId, const MessageDeliveryStatus &messageDeliveryStatus) override; + ScopedAStatus getHubs(std::vector<HubInfo> *hubs) override; + ScopedAStatus getEndpoints(std::vector<EndpointInfo> *endpoints) override; + ScopedAStatus registerEndpoint(const EndpointInfo &endpoint) override; + ScopedAStatus unregisterEndpoint(const EndpointInfo &endpoint) override; + ScopedAStatus registerEndpointCallback( + const std::shared_ptr<IEndpointCallback> &callback) override; + ScopedAStatus requestSessionIdRange(int32_t size, + std::vector<int32_t> *ids) override; + ScopedAStatus openEndpointSession( + int32_t sessionId, const EndpointId &destination, + const EndpointId &initiator, + const std::optional<std::string> &serviceDescriptor) override; + ScopedAStatus sendMessageToEndpoint(int32_t sessionId, + const Message &msg) override; + ScopedAStatus sendMessageDeliveryStatusToEndpoint( + int32_t sessionId, const MessageDeliveryStatus &msgStatus) override; + ScopedAStatus closeEndpointSession(int32_t sessionId, Reason reason) override; + ScopedAStatus endpointSessionOpenComplete(int32_t sessionId) override; // Functions implementing ChreConnectionCallback. void handleMessageFromChre(const unsigned char *messageBuffer, size_t messageLen) override; void onChreRestarted() override; + void onChreDisconnected() override { + mIsChreReady = false; + } // Functions for dumping debug information. binder_status_t dump(int fd, const char **args, uint32_t numArgs) override; @@ -197,6 +221,10 @@ // one instance of a HalClientManager. std::unique_ptr<HalClientManager> mHalClientManager{}; + // Implementation of the V4+ API. Should be instantiated by the target HAL + // implementation. + std::optional<ContextHubV4Impl> mV4Impl{}; + std::unique_ptr<PreloadedNanoappLoader> mPreloadedNanoappLoader{}; std::unique_ptr<ContextHubInfo> mContextHubInfo; @@ -242,6 +270,12 @@ std::mutex mReliableMessageMutex; std::deque<ReliableMessageRecord> mReliableMessageQueue; + // A thread safe flag indicating if CHRE is ready for operations. + // Outside of the constructor, this boolean flag should only be written by + // onChreDisconnected and onChreRestarted, the order of which should be + // guaranteed by the CHRE's disconnection handler. + std::atomic_bool mIsChreReady = true; + // TODO(b/333567700): Remove when cleaning up the bug_fix_hal_reliable_message_record flag std::unordered_map<int32_t, HostEndpointId> mReliableMessageMap; };
diff --git a/host/test/hal_generic/common/hal_client_manager_test.cc b/host/test/hal_generic/common/hal_client_manager_test.cc index e40e249..7a57a2c 100644 --- a/host/test/hal_generic/common/hal_client_manager_test.cc +++ b/host/test/hal_generic/common/hal_client_manager_test.cc
@@ -535,7 +535,7 @@ EXPECT_THAT(client.endpointIds, IsEmpty()); } -TEST_F(HalClientManagerTest, handleChreRestartForConnectedClientsOnly) { +TEST_F(HalClientManagerTest, handleChreRestart) { auto halClientManager = std::make_unique<HalClientManagerForTest>( mockDeadClientUnlinker, kClientIdMappingFilePath); std::shared_ptr<ContextHubCallbackForTest> vendorCallback = @@ -550,17 +550,35 @@ EXPECT_TRUE(halClientManager->registerCallback( kVendorPid, vendorCallback, /* deathRecipientCookie= */ nullptr)); - // Only connected clients' handleContextHubAsyncEvent should be called. + // Calls to clients' handleContextHubAsyncEvent should be postponed to HAL. EXPECT_CALL(*systemCallback, - handleContextHubAsyncEvent(AsyncEventType::RESTARTED)); + handleContextHubAsyncEvent(AsyncEventType::RESTARTED)) + .Times(0); EXPECT_CALL(*vendorCallback, handleContextHubAsyncEvent(AsyncEventType::RESTARTED)) .Times(0); - // Disconnect the vendor client and handle CHRE restart for the system server - halClientManager->handleClientDeath(kVendorPid); halClientManager->handleChreRestart(); } +TEST_F(HalClientManagerTest, getAllConnectedCallbacks) { + auto halClientManager = std::make_unique<HalClientManagerForTest>( + mockDeadClientUnlinker, kClientIdMappingFilePath); + std::shared_ptr<ContextHubCallbackForTest> vendorCallback = + ContextHubCallbackForTest::make<ContextHubCallbackForTest>(kVendorUuid); + std::shared_ptr<ContextHubCallbackForTest> systemCallback = + ContextHubCallbackForTest::make<ContextHubCallbackForTest>( + kSystemServerUuid); + // Register the system callback + EXPECT_TRUE(halClientManager->registerCallback( + kSystemServerPid, systemCallback, /* deathRecipientCookie= */ nullptr)); + // Register the vendor callback + EXPECT_TRUE(halClientManager->registerCallback( + kVendorPid, vendorCallback, /* deathRecipientCookie= */ nullptr)); + + EXPECT_THAT(halClientManager->getCallbacks(), + UnorderedElementsAre(vendorCallback, systemCallback)); +} + } // namespace } // namespace android::hardware::contexthub::common::implementation
diff --git a/host/tinysys/hal/Android.bp b/host/tinysys/hal/Android.bp index dc7e51d..ba1e970 100644 --- a/host/tinysys/hal/Android.bp +++ b/host/tinysys/hal/Android.bp
@@ -28,7 +28,10 @@ cc_binary { name: "android.hardware.contexthub-service.tinysys", cpp_std: "c++20", - defaults: ["hidl_defaults"], + defaults: [ + "contexthub_hal_defaults", + "hidl_defaults", + ], vendor: true, relative_install_path: "hw", srcs: [ @@ -38,47 +41,13 @@ "tinysys_chre_connection.cc", "tinysys_context_hub.cc", ], - include_dirs: [ - "system/chre/host/common/include/", - "system/chre/host/hal_generic/aidl/", - "system/chre/host/hal_generic/common/", - "system/chre/platform/shared/include/", - "system/chre/util/include/", - ], - cflags: [ - "-DCHRE_HOST_DEFAULT_FRAGMENT_SIZE=2048", - "-DCHRE_IS_HOST_BUILD", - "-DCHRE_MESSAGE_TO_HOST_MAX_SIZE=4000", - "-DCHRE_ST_LPMA_HANDLER_AIDL", - "-Wall", - "-Werror", - ], + cflags: ["-DCHRE_ST_LPMA_HANDLER_AIDL"], shared_libs: [ - "android.frameworks.stats-V2-ndk", - "android.hardware.contexthub-V3-ndk", "android.hardware.soundtrigger3-V1-ndk", "android.media.soundtrigger.types-V1-ndk", - "chre_atoms_log", - "chremetrics-cpp", - "libaconfig_storage_read_api_cc", - "libbase", - "libbinder_ndk", - "libcutils", - "libjsoncpp", - "liblog", "libpower", - "libprotobuf-cpp-lite", - "libutils", - "server_configurable_flags", - ], - header_libs: [ - "chre_api", ], static_libs: [ - "chre_client", - "chre_flags_c_lib", - "chre_metrics_reporter", - "event_logger", "pw_detokenizer", "pw_polyfill", "pw_span",
diff --git a/host/tinysys/hal/android.hardware.contexthub-service.tinysys.xml b/host/tinysys/hal/android.hardware.contexthub-service.tinysys.xml index db2e2d7..3d9d4af 100644 --- a/host/tinysys/hal/android.hardware.contexthub-service.tinysys.xml +++ b/host/tinysys/hal/android.hardware.contexthub-service.tinysys.xml
@@ -1,7 +1,7 @@ <manifest version="1.0" type="device"> <hal format="aidl"> <name>android.hardware.contexthub</name> - <version>3</version> + <version>4</version> <fqname>IContextHub/default</fqname> </hal> </manifest>
diff --git a/host/tinysys/hal/tinysys_chre_connection.cc b/host/tinysys/hal/tinysys_chre_connection.cc index ddd8402..777596f 100644 --- a/host/tinysys/hal/tinysys_chre_connection.cc +++ b/host/tinysys/hal/tinysys_chre_connection.cc
@@ -70,8 +70,8 @@ bool TinysysChreConnection::init() { // Make sure the payload size is large enough for nanoapp binary fragment - static_assert(kMaxPayloadBytes > CHRE_HOST_DEFAULT_FRAGMENT_SIZE && - kMaxPayloadBytes - CHRE_HOST_DEFAULT_FRAGMENT_SIZE > + static_assert(kMaxSendingPayloadBytes > CHRE_HOST_DEFAULT_FRAGMENT_SIZE && + kMaxSendingPayloadBytes - CHRE_HOST_DEFAULT_FRAGMENT_SIZE > kMaxPayloadOverheadBytes); mChreFileDescriptor = TEMP_FAILURE_RETRY(open(kChreFileDescriptorPath, O_RDWR)); @@ -93,8 +93,8 @@ auto chreFd = chreConnection->getChreFileDescriptor(); while (true) { { - ssize_t payloadSize = TEMP_FAILURE_RETRY( - read(chreFd, chreConnection->mPayload.get(), kMaxPayloadBytes)); + ssize_t payloadSize = TEMP_FAILURE_RETRY(read( + chreFd, chreConnection->mPayload.get(), kMaxReceivingPayloadBytes)); if (payloadSize == 0) { // Payload size 0 is a fake signal from kernel which is normal if the // device is in sleep. @@ -161,7 +161,7 @@ } bool TinysysChreConnection::sendMessage(void *data, size_t length) { - if (length <= 0 || length > kMaxPayloadBytes) { + if (length <= 0 || length > kMaxSendingPayloadBytes) { LOGE("length %zu is not within the accepted range.", length); return false; }
diff --git a/host/tinysys/hal/tinysys_chre_connection.h b/host/tinysys/hal/tinysys_chre_connection.h index d30ba8f..5c771b4 100644 --- a/host/tinysys/hal/tinysys_chre_connection.h +++ b/host/tinysys/hal/tinysys_chre_connection.h
@@ -44,7 +44,7 @@ public: TinysysChreConnection(ChreConnectionCallback *callback) : mCallback(callback), mLpmaHandler(/* allowed= */ true) { - mPayload = std::make_unique<uint8_t[]>(kMaxPayloadBytes); + mPayload = std::make_unique<uint8_t[]>(kMaxReceivingPayloadBytes); }; ~TinysysChreConnection() override { @@ -104,11 +104,10 @@ static constexpr char kWakeLock[] = "tinysys_chre_hal_wakelock"; // Max payload size that can be sent to CHRE - // TODO(b/277235389): Adjust max payload size (AP -> SCP and SCP -> AP) - // as appropriate. This is a temp/quick fix for b/272311907 and b/270758946 - // setting max payload allowed to CHRE_MESSAGE_TO_HOST_MAX_SIZE + 128 byte - // to account for transport overhead. - static constexpr uint32_t kMaxPayloadBytes = 4224; // 4096 + 128 + static constexpr uint32_t kMaxSendingPayloadBytes = 0x8000; // 32K + + // Max payload size that can be received from CHRE + static constexpr uint32_t kMaxReceivingPayloadBytes = 0x8000; // 32K // Max overhead of the nanoapp binary payload caused by the fbs encapsulation static constexpr uint32_t kMaxPayloadOverheadBytes = 1024; @@ -126,10 +125,10 @@ // security check for proper use of the device node. uint32_t magic = 0x67728269; uint32_t payloadSize = 0; - uint8_t payload[kMaxPayloadBytes]; + uint8_t payload[kMaxSendingPayloadBytes]; ChreConnectionMessage(void *data, size_t length) { - assert(length <= kMaxPayloadBytes); + assert(length <= kMaxSendingPayloadBytes); memcpy(payload, data, length); payloadSize = static_cast<uint32_t>(length); }
diff --git a/java/test/audio_diagnostics/src/com/google/android/chre/test/audio_diagnostics/ContextHubAudioDiagnosticsTestExecutor.java b/java/test/audio_diagnostics/src/com/google/android/chre/test/audio_diagnostics/ContextHubAudioDiagnosticsTestExecutor.java index e67f038..b7defb0 100644 --- a/java/test/audio_diagnostics/src/com/google/android/chre/test/audio_diagnostics/ContextHubAudioDiagnosticsTestExecutor.java +++ b/java/test/audio_diagnostics/src/com/google/android/chre/test/audio_diagnostics/ContextHubAudioDiagnosticsTestExecutor.java
@@ -149,8 +149,8 @@ "audio_dc_offset_test_data.bin", mContext); Log.i(TAG, "DC Offset: " + runningSampleAvg); - Assert.assertTrue("DC offset " + runningSampleAvg + " >= threshold " + DC_OFFSET_LIMIT, - runningSampleAvg < DC_OFFSET_LIMIT); + Assert.assertTrue("DC offset " + runningSampleAvg + " > threshold " + DC_OFFSET_LIMIT, + runningSampleAvg <= DC_OFFSET_LIMIT); } /**
diff --git a/java/test/chqts/src/com/google/android/chre/test/chqts/ContextHubPendingIntentTestExecutor.java b/java/test/chqts/src/com/google/android/chre/test/chqts/ContextHubPendingIntentTestExecutor.java index 272de45..98320d7 100644 --- a/java/test/chqts/src/com/google/android/chre/test/chqts/ContextHubPendingIntentTestExecutor.java +++ b/java/test/chqts/src/com/google/android/chre/test/chqts/ContextHubPendingIntentTestExecutor.java
@@ -84,7 +84,7 @@ } public void init() throws InterruptedException, TimeoutException { - mTestHelper.initAndUnloadAllNanoApps(); + mTestHelper.init(); } /**
diff --git a/java/test/cross_validation/src/com/google/android/chre/test/crossvalidator/ChreCrossValidatorBase.java b/java/test/cross_validation/src/com/google/android/chre/test/crossvalidator/ChreCrossValidatorBase.java index c564127..0727580 100644 --- a/java/test/cross_validation/src/com/google/android/chre/test/crossvalidator/ChreCrossValidatorBase.java +++ b/java/test/cross_validation/src/com/google/android/chre/test/crossvalidator/ChreCrossValidatorBase.java
@@ -23,14 +23,9 @@ import android.hardware.location.ContextHubTransaction; import android.hardware.location.NanoAppBinary; import android.hardware.location.NanoAppMessage; -import android.hardware.location.NanoAppState; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; -import android.util.Log; import com.google.android.utils.chre.ChreTestUtil; -import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; @@ -99,9 +94,6 @@ /** * Validate the data from AP and CHRE according to the parameters passed to this cross * validator. Should be called in @Test methods of tests. - * - * @param samplingDurationInMs The amount of time in milliseconds to collect samples from AP and - * CHRE. */ public abstract void validate() throws AssertionError, InterruptedException; @@ -120,28 +112,6 @@ } /** - * Unloads all nanoapps from device. Call before validating data to ensure no inconsistencies - * with data received. - */ - private void unloadAllNanoApps() { - // We only need to unload all nanoapps when the device has version < U, so the - // tests remain the same on those devices. On newer devices, test mode will - // handle this. - if (VERSION.SDK_INT >= VERSION_CODES.UPSIDE_DOWN_CAKE) { - return; - } - - List<NanoAppState> nanoAppStateList = - ChreTestUtil.queryNanoAppsAssertSuccess(mContextHubManager, mContextHubInfo); - - for (NanoAppState state : nanoAppStateList) { - ChreTestUtil.unloadNanoAppAssertSuccess( - mContextHubManager, mContextHubInfo, state.getNanoAppId()); - Log.d(TAG, String.format("Unloaded napp: 0x%X", state.getNanoAppId())); - } - } - - /** * Close the context hub client connection. */ private void closeContextHubConnection() { @@ -163,28 +133,20 @@ * @return the name of the context hub result. */ protected static String contextHubTransactionResultToString(int result) { - switch (result) { - case ContextHubTransaction.RESULT_SUCCESS: - return "RESULT_SUCCESS"; - case ContextHubTransaction.RESULT_FAILED_UNKNOWN: - return "RESULT_FAILED_UNKNOWN"; - case ContextHubTransaction.RESULT_FAILED_BAD_PARAMS: - return "RESULT_FAILED_BAD_PARAMS"; - case ContextHubTransaction.RESULT_FAILED_UNINITIALIZED: - return "RESULT_FAILED_UNINITIALIZED"; - case ContextHubTransaction.RESULT_FAILED_BUSY: - return "RESULT_FAILED_BUSY"; - case ContextHubTransaction.RESULT_FAILED_AT_HUB: - return "RESULT_FAILED_AT_HUB"; - case ContextHubTransaction.RESULT_FAILED_TIMEOUT: - return "RESULT_FAILED_TIMEOUT"; - case ContextHubTransaction.RESULT_FAILED_SERVICE_INTERNAL_FAILURE: - return "RESULT_FAILED_SERVICE_INTERNAL_FAILURE"; - case ContextHubTransaction.RESULT_FAILED_HAL_UNAVAILABLE: - return "RESULT_FAILED_HAL_UNAVAILABLE"; - default: - return "UNKNOWN_RESULT"; - } + return switch (result) { + case ContextHubTransaction.RESULT_SUCCESS -> "RESULT_SUCCESS"; + case ContextHubTransaction.RESULT_FAILED_UNKNOWN -> "RESULT_FAILED_UNKNOWN"; + case ContextHubTransaction.RESULT_FAILED_BAD_PARAMS -> "RESULT_FAILED_BAD_PARAMS"; + case ContextHubTransaction.RESULT_FAILED_UNINITIALIZED -> "RESULT_FAILED_UNINITIALIZED"; + case ContextHubTransaction.RESULT_FAILED_BUSY -> "RESULT_FAILED_BUSY"; + case ContextHubTransaction.RESULT_FAILED_AT_HUB -> "RESULT_FAILED_AT_HUB"; + case ContextHubTransaction.RESULT_FAILED_TIMEOUT -> "RESULT_FAILED_TIMEOUT"; + case ContextHubTransaction.RESULT_FAILED_SERVICE_INTERNAL_FAILURE -> + "RESULT_FAILED_SERVICE_INTERNAL_FAILURE"; + case ContextHubTransaction.RESULT_FAILED_HAL_UNAVAILABLE -> + "RESULT_FAILED_HAL_UNAVAILABLE"; + default -> "UNKNOWN_RESULT"; + }; } /**
diff --git a/java/test/utils/src/com/google/android/utils/chre/ChreApiTestUtil.java b/java/test/utils/src/com/google/android/utils/chre/ChreApiTestUtil.java index 75e56d4..c01b020 100644 --- a/java/test/utils/src/com/google/android/utils/chre/ChreApiTestUtil.java +++ b/java/test/utils/src/com/google/android/utils/chre/ChreApiTestUtil.java
@@ -548,7 +548,7 @@ */ public static void writeDataToFile(byte[] data, String filename, Context context) throws Exception { - File file = new File(context.getExternalFilesDir(null), filename); + File file = new File(context.getFilesDir(), filename); ByteSink sink = Files.asByteSink(file); sink.write(data); }
diff --git a/java/test/utils/src/com/google/android/utils/chre/ContextHubBroadcastReceiver.java b/java/test/utils/src/com/google/android/utils/chre/ContextHubBroadcastReceiver.java index 3a34d4f..e626b1a 100644 --- a/java/test/utils/src/com/google/android/utils/chre/ContextHubBroadcastReceiver.java +++ b/java/test/utils/src/com/google/android/utils/chre/ContextHubBroadcastReceiver.java
@@ -51,7 +51,7 @@ } Log.d(TAG, "Received intent event: " + event); - Assert.assertEquals("Received too many Intent events", sQueue.size(), 0); + Assert.assertEquals("Received too many Intent events", /* expected= */ 0, sQueue.size()); sQueue.add(event); }
diff --git a/java/test/utils/src/com/google/android/utils/chre/ContextHubServiceTestHelper.java b/java/test/utils/src/com/google/android/utils/chre/ContextHubServiceTestHelper.java index 18623a0..9bd5899 100644 --- a/java/test/utils/src/com/google/android/utils/chre/ContextHubServiceTestHelper.java +++ b/java/test/utils/src/com/google/android/utils/chre/ContextHubServiceTestHelper.java
@@ -26,8 +26,6 @@ import android.hardware.location.ContextHubTransaction; import android.hardware.location.NanoAppBinary; import android.hardware.location.NanoAppState; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; import java.util.HashMap; import java.util.List; @@ -65,18 +63,6 @@ registerHubResetClient(); } - public void initAndUnloadAllNanoApps() throws InterruptedException, TimeoutException { - init(); - - // We only need to unload all nanoapps when the device has version < U, so the - // tests remain the same on those devices. On newer devices, test mode will - // handle this. - if (VERSION.SDK_INT < VERSION_CODES.UPSIDE_DOWN_CAKE) { - // Unload all nanoapps to ensure test starts at a clean state. - unloadAllNanoApps(); - } - } - public void deinit() { // unregister to detect any hub reset. unregisterHubResetClient();
diff --git a/pal/CMakeLists.txt b/pal/CMakeLists.txt new file mode 100644 index 0000000..b8d562d --- /dev/null +++ b/pal/CMakeLists.txt
@@ -0,0 +1,99 @@ +include($ENV{PW_ROOT}/pw_build/pigweed.cmake) +include(backend.cmake) + +pw_add_facade(chre.pal.audio INTERFACE + BACKEND + chre.pal.audio_BACKEND + HEADERS + include/chre/pal/audio.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.pal.system + chre.pal.version + chre.chre_api +) + +pw_add_facade(chre.pal.ble INTERFACE + BACKEND + chre.pal.ble_BACKEND + HEADERS + include/chre/pal/ble.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.pal.system + chre.pal.version + chre.chre_api +) + +pw_add_facade(chre.pal.gnss INTERFACE + BACKEND + chre.pal.gnss_BACKEND + HEADERS + include/chre/pal/gnss.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.pal.system + chre.pal.version + chre.chre_api +) + +pw_add_facade(chre.pal.sensor INTERFACE + BACKEND + chre.pal.sensor_BACKEND + HEADERS + include/chre/pal/sensor.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.pal.system + chre.pal.version + chre.chre_api +) + +pw_add_library(chre.pal.system INTERFACE + HEADERS + include/chre/pal/system.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.chre_api +) + +pw_add_library(chre.pal.version INTERFACE + HEADERS + include/chre/pal/version.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.chre_api + chre.pal.version +) + +pw_add_facade(chre.pal.wifi INTERFACE + BACKEND + chre.pal.wifi_BACKEND + HEADERS + include/chre/pal/wifi.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.pal.system + chre.pal.version + chre.chre_api +) + +pw_add_facade(chre.pal.wwan INTERFACE + BACKEND + chre.pal.wwan_BACKEND + HEADERS + include/chre/pal/wwan.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.pal.system + chre.pal.version + chre.chre_api +)
diff --git a/pal/backend.cmake b/pal/backend.cmake new file mode 100644 index 0000000..9a4c871 --- /dev/null +++ b/pal/backend.cmake
@@ -0,0 +1,21 @@ +include_guard(GLOBAL) + +include($ENV{PW_ROOT}/pw_build/pigweed.cmake) + +# Backend for chre.pal.audio. +pw_add_backend_variable(chre.pal.audio_BACKEND) + +# Backend for chre.pal.ble. +pw_add_backend_variable(chre.pal.ble_BACKEND) + +# Backend for chre.pal.gnss. +pw_add_backend_variable(chre.pal.gnss_BACKEND) + +# Backend for chre.pal.sensor. +pw_add_backend_variable(chre.pal.sensor_BACKEND) + +# Backend for chre.pal.wifi. +pw_add_backend_variable(chre.pal.wifi_BACKEND) + +# Backend for chre.pal.wwan. +pw_add_backend_variable(chre.pal.wwan_BACKEND)
diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt new file mode 100644 index 0000000..7f2d2a9 --- /dev/null +++ b/platform/CMakeLists.txt
@@ -0,0 +1,342 @@ +include($ENV{PW_ROOT}/pw_build/pigweed.cmake) +include(backend.cmake) + +add_subdirectory(arm) +add_subdirectory(freertos) +add_subdirectory(shared) + +pw_add_facade(chre.platform.assert INTERFACE + BACKEND + chre.platform.assert_BACKEND + HEADERS + include/chre/platform/assert.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.platform.log + chre.variant.config +) + +pw_add_facade(chre.platform.atomic INTERFACE + BACKEND + chre.platform.atomic_BACKEND + HEADERS + include/chre/platform/atomic.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util + chre.variant.config +) + +pw_add_facade(chre.platform.condition_variable INTERFACE + BACKEND + chre.platform.condition_variable_BACKEND + HEADERS + include/chre/platform/condition_variable.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.platform.mutex + chre.util + chre.variant.config +) + +pw_add_facade(chre.platform.context INTERFACE + BACKEND + chre.platform.context_BACKEND + HEADERS + include/chre/platform/context.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.variant.config +) + +pw_add_facade(chre.platform.fatal_error INTERFACE + BACKEND + chre.platform.fatal_error_BACKEND + HEADERS + include/chre/platform/fatal_error.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.platform.log + chre.variant.config +) + +pw_add_facade(chre.platform.host_link INTERFACE + BACKEND + chre.platform.host_link_BACKEND + HEADERS + include/chre/platform/host_link.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util + chre.variant.config +) + +pw_add_facade(chre.platform.log INTERFACE + BACKEND + chre.platform.log_BACKEND + HEADERS + include/chre/platform/log.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util + chre.variant.config +) + +pw_add_facade(chre.platform.memory INTERFACE + BACKEND + chre.platform.memory_BACKEND + HEADERS + include/chre/platform/memory.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.variant.config +) + +pw_add_facade(chre.platform.memory_manager INTERFACE + BACKEND + chre.platform.memory_manager_BACKEND + HEADERS + include/chre/platform/heap_block_header.h + include/chre/platform/memory_manager.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util + chre.core + chre.variant.config +) + +pw_add_facade(chre.platform.mutex INTERFACE + BACKEND + chre.platform.mutex_BACKEND + HEADERS + include/chre/platform/mutex.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util + chre.variant.config +) + +pw_add_facade(chre.platform.notifier INTERFACE + BACKEND + chre.platform.notifier_BACKEND + HEADERS + include/chre/platform/notifier.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util + chre.variant.config +) + +pw_add_facade(chre.platform.platform_audio INTERFACE + BACKEND + chre.platform.platform_audio_BACKEND + HEADERS + include/chre/platform/platform_audio.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util + chre.chre_api + chre.variant.config +) + +pw_add_facade(chre.platform.platform_ble INTERFACE + BACKEND + chre.platform.platform_ble_BACKEND + HEADERS + include/chre/platform/platform_ble.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util + chre.variant.config +) + +pw_add_facade(chre.platform.platform_debug_dump_manager INTERFACE + BACKEND + chre.platform.platform_debug_dump_manager_BACKEND + HEADERS + include/chre/platform/platform_debug_dump_manager.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util + chre.chre_api + chre.variant.config +) + +pw_add_facade(chre.platform.platform_gnss INTERFACE + BACKEND + chre.platform.platform_gnss_BACKEND + HEADERS + include/chre/platform/platform_gnss.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util + chre.variant.config +) + +pw_add_facade(chre.platform.platform_nanoapp INTERFACE + BACKEND + chre.platform.platform_nanoapp_BACKEND + HEADERS + include/chre/platform/platform_nanoapp.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util + chre.variant.config +) + +pw_add_facade(chre.platform.platform_sensor INTERFACE + BACKEND + chre.platform.platform_sensor_BACKEND + HEADERS + include/chre/platform/platform_sensor.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.core + chre.platform.fatal_error + chre.util + chre.variant.config +) + +pw_add_facade(chre.platform.platform_sensor_manager INTERFACE + BACKEND + chre.platform.platform_sensor_manager_BACKEND + HEADERS + include/chre/platform/platform_sensor_manager.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.core + chre.util + chre.variant.config +) + +pw_add_facade(chre.platform.platform_sensor_type_helpers INTERFACE + BACKEND + chre.platform.platform_sensor_type_helpers_BACKEND + HEADERS + include/chre/platform/platform_sensor_type_helpers.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.core + chre.variant.config +) + +pw_add_facade(chre.platform.platform_wifi INTERFACE + BACKEND + chre.platform.platform_wifi_BACKEND + HEADERS + include/chre/platform/platform_wifi.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.variant.config +) + +pw_add_facade(chre.platform.platform_wwan INTERFACE + BACKEND + chre.platform.platform_wwan_BACKEND + HEADERS + include/chre/platform/platform_wwan.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.variant.config +) + +pw_add_facade(chre.platform.power_control_manager INTERFACE + BACKEND + chre.platform.power_control_manager_BACKEND + HEADERS + include/chre/platform/power_control_manager.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util + chre.variant.config +) + +pw_add_facade(chre.platform.static_nanoapp_init INTERFACE + BACKEND + chre.platform.static_nanoapp_init_BACKEND + HEADERS + include/chre/platform/static_nanoapp_init.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.variant.config +) + +pw_add_facade(chre.platform.system_time INTERFACE + BACKEND + chre.platform.system_time_BACKEND + HEADERS + include/chre/platform/system_time.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util + chre.variant.config +) + +pw_add_facade(chre.platform.system_timer INTERFACE + BACKEND + chre.platform.system_timer_BACKEND + HEADERS + include/chre/platform/system_timer.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util + chre.variant.config +) + +pw_add_facade(chre.platform.thread_handle INTERFACE + BACKEND + chre.platform.thread_handle_BACKEND + HEADERS + include/chre/platform/thread_handle.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.variant.config +) + +pw_add_facade(chre.platform.tracing INTERFACE + BACKEND + chre.platform.tracing_BACKEND + HEADERS + include/chre/platform/tracing.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.variant.config +) + +pw_add_facade(chre.platform.version INTERFACE + BACKEND + chre.platform.version_BACKEND + HEADERS + include/chre/platform/version.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.variant.config +)
diff --git a/platform/arm/CMakeLists.txt b/platform/arm/CMakeLists.txt new file mode 100644 index 0000000..a7fda77 --- /dev/null +++ b/platform/arm/CMakeLists.txt
@@ -0,0 +1,8 @@ +include($ENV{PW_ROOT}/pw_build/pigweed.cmake) + +pw_add_library(chre.platform.arm.nanoapp_loader STATIC + SOURCES + nanoapp_loader.cc + PRIVATE_DEPS + chre.platform.shared.nanoapp_loader.facade +)
diff --git a/platform/backend.cmake b/platform/backend.cmake new file mode 100644 index 0000000..91d0712 --- /dev/null +++ b/platform/backend.cmake
@@ -0,0 +1,87 @@ +include_guard(GLOBAL) + +include($ENV{PW_ROOT}/pw_build/pigweed.cmake) + +# Backend for chre.platform.assert. +pw_add_backend_variable(chre.platform.assert_BACKEND) + +# Backend for chre.platform.atomic. +pw_add_backend_variable(chre.platform.atomic_BACKEND) + +# Backend for chre.platform.condition_variable. +pw_add_backend_variable(chre.platform.condition_variable_BACKEND) + +# Backend for chre.platform.context. +pw_add_backend_variable(chre.platform.context_BACKEND) + +# Backend for chre.platform.fatal_error. +pw_add_backend_variable(chre.platform.fatal_error_BACKEND) + +# Backend for chre.platform.host_link. +pw_add_backend_variable(chre.platform.host_link_BACKEND) + +# Backend for chre.platform.log. +pw_add_backend_variable(chre.platform.log_BACKEND) + +# Backend for chre.platform.memory. +pw_add_backend_variable(chre.platform.memory_BACKEND) + +# Backend for chre.platform.memory_manager. +pw_add_backend_variable(chre.platform.memory_manager_BACKEND) + +# Backend for chre.platform.mutex. +pw_add_backend_variable(chre.platform.mutex_BACKEND) + +# Backend for chre.platform.notifier. +pw_add_backend_variable(chre.platform.notifier_BACKEND) + +# Backend for chre.platform.platform_audio. +pw_add_backend_variable(chre.platform.platform_audio_BACKEND) + +# Backend for chre.platform.platform_ble. +pw_add_backend_variable(chre.platform.platform_ble_BACKEND) + +# Backend for chre.platform.platform_debug_dump_manager. +pw_add_backend_variable(chre.platform.platform_debug_dump_manager_BACKEND) + +# Backend for chre.platform.platform_gnss. +pw_add_backend_variable(chre.platform.platform_gnss_BACKEND) + +# Backend for chre.platform.platform_nanoapp. +pw_add_backend_variable(chre.platform.platform_nanoapp_BACKEND) + +# Backend for chre.platform.platform_sensor. +pw_add_backend_variable(chre.platform.platform_sensor_BACKEND) + +# Backend for chre.platform.platform_sensor_manager. +pw_add_backend_variable(chre.platform.platform_sensor_manager_BACKEND) + +# Backend for chre.platform.platform_sensor_type_helpers. +pw_add_backend_variable(chre.platform.platform_sensor_type_helpers_BACKEND) + +# Backend for chre.platform.platform_wifi. +pw_add_backend_variable(chre.platform.platform_wifi_BACKEND) + +# Backend for chre.platform.platform_wwan. +pw_add_backend_variable(chre.platform.platform_wwan_BACKEND) + +# Backend for chre.platform.power_control_manager. +pw_add_backend_variable(chre.platform.power_control_manager_BACKEND) + +# Backend for chre.platform.static_nanoapp_init. +pw_add_backend_variable(chre.platform.static_nanoapp_init_BACKEND) + +# Backend for chre.platform.system_time. +pw_add_backend_variable(chre.platform.system_time_BACKEND) + +# Backend for chre.platform.system_timer. +pw_add_backend_variable(chre.platform.system_timer_BACKEND) + +# Backend for chre.platform.thread_handle. +pw_add_backend_variable(chre.platform.thread_handle_BACKEND) + +# Backend for chre.platform.tracing. +pw_add_backend_variable(chre.platform.tracing_BACKEND) + +# Backend for chre.platform.version. +pw_add_backend_variable(chre.platform.version_BACKEND)
diff --git a/platform/exynos/host_link.cc b/platform/exynos/host_link.cc index 92629f2..5dfa7ce 100644 --- a/platform/exynos/host_link.cc +++ b/platform/exynos/host_link.cc
@@ -221,4 +221,14 @@ LOGE("NAN unsupported."); } +void HostMessageHandlers::handleBtSocketOpen( + uint16_t /* hostClientId */, uint64_t /* socketId */, + const char * /* name */, uint64_t /* endpointId */, uint64_t /* hubId */, + uint32_t /* aclConnectionHandle */, uint32_t /* localCid */, + uint32_t /* remoteCid */, uint32_t /* psm */, uint32_t /* localMtu */, + uint32_t /* remoteMtu */, uint32_t /* localMps */, uint32_t /* remoteMps */, + uint32_t /* initialRxCredits */, uint32_t /* initialTxCredits */) { + LOGE("BT Socket offload not supported"); +} + } // namespace chre
diff --git a/platform/exynos/platform_cache_management.cc b/platform/exynos/platform_cache_management.cc index 975fe79..7f3a65c 100644 --- a/platform/exynos/platform_cache_management.cc +++ b/platform/exynos/platform_cache_management.cc
@@ -14,7 +14,7 @@ * limitations under the License. */ -#include "chre/target_platform/platform_cache_management.h" +#include "chre/platform/shared/platform_cache_management.h" namespace chre {
diff --git a/platform/freertos/CMakeLists.txt b/platform/freertos/CMakeLists.txt new file mode 100644 index 0000000..ab464ee --- /dev/null +++ b/platform/freertos/CMakeLists.txt
@@ -0,0 +1,25 @@ +include($ENV{PW_ROOT}/pw_build/pigweed.cmake) + +pw_add_library(chre.platform.freertos.platform_nanoapp STATIC + HEADERS + public_platform_nanoapp/chre/target_platform/platform_nanoapp_base.h + PUBLIC_INCLUDES + public_platform_nanoapp + PUBLIC_DEPS + chre.platform.shared.memory + chre.platform.shared.nanoapp_support_lib_dso + SOURCES + platform_nanoapp.cc + PRIVATE_DEPS + chre.chre_api + chre.platform.assert + chre.platform.host_link + chre.platform.log + chre.platform.platform_nanoapp.facade + chre.platform.shared.authentication + chre.platform.shared.dlfcn + chre.platform.shared.nanoapp_dso_util + chre.platform.shared.nanoapp_loader + chre.util + chre.util.system +)
diff --git a/platform/freertos/include/chre/target_platform/init.h b/platform/freertos/include/chre/target_platform/init.h new file mode 120000 index 0000000..e90376d --- /dev/null +++ b/platform/freertos/include/chre/target_platform/init.h
@@ -0,0 +1 @@ +../../../public_init/chre/target_platform/init.h \ No newline at end of file
diff --git a/platform/freertos/include/chre/target_platform/mutex_base.h b/platform/freertos/include/chre/target_platform/mutex_base.h new file mode 120000 index 0000000..243ec1b --- /dev/null +++ b/platform/freertos/include/chre/target_platform/mutex_base.h
@@ -0,0 +1 @@ +../../../public_mutex/chre/target_platform/mutex_base.h \ No newline at end of file
diff --git a/platform/freertos/include/chre/target_platform/mutex_base_impl.h b/platform/freertos/include/chre/target_platform/mutex_base_impl.h new file mode 120000 index 0000000..8cb1b7a --- /dev/null +++ b/platform/freertos/include/chre/target_platform/mutex_base_impl.h
@@ -0,0 +1 @@ +../../../public_mutex/chre/target_platform/mutex_base_impl.h \ No newline at end of file
diff --git a/platform/freertos/include/chre/target_platform/platform_nanoapp_base.h b/platform/freertos/include/chre/target_platform/platform_nanoapp_base.h new file mode 120000 index 0000000..6628c23 --- /dev/null +++ b/platform/freertos/include/chre/target_platform/platform_nanoapp_base.h
@@ -0,0 +1 @@ +../../../public_platform_nanoapp/chre/target_platform/platform_nanoapp_base.h \ No newline at end of file
diff --git a/platform/freertos/include/chre/target_platform/static_nanoapp_init.h b/platform/freertos/include/chre/target_platform/static_nanoapp_init.h new file mode 120000 index 0000000..5302945 --- /dev/null +++ b/platform/freertos/include/chre/target_platform/static_nanoapp_init.h
@@ -0,0 +1 @@ +../../../public_static_nanoapp_init/chre/target_platform/static_nanoapp_init.h \ No newline at end of file
diff --git a/platform/freertos/include/chre/target_platform/init.h b/platform/freertos/public_init/chre/target_platform/init.h similarity index 100% rename from platform/freertos/include/chre/target_platform/init.h rename to platform/freertos/public_init/chre/target_platform/init.h
diff --git a/platform/freertos/include/chre/target_platform/mutex_base.h b/platform/freertos/public_mutex/chre/target_platform/mutex_base.h similarity index 100% rename from platform/freertos/include/chre/target_platform/mutex_base.h rename to platform/freertos/public_mutex/chre/target_platform/mutex_base.h
diff --git a/platform/freertos/include/chre/target_platform/mutex_base_impl.h b/platform/freertos/public_mutex/chre/target_platform/mutex_base_impl.h similarity index 100% rename from platform/freertos/include/chre/target_platform/mutex_base_impl.h rename to platform/freertos/public_mutex/chre/target_platform/mutex_base_impl.h
diff --git a/platform/freertos/include/chre/target_platform/platform_nanoapp_base.h b/platform/freertos/public_platform_nanoapp/chre/target_platform/platform_nanoapp_base.h similarity index 100% rename from platform/freertos/include/chre/target_platform/platform_nanoapp_base.h rename to platform/freertos/public_platform_nanoapp/chre/target_platform/platform_nanoapp_base.h
diff --git a/platform/freertos/include/chre/target_platform/static_nanoapp_init.h b/platform/freertos/public_static_nanoapp_init/chre/target_platform/static_nanoapp_init.h similarity index 100% rename from platform/freertos/include/chre/target_platform/static_nanoapp_init.h rename to platform/freertos/public_static_nanoapp_init/chre/target_platform/static_nanoapp_init.h
diff --git a/platform/include/chre/platform/event_loop_hooks.h b/platform/include/chre/platform/event_loop_hooks.h new file mode 100644 index 0000000..8756c79 --- /dev/null +++ b/platform/include/chre/platform/event_loop_hooks.h
@@ -0,0 +1,101 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CHRE_PLATFORM_EVENT_LOOP_HOOKS_H_ +#define CHRE_PLATFORM_EVENT_LOOP_HOOKS_H_ + +/** + * @file + * Include a platform-specific event-loop configuration header if it exists. + * This header can optionally override the default macros defined below. + * + * TODO(b/380327627): Move the conentents of this file to chre/variant/config.h + * once CHRE team migrates platforms to use the variant config pattern and + * they address b/376532038. + */ +#ifdef CHRE_PLATFORM_EVENT_LOOP_CONFIG_HEADER +#include CHRE_PLATFORM_EVENT_LOOP_CONFIG_HEADER +#endif // CHRE_PLATFORM_EVENT_LOOP_CONFIG_HEADER + +/** + * @param eventLoop Pointer to the current EventLoop instance that is used to + * deliver events to nanoapps. + * @param eventType Event type identifier, which implies the type of eventData + * @param eventData The data that failed to be posted + * @param freeCallback Function to invoke to when the event has been processed + * by all recipients; this must be safe to call immediately, to handle + * the case where CHRE is shutting down + * @param senderInstanceId The instance ID of the sender of this event + * @param targetInstanceId targetInstanceId The instance ID of the destination + * of this event + * @param targetGroupMask Mask used to limit the recipients that are + * registered to receive this event + * + * @since v1.11 + * @note FATAL_ERROR is called after this macro is executed + */ +#ifndef CHRE_HANDLE_FAILED_SYSTEM_EVENT_ENQUEUE +#define CHRE_HANDLE_FAILED_SYSTEM_EVENT_ENQUEUE( \ + eventLoop, eventType, eventData, freeCallback, senderInstanceId, \ + targetInstanceId, targetGroupMask) \ + do { \ + } while (0) +#endif // !CHRE_HANDLE_FAILED_SYSTEM_EVENT_ENQUEUE + +/** + * @param eventLoop Pointer to the current EventLoop instance that is used to + * deliver events to nanoapps. + * @param eventType Event type identifier, which implies the type of eventData + * @param eventData The data that failed to be posted + * @param callback Function to invoke from the context of the CHRE thread + * @param extraData Additional arbitrary data to provide to the callback + * + * @since v1.11 + * @note FATAL_ERROR is called after this macro is executed + */ +#ifndef CHRE_HANDLE_EVENT_QUEUE_FULL_DURING_SYSTEM_POST +#define CHRE_HANDLE_EVENT_QUEUE_FULL_DURING_SYSTEM_POST( \ + eventLoop, eventType, eventData, callback, extraData) \ + do { \ + } while (0) +#endif // !CHRE_HANDLE_EVENT_QUEUE_FULL_DURING_SYSTEM_POST + +/** + * @param eventLoop Pointer to the current EventLoop instance that is used to + * deliver events to nanoapps. + * @param eventType Event type identifier, which implies the type of eventData + * @param eventData The data that failed to be posted + * @param freeCallback Function to invoke to when the event has been processed + * by all recipients; this must be safe to call immediately, to handle + * the case where CHRE is shutting down + * @param senderInstanceId The instance ID of the sender of this event + * @param targetInstanceId targetInstanceId The instance ID of the destination + * of this event + * @param targetGroupMask Mask used to limit the recipients that are + * registered to receive this event + * + * @since v1.11 + * @note Upon return, the freeCallaback will be invoked if not nullptr. + */ +#ifndef CHRE_HANDLE_LOW_PRIORITY_ENQUEUE_FAILURE +#define CHRE_HANDLE_LOW_PRIORITY_ENQUEUE_FAILURE( \ + eventLoop, eventType, eventData, freeCallback, senderInstanceId, \ + targetInstanceId, targetGroupMask) \ + do { \ + } while (0) +#endif // !CHRE_HANDLE_LOW_PRIORITY_ENQUEUE_FAILURE + +#endif // CHRE_PLATFORM_EVENT_LOOP_HOOKS_H_
diff --git a/platform/include/chre/platform/host_link.h b/platform/include/chre/platform/host_link.h index 0d5b7b4..2bf5464 100644 --- a/platform/include/chre/platform/host_link.h +++ b/platform/include/chre/platform/host_link.h
@@ -93,4 +93,9 @@ } // namespace chre +/* The platform can optionally provide an inlined implementation */ +#if __has_include("chre/target_platform/host_link_impl.h") +#include "chre/target_platform/host_link_impl.h" +#endif // __has_include("chre/target_platform/host_link_impl.h") + #endif // CHRE_PLATFORM_HOST_LINK_H_
diff --git a/platform/include/chre/platform/memory_manager.h b/platform/include/chre/platform/memory_manager.h index 48c1881..e7906df 100644 --- a/platform/include/chre/platform/memory_manager.h +++ b/platform/include/chre/platform/memory_manager.h
@@ -21,9 +21,9 @@ #include <cstdint> #include "chre/core/nanoapp.h" +#include "chre/platform/heap_block_header.h" #include "chre/util/non_copyable.h" #include "chre/util/system/debug_dump.h" -#include "heap_block_header.h" // This default value can be overridden in the variant-specific makefile. #ifndef CHRE_MAX_ALLOCATION_BYTES @@ -140,4 +140,9 @@ } // namespace chre +/* The platform can optionally provide an inlined implementation */ +#if __has_include("chre/target_platform/memory_manager_impl.h") +#include "chre/target_platform/memory_manager_impl.h" +#endif // __has_include("chre/target_platform/memory_manager_impl.h") + #endif // CHRE_PLATFORM_MEMORY_MANAGER_H_
diff --git a/platform/include/chre/platform/platform_audio.h b/platform/include/chre/platform/platform_audio.h index 3f20115..353d6d9 100644 --- a/platform/include/chre/platform/platform_audio.h +++ b/platform/include/chre/platform/platform_audio.h
@@ -129,4 +129,9 @@ } // namespace chre +/* The platform can optionally provide an inlined implementation */ +#if __has_include("chre/target_platform/platform_audio_impl.h") +#include "chre/target_platform/platform_audio_impl.h" +#endif // __has_include("chre/target_platform/platform_audio_impl.h") + #endif // CHRE_PLATFORM_PLATFORM_AUDIO_H_
diff --git a/platform/include/chre/platform/platform_ble.h b/platform/include/chre/platform/platform_ble.h index fdb495f..8574b77 100644 --- a/platform/include/chre/platform/platform_ble.h +++ b/platform/include/chre/platform/platform_ble.h
@@ -120,4 +120,9 @@ } // namespace chre +/* The platform can optionally provide an inlined implementation */ +#if __has_include("chre/target_platform/platform_ble_impl.h") +#include "chre/target_platform/platform_ble_impl.h" +#endif // __has_include("chre/target_platform/platform_ble_impl.h") + #endif // CHRE_PLATFORM_PLATFORM_BLE_H_
diff --git a/platform/include/chre/platform/platform_debug_dump_manager.h b/platform/include/chre/platform/platform_debug_dump_manager.h index 89b2dce..3a665db 100644 --- a/platform/include/chre/platform/platform_debug_dump_manager.h +++ b/platform/include/chre/platform/platform_debug_dump_manager.h
@@ -66,4 +66,9 @@ } // namespace chre +/* The platform can optionally provide an inlined implementation */ +#if __has_include("chre/target_platform/platform_debug_dump_manager_impl.h") +#include "chre/target_platform/platform_debug_dump_manager_impl.h" +#endif // __has_include("chre/target_platform/platform_debug_dump_manager_impl.h") + #endif // CHRE_PLATFORM_PLATFORM_DEBUG_DUMP_MANAGER_H_
diff --git a/platform/include/chre/platform/platform_gnss.h b/platform/include/chre/platform/platform_gnss.h index c922f5e..2bc7cfb 100644 --- a/platform/include/chre/platform/platform_gnss.h +++ b/platform/include/chre/platform/platform_gnss.h
@@ -95,4 +95,9 @@ } // namespace chre +/* The platform can optionally provide an inlined implementation */ +#if __has_include("chre/target_platform/platform_gnss_impl.h") +#include "chre/target_platform/platform_gnss_impl.h" +#endif // __has_include("chre/target_platform/platform_gnss_impl.h") + #endif // CHRE_PLATFORM_PLATFORM_GNSS_H_
diff --git a/platform/include/chre/platform/platform_nanoapp.h b/platform/include/chre/platform/platform_nanoapp.h index 817226c..7d9e736 100644 --- a/platform/include/chre/platform/platform_nanoapp.h +++ b/platform/include/chre/platform/platform_nanoapp.h
@@ -135,4 +135,9 @@ } // namespace chre +/* The platform can optionally provide an inlined implementation */ +#if __has_include("chre/target_platform/platform_nanoapp_impl.h") +#include "chre/target_platform/platform_nanoapp_impl.h" +#endif // __has_include("chre/target_platform/platform_nanoapp_impl.h") + #endif // CHRE_PLATFORM_PLATFORM_NANOAPP_H_
diff --git a/platform/include/chre/platform/platform_sensor.h b/platform/include/chre/platform/platform_sensor.h index 277afb5..fa0a75d 100644 --- a/platform/include/chre/platform/platform_sensor.h +++ b/platform/include/chre/platform/platform_sensor.h
@@ -92,4 +92,9 @@ } // namespace chre +/* The platform can optionally provide an inlined implementation */ +#if __has_include("chre/target_platform/platform_sensor_impl.h") +#include "chre/target_platform/platform_sensor_impl.h" +#endif // __has_include("chre/target_platform/platform_sensor_impl.h") + #endif // CHRE_PLATFORM_PLATFORM_SENSOR_H_
diff --git a/platform/include/chre/platform/platform_sensor_manager.h b/platform/include/chre/platform/platform_sensor_manager.h index ded9859..a3c0fb6 100644 --- a/platform/include/chre/platform/platform_sensor_manager.h +++ b/platform/include/chre/platform/platform_sensor_manager.h
@@ -18,7 +18,6 @@ #define CHRE_PLATFORM_PLATFORM_SENSOR_MANAGER_H_ #include "chre/core/sensor.h" -#include "chre/pal/sensor.h" #include "chre/target_platform/platform_sensor_manager_base.h" #include "chre/util/dynamic_vector.h" @@ -155,4 +154,9 @@ } // namespace chre +/* The platform can optionally provide an inlined implementation */ +#if __has_include("chre/target_platform/platform_sensor_manager_impl.h") +#include "chre/target_platform/platform_sensor_manager_impl.h" +#endif // __has_include("chre/target_platform/platform_sensor_manager_impl.h") + #endif // CHRE_PLATFORM_PLATFORM_SENSOR_MANAGER_H_
diff --git a/platform/include/chre/platform/platform_sensor_type_helpers.h b/platform/include/chre/platform/platform_sensor_type_helpers.h index a396897..7afb88b 100644 --- a/platform/include/chre/platform/platform_sensor_type_helpers.h +++ b/platform/include/chre/platform/platform_sensor_type_helpers.h
@@ -79,4 +79,9 @@ } // namespace chre +/* The platform can optionally provide an inlined implementation */ +#if __has_include("chre/target_platform/platform_sensor_type_helpers_impl.h") +#include "chre/target_platform/platform_sensor_type_helpers_impl.h" +#endif // __has_include("chre/target_platform/platform_sensor_type_helpers_impl.h") + #endif // CHRE_PLATFORM_PLATFORM_SENSOR_TYPE_HELPERS_H_
diff --git a/platform/include/chre/platform/platform_wifi.h b/platform/include/chre/platform/platform_wifi.h index fc7a545..1692575 100644 --- a/platform/include/chre/platform/platform_wifi.h +++ b/platform/include/chre/platform/platform_wifi.h
@@ -129,4 +129,9 @@ } // namespace chre +/* The platform can optionally provide an inlined implementation */ +#if __has_include("chre/target_platform/platform_wifi_impl.h") +#include "chre/target_platform/platform_wifi_impl.h" +#endif // __has_include("chre/target_platform/platform_wifi_impl.h") + #endif // CHRE_PLATFORM_PLATFORM_WIFI_H_
diff --git a/platform/include/chre/platform/platform_wwan.h b/platform/include/chre/platform/platform_wwan.h index bed6449..e22ad55 100644 --- a/platform/include/chre/platform/platform_wwan.h +++ b/platform/include/chre/platform/platform_wwan.h
@@ -64,4 +64,9 @@ } // namespace chre +/* The platform can optionally provide an inlined implementation */ +#if __has_include("chre/target_platform/platform_wwan_impl.h") +#include "chre/target_platform/platform_wwan_impl.h" +#endif // __has_include("chre/target_platform/platform_wwan_impl.h") + #endif // CHRE_PLATFORM_PLATFORM_WWAN_H_
diff --git a/platform/include/chre/platform/power_control_manager.h b/platform/include/chre/platform/power_control_manager.h index 6b3566b..963718c 100644 --- a/platform/include/chre/platform/power_control_manager.h +++ b/platform/include/chre/platform/power_control_manager.h
@@ -52,4 +52,9 @@ } // namespace chre +/* The platform can optionally provide an inlined implementation */ +#if __has_include("chre/target_platform/power_control_manager_impl.h") +#include "chre/target_platform/power_control_manager_impl.h" +#endif // __has_include("chre/target_platform/power_control_manager_impl.h") + #endif // CHRE_PLATFORM_POWER_CONTROL_MANAGER_H
diff --git a/platform/include/chre/platform/system_time.h b/platform/include/chre/platform/system_time.h index ac58e50..a25bd02 100644 --- a/platform/include/chre/platform/system_time.h +++ b/platform/include/chre/platform/system_time.h
@@ -66,4 +66,9 @@ } // namespace chre +/* The platform can optionally provide an inlined implementation */ +#if __has_include("chre/target_platform/system_time_impl.h") +#include "chre/target_platform/system_time_impl.h" +#endif // __has_include("chre/target_platform/system_time_impl.h") + #endif // CHRE_PLATFORM_TIME_H_
diff --git a/platform/include/chre/platform/system_timer.h b/platform/include/chre/platform/system_timer.h index 08160d2..7a4e459 100644 --- a/platform/include/chre/platform/system_timer.h +++ b/platform/include/chre/platform/system_timer.h
@@ -107,4 +107,9 @@ } // namespace chre +/* The platform can optionally provide an inlined implementation */ +#if __has_include("chre/target_platform/system_timer_impl.h") +#include "chre/target_platform/system_timer_impl.h" +#endif // __has_include("chre/target_platform/system_timer_impl.h") + #endif // CHRE_PLATFORM_SYSTEM_TIMER_H_
diff --git a/platform/platform.mk b/platform/platform.mk index 8e16753..8dd0d61 100644 --- a/platform/platform.mk +++ b/platform/platform.mk
@@ -193,6 +193,11 @@ # Simulator-specific Compiler Flags ############################################ SIM_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/include +SIM_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/public_platform_ble_pal +SIM_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/public_platform_debug_dump_manager +SIM_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/public_platform_gnss_pal +SIM_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/public_platform_wifi_pal +SIM_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/public_platform_wwan_pal SIM_CFLAGS += -Iplatform/linux/sim/include # Simulator-specific Source Files ############################################## @@ -342,6 +347,11 @@ # The order here is important so that the googletest target prefers shared, # linux and then SLPI. GOOGLETEST_CFLAGS += -Iplatform/shared/include +GOOGLETEST_CFLAGS += -Iplatform/shared/public_platform_ble_pal +GOOGLETEST_CFLAGS += -Iplatform/shared/public_platform_debug_dump_manager +GOOGLETEST_CFLAGS += -Iplatform/shared/public_platform_gnss_pal +GOOGLETEST_CFLAGS += -Iplatform/shared/public_platform_wifi_pal +GOOGLETEST_CFLAGS += -Iplatform/shared/public_platform_wwan_pal GOOGLETEST_CFLAGS += -Iplatform/linux/include GOOGLETEST_CFLAGS += -Iplatform/slpi/include GOOGLETEST_CFLAGS += -Iplatform/shared/pw_trace/include @@ -513,6 +523,14 @@ TINYSYS_SRCS += $(CHRE_PREFIX)/platform/shared/platform_gnss.cc endif +ifeq ($(CHRE_WIFI_SUPPORT_ENABLED), true) +TINYSYS_SRCS += platform/shared/platform_wifi.cc +endif + +ifeq ($(CHRE_WWAN_SUPPORT_ENABLED), true) +TINYSYS_SRCS += platform/shared/platform_wwan.cc +endif + # Compiler flags # Variables @@ -523,6 +541,11 @@ TINYSYS_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/aligned_alloc_unsupported/include TINYSYS_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/include TINYSYS_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/nanoapp/include +TINYSYS_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/public_platform_ble_pal +TINYSYS_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/public_platform_debug_dump_manager +TINYSYS_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/public_platform_gnss_pal +TINYSYS_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/public_platform_wifi_pal +TINYSYS_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/public_platform_wwan_pal TINYSYS_CFLAGS += -I$(CHRE_PREFIX)/platform/shared/include/chre/platform/shared/libc TINYSYS_CFLAGS += -I$(CHRE_PREFIX)/platform/tinysys/include
diff --git a/platform/shared/CMakeLists.txt b/platform/shared/CMakeLists.txt new file mode 100644 index 0000000..f6beab8 --- /dev/null +++ b/platform/shared/CMakeLists.txt
@@ -0,0 +1,644 @@ +include($ENV{PW_ROOT}/pw_build/pigweed.cmake) +include(backend.cmake) + +pw_add_facade(chre.platform.shared.authentication INTERFACE + BACKEND + chre.platform.shared.authentication_BACKEND + HEADERS + include/chre/platform/shared/authentication.h + PUBLIC_INCLUDES + include +) + +pw_add_facade(chre.platform.shared.bt_snoop_log INTERFACE + BACKEND + chre.platform.shared.bt_snoop_log_BACKEND + HEADERS + include/chre/platform/shared/bt_snoop_log.h + PUBLIC_INCLUDES + include +) + +# Implements chre_api/chre/audio.h's: +# - bool chreAudioGetSource(uint32_t handle, +# struct chreAudioSource *audioSource) +# - bool chreAudioConfigureSource(uint32_t handle, bool enable, +# uint64_t bufferDuration, +# uint64_t deliveryInterval) +# - bool chreAudioGetStatus(uint32_t handle, +# struct chreAudioSourceStatus *status) +# +pw_add_library(chre.platform.shared.chre_api_audio STATIC + SOURCES + chre_api_audio.cc + PRIVATE_DEPS + chre.chre_api.facade + chre.platform.platform_audio + chre.util + chre.util.system +) +# Implements chre_api/chre/ble.h's: +# - uint32_t chreBleGetCapabilities() +# - uint32_t chreBleGetFilterCapabilities() +# - bool chreBleFlushAsync(const void *cookie) +# - bool chreBleStartScanAsync(chreBleScanMode mode, +# uint32_t reportDelayMs, +# const struct chreBleScanFilter *filter) +# - bool chreBleStartScanAsyncV1_9(enum chreBleScanMode mode, +# uint32_t reportDelayMs, +# const struct chreBleScanFilterV1_9 *filter, +# const void *cookie) +# - bool chreBleStopScanAsync() +# - bool chreBleStopScanAsyncV1_9(const void *cookie) +# - bool chreBleReadRssiAsync(uint16_t connectionHandle, +# const void *cookie) +# - bool chreBleGetScanStatus(struct chreBleScanStatus *status) +# +pw_add_library(chre.platform.shared.chre_api_ble STATIC + SOURCES + chre_api_ble.cc + PRIVATE_DEPS + chre.chre_api.facade + chre.core + chre.util + chre.util.system +) + +# Implements chre_api/chre/event.h's: +# - bool chreSendEvent(uint16_t eventType, void *eventData, +# chreEventCompleteFunction *freeCallback, +# uint32_t targetInstanceId) +# - bool chreSendMessageToHost(void *message, uint32_t messageSize, +# uint32_t messageType, +# chreMessageFreeFunction *freeCallback) +# - bool chreSendMessageToHostEndpoint( +# void *message, size_t messageSize, uint32_t messageType, +# uint16_t hostEndpoint, chreMessageFreeFunction *freeCallback) +# - bool chreSendMessageWithPermissions( +# void *message, size_t messageSize, uint32_t messageType, +# uint16_t hostEndpoint, uint32_t messagePermissions, +# chreMessageFreeFunction *freeCallback) +# - bool chreSendReliableMessageAsync( +# void *message, size_t messageSize, uint32_t messageType, +# uint16_t hostEndpoint, uint32_t messagePermissions, +# chreMessageFreeFunction *freeCallback, const void *cookie) +# - bool chreGetNanoappInfoByAppId(uint64_t appId, struct chreNanoappInfo *info) +# - bool chreGetNanoappInfoByInstanceId(uint32_t instanceId, +# struct chreNanoappInfo *info) +# - void chreConfigureNanoappInfoEvents(bool enable) +# - void chreConfigureHostSleepStateEvents(bool enable) +# - bool chreIsHostAwake() +# - void chreConfigureDebugDumpEvent(bool enable) +# - bool chreConfigureHostEndpointNotifications(uint16_t hostEndpointId, +# bool enable) +# - bool chrePublishRpcServices(struct chreNanoappRpcService *services, +# size_t numServices) +# - bool chreGetHostEndpointInfo(uint16_t hostEndpointId, +# struct chreHostEndpointInfo *info) +# +pw_add_library(chre.platform.shared.chre_api_core STATIC + SOURCES + chre_api_core.cc + PRIVATE_DEPS + chre.chre_api.facade + chre.core + chre.platform.log + chre.util + chre.util.system +) + +# Implements chre_api/chre/gnss.h's: +# - uint32_t chreGnssGetCapabilities() +# - bool chreGnssLocationSessionStartAsync( +# uint32_t minIntervalMs, uint32_t minTimeToNextFixMs, +# const void *cookie) +# - bool chreGnssLocationSessionStopAsync(const void *cookie) +# - bool chreGnssMeasurementSessionStartAsync( +# uint32_t minIntervalMs, const void *cookie) +# - bool chreGnssMeasurementSessionStopAsync(const void *cookie) +# - bool chreGnssConfigurePassiveLocationListener(bool enable) +# +pw_add_library(chre.platform.shared.chre_api_gnss STATIC + SOURCES + chre_api_gnss.cc + PRIVATE_DEPS + chre.chre_api.facade + chre.core + chre.util + chre.util.system +) + +# Implements chre_api/chre/re.h's: +# - uint32_t chreGetCapabilities() +# - uint32_t chreGetMessageToHostMaxSize() +# - uint64_t chreGetAppId(void) +# - uint32_t chreGetInstanceId(void) +# - uint64_t chreGetTime() +# - int64_t chreGetEstimatedHostTimeOffset() +# - uint32_t chreTimerSet(uint64_t duration, const void *cookie, bool oneShot) +# - bool chreTimerCancel(uint32_t timerId) +# - void chreAbort(uint32_t abortCode) +# - void* chreHeapAlloc(uint32_t bytes) +# - void chreHeapFree(void *ptr) +# - chreDebugDumpLog(const char *formatStr, ...) +# +# Also provides: +# - void platform_chreDebugDumpVaLog(const char *formatStr, va_list args) +# +# Does not provide: +# - void chreLog(enum chreLogLevel level, const char *formatStr, ...) +pw_add_library(chre.platform.shared.chre_api_re STATIC + HEADERS + include/chre/platform/shared/debug_dump.h + PUBLIC_INCLUDES + include + SOURCES + chre_api_re.cc + PRIVATE_DEPS + chre.chre_api.facade + chre.core + chre.platform.fatal_error + chre.util +) + +# Implements chre_api/chre/sensor.h's: +# - bool chreSensorFindDefault(uint8_t sensorType, uint32_t *handle) +# - bool chreSensorFind(uint8_t sensorType, uint8_t sensorIndex, +# uint32_t *handle) +# - bool chreGetSensorInfo(uint32_t sensorHandle, struct chreSensorInfo *info) +# - bool chreGetSensorSamplingStatus(uint32_t sensorHandle, +# struct chreSensorSamplingStatus *status) +# - bool chreSensorConfigure(uint32_t sensorHandle, +# enum chreSensorConfigureMode mode, +# uint64_t interval, uint64_t latency) +# - bool chreSensorConfigureBiasEvents(uint32_t sensorHandle, bool enable) +# - bool chreSensorGetThreeAxisBias(uint32_t sensorHandle, +# struct chreSensorThreeAxisData *bias) +# - bool chreSensorFlushAsync(uint32_t sensorHandle, const void *cookie) +# +pw_add_library(chre.platform.shared.chre_api_sensor STATIC + SOURCES + chre_api_sensor.cc + PRIVATE_DEPS + chre.chre_api.facade + chre.core + chre.util +) + +# Implements chre_api/chre/user_settings.h's: +# - int8_t chreUserSettingGetState(uint8_t setting) +# - void chreUserSettingConfigureEvents(uint8_t setting, bool enable) +# +pw_add_library(chre.platform.shared.chre_api_user_settings STATIC + SOURCES + chre_api_user_settings.cc + PRIVATE_DEPS + chre.chre_api.facade + chre.core + chre.util +) + +# Implements chre_api/chre/version.h's: +# - uint32_t chreGetApiVersion(void) +# - uint32_t chreGetVersion(void) +# - uint64_t chreGetPlatformId(void) +# +pw_add_library(chre.platform.shared.chre_api_version STATIC + SOURCES + chre_api_version.cc + PRIVATE_DEPS + chre.chre_api.facade + chre.core + chre.util +) + +# Implements chre_api/chre/wifi.h's: +# - uint32_t chreWifiGetCapabilities() +# - bool chreWifiNanGetCapabilities( +# struct chreWifiNanCapabilities *capabilities) +# - bool chreWifiConfigureScanMonitorAsync(bool enable, const void *cookie) +# - bool chreWifiRequestScanAsync(const struct chreWifiScanParams *params, +# const void *cookie) +# - bool chreWifiRequestRangingAsync( +# const struct chreWifiRangingParams *params, const void *cookie) +# - bool chreWifiNanSubscribe(struct chreWifiNanSubscribeConfig *config, +# const void *cookie) +# - bool chreWifiNanSubscribeCancel(uint32_t subscriptionId) +# - bool chreWifiNanRequestRangingAsync( +# const struct chreWifiNanRangingParams *params, const void *cookie) +# +pw_add_library(chre.platform.shared.chre_api_wifi STATIC + SOURCES + chre_api_wifi.cc + PRIVATE_DEPS + chre.chre_api.facade + chre.core + chre.util + chre.util.system +) + +# Implements chre_api/chre/wwan.h's: +# - uint32_t chreWwanGetCapabilities() +# - bool chreWwanGetCellInfoAsync(const void *cookie) +# +pw_add_library(chre.platform.shared.chre_api_wwan STATIC + SOURCES + chre_api_wwan.cc + PRIVATE_DEPS + chre.chre_api.facade + chre.core + chre.util + chre.util.system +) + +pw_add_library(chre.platform.shared.dlfcn STATIC + HEADERS + include/chre/platform/shared/libc/dlfcn.h + PUBLIC_INCLUDES + include/chre/platform/shared/libc + SOURCES + dlfcn.cc + PRIVATE_DEPS + chre.platform.assert + chre.platform.log + chre.platform.shared.nanoapp_loader + chre.util +) + +pw_add_library(chre.platform.shared.generated.host_messages_generated INTERFACE + HEADERS + include/chre/platform/shared/generated/host_messages_generated.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre_third_party.flatbuffers +) + +pw_add_library(chre.platform.shared.host_protocol_chre STATIC + HEADERS + include/chre/platform/shared/host_protocol_chre.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.core + chre.platform.shared.generated.host_messages_generated + chre.platform.shared.host_protocol_common + chre.util + chre.util.flatbuffers + chre.chre_api + chre_third_party.flatbuffers + SOURCES + host_protocol_chre.cc + host_link.cc + PRIVATE_DEPS + chre.core + chre.platform.log + chre.platform.shared.host_protocol_chre + chre.platform.shared.nanoapp_load_manager +) + +pw_add_library(chre.platform.shared.host_protocol_common STATIC + HEADERS + include/chre/platform/shared/host_protocol_common.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util.system + chre_third_party.flatbuffers + SOURCES + host_protocol_common.cc + PRIVATE_DEPS + chre.platform.shared.generated.host_messages_generated +) + +pw_add_library(chre.platform.shared.loader_util INTERFACE + HEADERS + include/chre/platform/shared/loader_util.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.variant.config +) + +pw_add_library(chre.platform.shared.log_buffer STATIC + HEADERS + include/chre/platform/shared/log_buffer.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.core + chre.platform.mutex + chre.platform.shared.bt_snoop_log + chre.platform.shared.generated.host_messages_generated + SOURCES + log_buffer.cc + PRIVATE_DEPS + chre.platform.assert + chre.util +) + +# This requires the backend to provide an implementation for: +# - void LogBufferManager::preSecondaryBufferUse() const +pw_add_facade(chre.platform.shared.log_buffer_manager STATIC + BACKEND + chre.platform.shared.log_buffer_manager_BACKEND + HEADERS + include/chre/platform/shared/log_buffer_manager.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.chre_api + chre.platform.assert + chre.platform.condition_variable + chre.platform.mutex + chre.platform.shared.bt_snoop_log.facade + chre.platform.shared.generated.host_messages_generated + chre.platform.shared.log_buffer + chre.util + SOURCES + log_buffer_manager.cc + PRIVATE_DEPS + chre.core + chre.platform.log + chre.util + pw_log_tokenized.config + pw_tokenizer +) + +pw_add_facade(chre.platform.shared.memory INTERFACE + BACKEND + chre.platform.shared.memory_BACKEND + HEADERS + include/chre/platform/shared/memory.h + PUBLIC_INCLUDES + include +) + +# Partial backend for chre.platform.memory_manger which implements: +# 1) void *MemoryManager::nanoappAlloc(Nanoapp *app, uint32_t bytes) +# 2) void MemoryManager::nanoappFree(Nanoapp *app, void *ptr) +# 3) uint32_t MemoryManager::nanoappFreeAll(Nanoapp *app) +# 4) void MemoryManager::logStateToBuffer(DebugDumpWrapper &debugDump) const +pw_add_library(chre.platform.shared.memory_manager STATIC + SOURCES + memory_manager.cc + PRIVATE_DEPS + chre.platform.assert + chre.platform.memory_manager.facade + chre.util.system +) + +pw_add_library(chre.platform.shared.nanoapp_dso_util STATIC + HEADERS + include/chre/platform/shared/nanoapp_dso_util.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.platform.shared.nanoapp_support_lib_dso + SOURCES + nanoapp/nanoapp_dso_util.cc + PRIVATE_DEPS + chre.platform.log +) + +# This is itself a facade for: +# 1) bool NanoappLoader::relocateTable(DynamicHeader *dyn, int tag) +# 2) bool NanoappLoader::resolveGot() +# 3) if CHREX_SYMBOL_EXTENSIONS is set, providing +# `const ExportedData chre::kVendorExportedData[]` via +# `chre/extensions/platform/symbol_list.h`. +pw_add_facade(chre.platform.shared.nanoapp_loader STATIC + BACKEND + chre.platform.shared.nanoapp_loader_BACKEND + HEADERS + include/chre/platform/shared/nanoapp_loader.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util + chre.platform.shared.loader_util + SOURCES + nanoapp_loader.cc + PRIVATE_DEPS + chre.chre_api + chre.platform.assert + chre.platform.fatal_error + chre.platform.shared.chre_api_re + chre.platform.shared.dlfcn + chre.platform.shared.memory + chre.platform.shared.nanoapp_tokenized_log + chre.platform.shared.platform_cache_management + chre.variant.config +) + +pw_add_library(chre.platform.shared.nanoapp_load_manager STATIC + HEADERS + include/chre/platform/shared/nanoapp_load_manager.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.core + chre.util + SOURCES + nanoapp_load_manager.cc +) + +# Note that this does NOT actually implement, which are only required for +# nanoapp builds: +# - const struct chreNslNanoappInfo *getChreNslDsoNanoappInfo() +# - bool chreNslDsoGetApi(uint32_t apiId, void **apiHandle) +pw_add_library(chre.platform.shared.nanoapp_support_lib_dso INTERFACE + HEADERS + include/chre/platform/shared/nanoapp_support_lib_dso.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.chre_api +) + +pw_add_library(chre.platform.shared.nanoapp_tokenized_log STATIC + HEADERS + nanoapp/include/chre/platform/shared/nanoapp/tokenized_log.h + PUBLIC_INCLUDES + nanoapp/include + PUBLIC_DEPS + chre.chre_api + SOURCES + tokenized_log.cc + PRIVATE_DEPS + chre.core + chre.platform.log + chre.platform.shared.log_buffer_manager + pw_log_tokenized.config + pw_tokenizer +) + +pw_add_library(chre.platform.shared.pal_audio_stub STATIC + SOURCES + pal_audio_stub.cc + PRIVATE_DEPS + chre.pal.audio.facade +) + +pw_add_library(chre.platform.shared.pal_ble_stub STATIC + SOURCES + pal_ble_stub.cc + PRIVATE_DEPS + chre.pal.ble.facade +) + +pw_add_library(chre.platform.shared.pal_gnss_stub STATIC + SOURCES + pal_gnss_stub.cc + PRIVATE_DEPS + chre.pal.gnss.facade +) + +pw_add_library(chre.platform.shared.pal_sensor_stub STATIC + SOURCES + pal_sensor_stub.cc + PRIVATE_DEPS + chre.pal.sensor.facade +) + +pw_add_facade(chre.platform.shared.pal_system_api STATIC + BACKEND + chre.platform.shared.pal_system_api_BACKEND + HEADERS + include/chre/platform/shared/pal_system_api.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.pal.system + SOURCES + pal_system_api.cc + PRIVATE_DEPS + chre.platform.log + chre.platform.memory + chre.platform.system_time +) + +pw_add_library(chre.platform.shared.pal_wifi_stub STATIC + SOURCES + pal_wifi_stub.cc + PRIVATE_DEPS + chre.pal.wifi.facade +) + +pw_add_library(chre.platform.shared.pal_wwan_stub STATIC + SOURCES + pal_wwan_stub.cc + PRIVATE_DEPS + chre.pal.wwan.facade +) + +pw_add_library(chre.platform.shared.platform_ble_pal STATIC + HEADERS + public_platform_ble_pal/chre/target_platform/platform_ble_base.h + PUBLIC_INCLUDES + public_platform_ble_pal + PUBLIC_DEPS + chre.pal.ble + chre.platform.shared.platform_pal + SOURCES + platform_ble.cc + PRIVATE_DEPS + chre.chre_api + chre.core + chre.platform.log + chre.platform.platform_ble.facade + chre.platform.shared.bt_snoop_log + chre.platform.shared.pal_system_api + chre.variant.config +) + +pw_add_facade(chre.platform.shared.platform_cache_management INTERFACE + BACKEND + chre.platform.shared.platform_cache_management_BACKEND + HEADERS + include/chre/platform/shared/platform_cache_management.h + PUBLIC_INCLUDES + include +) + +# The optional CHPP and ASH integration is not supported. +pw_add_library(chre.platform.shared.platform_debug_dump_manager STATIC + HEADERS + public_platform_debug_dump_manager/chre/target_platform/platform_debug_dump_manager_base.h + PUBLIC_INCLUDES + public_platform_debug_dump_manager + PUBLIC_DEPS + chre.variant.config + SOURCES + platform_debug_dump_manager.cc + PRIVATE_DEPS + chre.core + chre.platform.host_link + chre.platform.log + chre.platform.platform_debug_dump_manager.facade + chre.util +) + +pw_add_library(chre.platform.shared.platform_gnss_pal STATIC + HEADERS + public_platform_gnss_pal/chre/target_platform/platform_gnss_base.h + PUBLIC_INCLUDES + public_platform_gnss_pal + PUBLIC_DEPS + chre.pal.gnss + chre.platform.shared.platform_pal + SOURCES + platform_gnss.cc + PRIVATE_DEPS + chre.core + chre.platform.log + chre.platform.platform_gnss.facade + chre.platform.shared.pal_system_api + chre.variant.config +) + +pw_add_facade(chre.platform.shared.platform_pal INTERFACE + BACKEND + chre.platform.shared.platform_pal_BACKEND + HEADERS + include/chre/platform/shared/platform_pal.h + PUBLIC_INCLUDES + include +) + +pw_add_library(chre.platform.shared.platform_wifi_pal STATIC + HEADERS + public_platform_wifi_pal/chre/target_platform/platform_wifi_base.h + PUBLIC_INCLUDES + public_platform_wifi_pal + PUBLIC_DEPS + chre.pal.wifi + chre.platform.shared.platform_pal + SOURCES + platform_wifi.cc + PRIVATE_DEPS + chre.core + chre.platform.log + chre.platform.platform_wifi.facade + chre.platform.shared.pal_system_api + chre.util.system + chre.variant.config +) + +pw_add_library(chre.platform.shared.platform_wwan_pal STATIC + HEADERS + public_platform_wwan_pal/chre/target_platform/platform_wwan_base.h + PUBLIC_INCLUDES + public_platform_wwan_pal + PUBLIC_DEPS + chre.pal.wwan + chre.platform.shared.platform_pal + SOURCES + platform_wwan.cc + PRIVATE_DEPS + chre.core + chre.platform.log + chre.platform.platform_wwan.facade + chre.platform.shared.pal_system_api + chre.variant.config +)
diff --git a/platform/shared/backend.cmake b/platform/shared/backend.cmake new file mode 100644 index 0000000..5d436df --- /dev/null +++ b/platform/shared/backend.cmake
@@ -0,0 +1,27 @@ +include_guard(GLOBAL) + +include($ENV{PW_ROOT}/pw_build/pigweed.cmake) + +# Backend for chre.platform.shared.authentication. +pw_add_backend_variable(chre.platform.shared.authentication_BACKEND) + +# Backend for chre.platform.shared.bt_snoop_log. +pw_add_backend_variable(chre.platform.shared.bt_snoop_log_BACKEND) + +# Backend for chre.platform.shared.log_buffer_manager. +pw_add_backend_variable(chre.platform.shared.log_buffer_manager_BACKEND) + +# Backend for chre.platform.shared.memory. +pw_add_backend_variable(chre.platform.shared.memory_BACKEND) + +# Backend for chre.platform.shared.nanoapp_loader. +pw_add_backend_variable(chre.platform.shared.nanoapp_loader_BACKEND) + +# Backend for chre.platform.shared.platform_cache_management. +pw_add_backend_variable(chre.platform.shared.platform_cache_management_BACKEND) + +# Backend for chre.platform.shared.platform_pal. +pw_add_backend_variable(chre.platform.shared.platform_pal_BACKEND) + +# Backend for chre.platform.shared.pal_system_api. +pw_add_backend_variable(chre.platform.shared.pal_system_api_BACKEND)
diff --git a/platform/shared/chre_api_audio.cc b/platform/shared/chre_api_audio.cc index adad654..5cec25f 100644 --- a/platform/shared/chre_api_audio.cc +++ b/platform/shared/chre_api_audio.cc
@@ -20,10 +20,6 @@ #include "chre/util/macros.h" #include "chre/util/system/napp_permissions.h" -#ifdef CHRE_AUDIO_SUPPORT_ENABLED -#include "chre/platform/platform_audio.h" -#endif // CHRE_AUDIO_SUPPORT_ENABLED - using chre::EventLoopManager; using chre::EventLoopManagerSingleton; using chre::Nanoapp; @@ -65,3 +61,11 @@ return false; #endif // CHRE_AUDIO_SUPPORT_ENABLED } + +DLL_EXPORT bool chreAudioGetStatus(uint32_t handle, + struct chreAudioSourceStatus *status) { + // TODO(b/174590023): either implement or deprecate this API + UNUSED_VAR(handle); + UNUSED_VAR(status); + return false; +}
diff --git a/platform/shared/chre_api_ble.cc b/platform/shared/chre_api_ble.cc index ea40387..5b65ac1 100644 --- a/platform/shared/chre_api_ble.cc +++ b/platform/shared/chre_api_ble.cc
@@ -22,6 +22,7 @@ using chre::EventLoopManager; using chre::EventLoopManagerSingleton; +using chre::Nanoapp; using chre::NanoappPermissions; DLL_EXPORT uint32_t chreBleGetCapabilities() { @@ -46,7 +47,7 @@ DLL_EXPORT bool chreBleFlushAsync(const void *cookie) { #ifdef CHRE_BLE_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_BLE) && EventLoopManagerSingleton::get()->getBleRequestManager().flushAsync( nanoapp, cookie); @@ -60,7 +61,7 @@ chreBleScanMode mode, uint32_t reportDelayMs, const struct chreBleScanFilterV1_9 *filter, const void *cookie) { #ifdef CHRE_BLE_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_BLE) && EventLoopManagerSingleton::get() ->getBleRequestManager() @@ -91,7 +92,7 @@ DLL_EXPORT bool chreBleStopScanAsyncV1_9(const void *cookie) { #ifdef CHRE_BLE_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_BLE) && EventLoopManagerSingleton::get()->getBleRequestManager().stopScanAsync( nanoapp, cookie); @@ -108,7 +109,7 @@ DLL_EXPORT bool chreBleReadRssiAsync(uint16_t connectionHandle, const void *cookie) { #ifdef CHRE_BLE_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_BLE) && EventLoopManagerSingleton::get()->getBleRequestManager().readRssiAsync( nanoapp, connectionHandle, cookie); @@ -121,7 +122,7 @@ DLL_EXPORT bool chreBleGetScanStatus(struct chreBleScanStatus *status) { #ifdef CHRE_BLE_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_BLE) && EventLoopManagerSingleton::get()->getBleRequestManager().getScanStatus( status);
diff --git a/platform/shared/chre_api_core.cc b/platform/shared/chre_api_core.cc index 780308b..3b5d7db 100644 --- a/platform/shared/chre_api_core.cc +++ b/platform/shared/chre_api_core.cc
@@ -14,6 +14,8 @@ * limitations under the License. */ +#include "chre_api/chre/event.h" + #include <cstdarg> #include <cstdio> #include <cstring> @@ -21,19 +23,15 @@ #include "chre/core/event_loop_manager.h" #include "chre/core/host_comms_manager.h" #include "chre/core/host_endpoint_manager.h" -#include "chre/platform/fatal_error.h" #include "chre/platform/log.h" #include "chre/util/macros.h" #include "chre/util/system/napp_permissions.h" -#include "chre_api/chre/event.h" -#include "chre_api/chre/re.h" -using ::chre::EventLoop; -using ::chre::EventLoopManager; -using ::chre::EventLoopManagerSingleton; -using ::chre::handleNanoappAbort; -using ::chre::HostCommsManager; -using ::chre::Nanoapp; +using chre::EventLoop; +using chre::EventLoopManager; +using chre::EventLoopManagerSingleton; +using chre::HostCommsManager; +using chre::Nanoapp; namespace { @@ -80,19 +78,6 @@ } // namespace -DLL_EXPORT void chreAbort(uint32_t /* abortCode */) { - Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); - - // TODO: we should cleanly unload the nanoapp, release all of its resources, - // and send an abort notification to the host so as to localize the impact to - // the calling nanoapp - if (nanoapp == nullptr) { - FATAL_ERROR("chreAbort called in unknown context"); - } else { - handleNanoappAbort(*nanoapp); - } -} - DLL_EXPORT bool chreSendEvent(uint16_t eventType, void *eventData, chreEventCompleteFunction *freeCallback, uint32_t targetInstanceId) { @@ -183,12 +168,12 @@ } DLL_EXPORT void chreConfigureNanoappInfoEvents(bool enable) { - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); nanoapp->configureNanoappInfoEvents(enable); } DLL_EXPORT void chreConfigureHostSleepStateEvents(bool enable) { - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); nanoapp->configureHostSleepEvents(enable); } @@ -200,19 +185,19 @@ } DLL_EXPORT void chreConfigureDebugDumpEvent(bool enable) { - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); nanoapp->configureDebugDumpEvent(enable); } DLL_EXPORT bool chreConfigureHostEndpointNotifications(uint16_t hostEndpointId, bool enable) { - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->configureHostEndpointNotifications(hostEndpointId, enable); } DLL_EXPORT bool chrePublishRpcServices(struct chreNanoappRpcService *services, size_t numServices) { - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->publishRpcServices(services, numServices); }
diff --git a/platform/shared/chre_api_gnss.cc b/platform/shared/chre_api_gnss.cc index f1f7706..7e46bc2 100644 --- a/platform/shared/chre_api_gnss.cc +++ b/platform/shared/chre_api_gnss.cc
@@ -24,13 +24,12 @@ using chre::EventLoopManager; using chre::EventLoopManagerSingleton; using chre::Milliseconds; +using chre::Nanoapp; using chre::NanoappPermissions; DLL_EXPORT uint32_t chreGnssGetCapabilities() { #ifdef CHRE_GNSS_SUPPORT_ENABLED - return chre::EventLoopManagerSingleton::get() - ->getGnssManager() - .getCapabilities(); + return EventLoopManagerSingleton::get()->getGnssManager().getCapabilities(); #else return CHRE_GNSS_CAPABILITIES_NONE; #endif // CHRE_GNSS_SUPPORT_ENABLED @@ -41,9 +40,9 @@ [[maybe_unused]] uint32_t minTimeToNextFixMs, [[maybe_unused]] const void *cookie) { #ifdef CHRE_GNSS_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_GNSS) && - chre::EventLoopManagerSingleton::get() + EventLoopManagerSingleton::get() ->getGnssManager() .getLocationSession() .addRequest(nanoapp, Milliseconds(minIntervalMs), @@ -56,9 +55,9 @@ DLL_EXPORT bool chreGnssLocationSessionStopAsync( [[maybe_unused]] const void *cookie) { #ifdef CHRE_GNSS_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_GNSS) && - chre::EventLoopManagerSingleton::get() + EventLoopManagerSingleton::get() ->getGnssManager() .getLocationSession() .removeRequest(nanoapp, cookie); @@ -70,9 +69,9 @@ DLL_EXPORT bool chreGnssMeasurementSessionStartAsync( [[maybe_unused]] uint32_t minIntervalMs, [[maybe_unused]] const void *cookie) { #ifdef CHRE_GNSS_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_GNSS) && - chre::EventLoopManagerSingleton::get() + EventLoopManagerSingleton::get() ->getGnssManager() .getMeasurementSession() .addRequest(nanoapp, Milliseconds(minIntervalMs), @@ -85,9 +84,9 @@ DLL_EXPORT bool chreGnssMeasurementSessionStopAsync( [[maybe_unused]] const void *cookie) { #ifdef CHRE_GNSS_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_GNSS) && - chre::EventLoopManagerSingleton::get() + EventLoopManagerSingleton::get() ->getGnssManager() .getMeasurementSession() .removeRequest(nanoapp, cookie); @@ -99,9 +98,9 @@ DLL_EXPORT bool chreGnssConfigurePassiveLocationListener( [[maybe_unused]] bool enable) { #ifdef CHRE_GNSS_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_GNSS) && - chre::EventLoopManagerSingleton::get() + EventLoopManagerSingleton::get() ->getGnssManager() .configurePassiveLocationListener(nanoapp, enable); #else
diff --git a/platform/shared/chre_api_re.cc b/platform/shared/chre_api_re.cc index 11102ed..3d7c8fd 100644 --- a/platform/shared/chre_api_re.cc +++ b/platform/shared/chre_api_re.cc
@@ -14,17 +14,19 @@ * limitations under the License. */ +#include "chre_api/chre/re.h" + #include "chre/core/event_loop.h" #include "chre/core/event_loop_manager.h" -#include "chre/platform/assert.h" -#include "chre/platform/memory.h" +#include "chre/platform/fatal_error.h" #include "chre/platform/shared/debug_dump.h" #include "chre/platform/system_time.h" #include "chre/util/macros.h" -#include "chre_api/chre/re.h" using chre::EventLoopManager; using chre::EventLoopManagerSingleton; +using chre::handleNanoappAbort; +using chre::Nanoapp; DLL_EXPORT uint32_t chreGetCapabilities() { uint32_t capabilities = CHRE_CAPABILITIES_NONE; @@ -37,26 +39,27 @@ } DLL_EXPORT uint32_t chreGetMessageToHostMaxSize() { -#ifdef CHRE_RELIABLE_MESSAGE_SUPPORT_ENABLED - -#ifndef CHRE_LARGE_PAYLOAD_MAX_SIZE - static_assert(false, - "CHRE_LARGE_PAYLOAD_MAX_SIZE must be defined if " - "CHRE_RELIABLE_MESSAGE_SUPPORT_ENABLED is enabled"); -#else +#ifdef CHRE_LARGE_PAYLOAD_MAX_SIZE static_assert(CHRE_LARGE_PAYLOAD_MAX_SIZE >= CHRE_MESSAGE_TO_HOST_MAX_SIZE, "CHRE_LARGE_PAYLOAD_MAX_SIZE must be greater than or equal to " "CHRE_MESSAGE_TO_HOST_MAX_SIZE"); +#ifdef CHRE_RELIABLE_MESSAGE_SUPPORT_ENABLED static_assert(CHRE_LARGE_PAYLOAD_MAX_SIZE >= 32000, "CHRE_LARGE_PAYLOAD_MAX_SIZE must be greater than or equal to " "32000 when CHRE_RELIABLE_MESSAGE_SUPPORT_ENABLED is enabled"); - return CHRE_LARGE_PAYLOAD_MAX_SIZE; -#endif // CHRE_LARGE_PAYLOAD_MAX_SIZE +#endif + return CHRE_LARGE_PAYLOAD_MAX_SIZE; #else +#ifdef CHRE_RELIABLE_MESSAGE_SUPPORT_ENABLED + static_assert(false, + "CHRE_LARGE_PAYLOAD_MAX_SIZE must be defined if " + "CHRE_RELIABLE_MESSAGE_SUPPORT_ENABLED is enabled"); +#endif + return CHRE_MESSAGE_TO_HOST_MAX_SIZE; -#endif // CHRE_RELIABLE_MESSAGE_SUPPORT_ENABLED +#endif // CHRE_LARGE_PAYLOAD_MAX_SIZE } DLL_EXPORT uint64_t chreGetTime() { @@ -68,18 +71,18 @@ } DLL_EXPORT uint64_t chreGetAppId(void) { - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->getAppId(); } DLL_EXPORT uint32_t chreGetInstanceId(void) { - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->getInstanceId(); } DLL_EXPORT uint32_t chreTimerSet(uint64_t duration, const void *cookie, bool oneShot) { - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return EventLoopManagerSingleton::get() ->getEventLoop() .getTimerPool() @@ -87,32 +90,39 @@ } DLL_EXPORT bool chreTimerCancel(uint32_t timerId) { - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return EventLoopManagerSingleton::get() ->getEventLoop() .getTimerPool() .cancelNanoappTimer(nanoapp, timerId); } +DLL_EXPORT void chreAbort(uint32_t /* abortCode */) { + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + if (nanoapp == nullptr) { + FATAL_ERROR("chreAbort called in unknown context"); + } else { + handleNanoappAbort(*nanoapp); + } +} + DLL_EXPORT void *chreHeapAlloc(uint32_t bytes) { - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); - return chre::EventLoopManagerSingleton::get() - ->getMemoryManager() - .nanoappAlloc(nanoapp, bytes); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + return EventLoopManagerSingleton::get()->getMemoryManager().nanoappAlloc( + nanoapp, bytes); } DLL_EXPORT void chreHeapFree(void *ptr) { - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); - chre::EventLoopManagerSingleton::get()->getMemoryManager().nanoappFree( - nanoapp, ptr); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + EventLoopManagerSingleton::get()->getMemoryManager().nanoappFree(nanoapp, + ptr); } DLL_EXPORT void platform_chreDebugDumpVaLog(const char *formatStr, va_list args) { - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); - chre::EventLoopManagerSingleton::get() - ->getDebugDumpManager() - .appendNanoappLog(*nanoapp, formatStr, args); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + EventLoopManagerSingleton::get()->getDebugDumpManager().appendNanoappLog( + *nanoapp, formatStr, args); } DLL_EXPORT void chreDebugDumpLog(const char *formatStr, ...) {
diff --git a/platform/shared/chre_api_sensor.cc b/platform/shared/chre_api_sensor.cc index 9b7b434..6f5b408 100644 --- a/platform/shared/chre_api_sensor.cc +++ b/platform/shared/chre_api_sensor.cc
@@ -14,15 +14,16 @@ * limitations under the License. */ +#include "chre_api/chre/sensor.h" + #include "chre/core/event_loop_manager.h" #include "chre/core/sensor_request.h" -#include "chre/core/sensor_type_helpers.h" #include "chre/util/macros.h" #include "chre/util/time.h" -#include "chre_api/chre/sensor.h" using chre::EventLoopManager; using chre::EventLoopManagerSingleton; +using chre::Nanoapp; using chre::Nanoseconds; using chre::SensorMode; using chre::SensorRequest; @@ -36,7 +37,7 @@ DLL_EXPORT bool chreSensorFind(uint8_t sensorType, uint8_t sensorIndex, uint32_t *handle) { #if CHRE_SENSORS_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return EventLoopManagerSingleton::get() ->getSensorRequestManager() .getSensorHandleForNanoapp(sensorType, sensorIndex, *nanoapp, handle); @@ -53,7 +54,7 @@ #ifdef CHRE_SENSORS_SUPPORT_ENABLED CHRE_ASSERT(info); - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); bool success = false; if (info != nullptr) { @@ -92,7 +93,7 @@ enum chreSensorConfigureMode mode, uint64_t interval, uint64_t latency) { #ifdef CHRE_SENSORS_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); SensorMode sensorMode = getSensorModeFromEnum(mode); SensorRequest sensorRequest(nanoapp->getInstanceId(), sensorMode, Nanoseconds(interval), Nanoseconds(latency)); @@ -111,7 +112,7 @@ DLL_EXPORT bool chreSensorConfigureBiasEvents(uint32_t sensorHandle, bool enable) { #ifdef CHRE_SENSORS_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return EventLoopManagerSingleton::get() ->getSensorRequestManager() .configureBiasEvents(nanoapp, sensorHandle, enable); @@ -138,7 +139,7 @@ DLL_EXPORT bool chreSensorFlushAsync(uint32_t sensorHandle, const void *cookie) { #ifdef CHRE_SENSORS_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return EventLoopManagerSingleton::get()->getSensorRequestManager().flushAsync( nanoapp, sensorHandle, cookie); #else // CHRE_SENSORS_SUPPORT_ENABLED
diff --git a/platform/shared/chre_api_user_settings.cc b/platform/shared/chre_api_user_settings.cc index 8ebba49..79394e7 100644 --- a/platform/shared/chre_api_user_settings.cc +++ b/platform/shared/chre_api_user_settings.cc
@@ -21,11 +21,12 @@ #include "chre/util/macros.h" using chre::EventLoopManager; +using chre::EventLoopManagerSingleton; using chre::Nanoapp; using chre::Setting; DLL_EXPORT int8_t chreUserSettingGetState(uint8_t setting) { - return chre::EventLoopManagerSingleton::get() + return EventLoopManagerSingleton::get() ->getSettingManager() .getSettingStateAsInt8(setting); }
diff --git a/platform/shared/chre_api_wifi.cc b/platform/shared/chre_api_wifi.cc index 02b3785..8617100 100644 --- a/platform/shared/chre_api_wifi.cc +++ b/platform/shared/chre_api_wifi.cc
@@ -22,11 +22,12 @@ using chre::EventLoopManager; using chre::EventLoopManagerSingleton; +using chre::Nanoapp; using chre::NanoappPermissions; DLL_EXPORT uint32_t chreWifiGetCapabilities() { #ifdef CHRE_WIFI_SUPPORT_ENABLED - return chre::EventLoopManagerSingleton::get() + return EventLoopManagerSingleton::get() ->getWifiRequestManager() .getCapabilities(); #else @@ -37,7 +38,7 @@ DLL_EXPORT bool chreWifiConfigureScanMonitorAsync( [[maybe_unused]] bool enable, [[maybe_unused]] const void *cookie) { #ifdef CHRE_WIFI_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_WIFI) && EventLoopManagerSingleton::get() ->getWifiRequestManager() @@ -51,7 +52,7 @@ [[maybe_unused]] const struct chreWifiScanParams *params, [[maybe_unused]] const void *cookie) { #ifdef CHRE_WIFI_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_WIFI) && EventLoopManagerSingleton::get()->getWifiRequestManager().requestScan( nanoapp, params, cookie); @@ -64,7 +65,7 @@ [[maybe_unused]] const struct chreWifiRangingParams *params, [[maybe_unused]] const void *cookie) { #ifdef CHRE_WIFI_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_WIFI) && EventLoopManagerSingleton::get() ->getWifiRequestManager() @@ -79,7 +80,7 @@ [[maybe_unused]] struct chreWifiNanSubscribeConfig *config, [[maybe_unused]] const void *cookie) { #if defined(CHRE_WIFI_SUPPORT_ENABLED) && defined(CHRE_WIFI_NAN_SUPPORT_ENABLED) - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_WIFI) && EventLoopManagerSingleton::get()->getWifiRequestManager().nanSubscribe( nanoapp, config, cookie); @@ -91,7 +92,7 @@ DLL_EXPORT bool chreWifiNanSubscribeCancel( [[maybe_unused]] uint32_t subscriptionId) { #if defined(CHRE_WIFI_SUPPORT_ENABLED) && defined(CHRE_WIFI_NAN_SUPPORT_ENABLED) - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_WIFI) && EventLoopManagerSingleton::get() ->getWifiRequestManager() @@ -105,7 +106,7 @@ [[maybe_unused]] const struct chreWifiNanRangingParams *params, [[maybe_unused]] const void *cookie) { #if defined(CHRE_WIFI_SUPPORT_ENABLED) && defined(CHRE_WIFI_NAN_SUPPORT_ENABLED) - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_WIFI) && EventLoopManagerSingleton::get() ->getWifiRequestManager()
diff --git a/platform/shared/chre_api_wwan.cc b/platform/shared/chre_api_wwan.cc index aa47722..b7bb634 100644 --- a/platform/shared/chre_api_wwan.cc +++ b/platform/shared/chre_api_wwan.cc
@@ -22,11 +22,12 @@ using chre::EventLoopManager; using chre::EventLoopManagerSingleton; +using chre::Nanoapp; using chre::NanoappPermissions; DLL_EXPORT uint32_t chreWwanGetCapabilities() { #ifdef CHRE_WWAN_SUPPORT_ENABLED - return chre::EventLoopManagerSingleton::get() + return EventLoopManagerSingleton::get() ->getWwanRequestManager() .getCapabilities(); #else @@ -36,9 +37,9 @@ DLL_EXPORT bool chreWwanGetCellInfoAsync([[maybe_unused]] const void *cookie) { #ifdef CHRE_WWAN_SUPPORT_ENABLED - chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); + Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__); return nanoapp->permitPermissionUse(NanoappPermissions::CHRE_PERMS_WWAN) && - chre::EventLoopManagerSingleton::get() + EventLoopManagerSingleton::get() ->getWwanRequestManager() .requestCellInfo(nanoapp, cookie); #else
diff --git a/platform/shared/dlfcn.cc b/platform/shared/dlfcn.cc index 630b73c..d561676 100644 --- a/platform/shared/dlfcn.cc +++ b/platform/shared/dlfcn.cc
@@ -17,6 +17,7 @@ #include <dlfcn.h> #include "chre/platform/assert.h" +#include "chre/platform/log.h" #include "chre/platform/shared/nanoapp_loader.h" #include "chre/util/unique_ptr.h"
diff --git a/platform/shared/host_link.cc b/platform/shared/host_link.cc index 7a0c797..2eff593 100644 --- a/platform/shared/host_link.cc +++ b/platform/shared/host_link.cc
@@ -73,8 +73,13 @@ if (getLoadManager().hasPendingLoadTransaction()) { FragmentedLoadInfo info = getLoadManager().getTransactionInfo(); + LOGW("A pending load transaction already exists (clientId=%" PRIu16 + ", txnId=%" PRIu32 ", nextFragmentId=%" PRIu32 "). Overriding it", + info.hostClientId, info.transactionId, info.nextFragmentId); + // Send a failure response to host where nextFragmentId is either current + // or future to the host. sendFragmentResponse(info.hostClientId, info.transactionId, - 0 /* fragmentId */, false /* success */); + info.nextFragmentId, /* success= */ false); getLoadManager().markFailure(); }
diff --git a/platform/shared/host_protocol_chre.cc b/platform/shared/host_protocol_chre.cc index ca0c86b..6224135 100644 --- a/platform/shared/host_protocol_chre.cc +++ b/platform/shared/host_protocol_chre.cc
@@ -18,6 +18,7 @@ #include <inttypes.h> #include <string.h> +#include <cstdint> #include "chre/core/event_loop_manager.h" #include "chre/core/host_endpoint_manager.h" @@ -200,13 +201,53 @@ break; } + case fbs::ChreMessage::BtSocketOpen: { + const auto *btSocketOpen = + static_cast<const fbs::BtSocketOpen *>(container->message()); + if (btSocketOpen->channelInfo_type() != + fbs::ChannelInfo::LeCocChannelInfo) { + LOGW("Unexpected BT Socket Open Channel Info Type %" PRIu8, + static_cast<uint8_t>(btSocketOpen->channelInfo_type())); + } else { + const auto *leCocChannelInfo = + static_cast<const fbs::LeCocChannelInfo *>( + btSocketOpen->channelInfo()); + const char *name = getStringFromByteVector(btSocketOpen->name()); + HostMessageHandlers::handleBtSocketOpen( + hostClientId, static_cast<uint64_t>(btSocketOpen->socketId()), + name, static_cast<uint64_t>(btSocketOpen->endpointId()), + static_cast<uint64_t>(btSocketOpen->hubId()), + static_cast<uint32_t>(btSocketOpen->aclConnectionHandle()), + static_cast<uint32_t>(leCocChannelInfo->localCid()), + static_cast<uint32_t>(leCocChannelInfo->remoteCid()), + static_cast<uint32_t>(leCocChannelInfo->psm()), + static_cast<uint32_t>(leCocChannelInfo->localMtu()), + static_cast<uint32_t>(leCocChannelInfo->remoteMtu()), + static_cast<uint32_t>(leCocChannelInfo->localMps()), + static_cast<uint32_t>(leCocChannelInfo->remoteMps()), + static_cast<uint32_t>(leCocChannelInfo->initialRxCredits()), + static_cast<uint32_t>(leCocChannelInfo->initialTxCredits())); + success = true; + } + break; + } + + case fbs::ChreMessage::BtSocketCloseResponse: { + const auto *btSocketCloseResponse = + static_cast<const fbs::BtSocketCloseResponse *>( + container->message()); + LOGD("Received BT Socket close response for socketId=%" PRIu64, + btSocketCloseResponse->socketId()); + success = true; + break; + } + default: LOGW("Got invalid/unexpected message type %" PRIu8, static_cast<uint8_t>(container->message_type())); success = false; } } - return success; } @@ -383,6 +424,29 @@ finalize(builder, fbs::ChreMessage::NanConfigurationRequest, request.Union()); } +void HostProtocolChre::encodeBtSocketOpenResponse( + ChreFlatBufferBuilder &builder, uint16_t hostClientId, uint64_t socketId, + bool success, const char *reason) { + auto reasonOffset = addStringAsByteVector(builder, reason); + auto socketOpenResponse = fbs::CreateBtSocketOpenResponse( + builder, socketId, + success ? fbs::BtSocketOpenStatus::SUCCESS + : fbs::BtSocketOpenStatus::FAILURE, + reasonOffset); + finalize(builder, fbs::ChreMessage::BtSocketOpenResponse, + socketOpenResponse.Union(), hostClientId); +} + +void HostProtocolChre::encodeBtSocketClose(ChreFlatBufferBuilder &builder, + uint16_t hostClientId, + uint64_t socketId, + const char *reason) { + auto reasonOffset = addStringAsByteVector(builder, reason); + auto socketClose = fbs::CreateBtSocketClose(builder, socketId, reasonOffset); + finalize(builder, fbs::ChreMessage::BtSocketClose, socketClose.Union(), + hostClientId); +} + bool HostProtocolChre::getSettingFromFbs(fbs::Setting setting, Setting *chreSetting) { bool success = true;
diff --git a/platform/shared/idl/host_messages.fbs b/platform/shared/idl/host_messages.fbs index cabc3df..2b86db5 100644 --- a/platform/shared/idl/host_messages.fbs +++ b/platform/shared/idl/host_messages.fbs
@@ -484,6 +484,281 @@ table PulseRequest {} table PulseResponse {} +// LE L2CAP COC channel information. +table LeCocChannelInfo { + // Local Channel Identifier. + localCid:int; + + // Remote Channel Identifier. + remoteCid:int; + + // Protocol Service Multiplexer. + psm:int; + + // Maximum Transmission Unit (MTU, max Rx SDU size) that the local device + // will accept for packets received on this channel. + localMtu:int; + + // Maximum Transmission Unit (MTU, max Tx SDU size) that the remote device + // will accept for packets sent on this channel. + remoteMtu:int; + + // Maximum PDU Payload Size (MPS) that the local device will accept for + // packets received on this channel. + localMps:int; + + // Maximum PDU Payload Size (MPS) that the remote device will accept for + // packets sent on this channel. + remoteMps:int; + + // The amount of PDUs that the local device will accept from this channel. + initialRxCredits:int; + + // The amount of PDUs that the remote device will accept from this channel. + initialTxCredits:int; +} + +// Used to specify the channel information of different protocol. +union ChannelInfo { + LeCocChannelInfo +} + +// Request from the host to the offload domain to open a BT socket. +table BtSocketOpen { + // Unique identifier for this socket connection. This ID in the offload + // domain matches the ID used on the host side. It is valid only while the + // socket is connected. + socketId:long; + + // The name of the socket. Nominally a UTF-8 string, but note that we're not + // using the built-in "string" data type from FlatBuffers here, because the + // generated C++ uses std::string which is not well-supported in the offload + // domain. This applies for vendor and toolchain as well. + name:[byte]; + + // ACL connection handle for the socket. + aclConnectionHandle:int; + + // Channel information of the socket protocol. + channelInfo:ChannelInfo; + + // The ID of the Hub to which the end point belongs for hardware offload + // data path. + hubId:long; + + // The ID of the Hub endpoint for hardware offload data path. + endpointId:long; +} + +// Status of BT socket open request. +enum BtSocketOpenStatus : byte { + SUCCESS = 0, + FAILURE, +} + +// Callback from the offload domain to the host to acknowledge that a BT socket +// has been opened successfully or has failed to be opened. +table BtSocketOpenResponse { + // Unique identifier for this socket connection. + socketId:long; + + // Status indicating success or failure. + status:BtSocketOpenStatus; + + // Reason string of the operation failure for debugging purposes. + reason:[byte]; +} + +// Request from offload domain to host to close a BT socket. +table BtSocketClose { + // Unique identifier for this socket connection. + socketId:long; + + // Reason string for closing the socket for debugging purposes + reason:[byte]; +} + +// Host callback to acknowledge that a BT socket has been closed. +table BtSocketCloseResponse { + // Unique identifier for this socket connection. + socketId:long; +} + +table VendorHubInfo { + /// The name of the hub. Nominally a UTF-8 string, but note that we're not + /// using the built-in "string" data type from FlatBuffers here, because the + /// generated C++ uses std::string which is not well-supported in CHRE. + name:[byte]; + + /// Hub version + version:uint; + + /// Additional vendor-defined data + extended_info:[ubyte]; +} + +union MessageHubDetails { + HubInfoResponse, + VendorHubInfo, +} + +table MessageHub { + /// The hub id. -1 is reserved and 0 is invalid. 0x416e64726f696400 represents + /// the ContextHub service. + id:long; + + /// Details of the message hub. + details:MessageHubDetails; +} + +table RegisterMessageHub { + hub:MessageHub; +} + +table UnregisterMessageHub { + id:long; +} + +table EndpointId { + /// Id of the hub hosting the endpoint + hubId:long; + + /// The id of the endpoint scoped to the hub + id:long; +} + +/// An enum describing the type of an endpoint. +enum EndpointType : ubyte { + INVALID = 0, + /// The endpoint is part of the Android Framework + FRAMEWORK = 1, + /// The endpoint is an Android app + APP, + /// The endpoint is a native Android program + NATIVE, + /// The endpoint is a nanoapp + NANOAPP, + /// A generic, non-nanoapp endpoint + GENERIC, +} + +enum RpcFormat : ubyte { + /// Fully custom format + CUSTOM = 0, + /// Stable AIDL defined interface using Binder marshalling + AIDL, + /// Pigweed RPC defined interface using Protobuf marshalling + PW_RPC, +} + +table Service { + format:RpcFormat; + + /// Service descriptor. Nominally a UTF-8 string, but note that we're not + /// using the built-in "string" data type from FlatBuffers here, because the + /// generated C++ uses std::string which is not well-supported in CHRE. + descriptor:[byte]; + + /// Breaking changes should bump the major version. + major_version:uint; + /// Monotonically increasing minor version. + minor_version:uint; +} + +table EndpointInfo { + id:EndpointId; + type:EndpointType; + + /// Endpoing name. Nominally a UTF-8 string, but note that we're not using + /// the built-in "string" data type from FlatBuffers here, because the + /// generated C++ uses std::string which is not well-supported in CHRE. + name:[byte]; + version:uint; + + /// Values from CHRE_MESSAGE_PERMISSION_* + required_permissions:uint; + services:[Service]; +} + +table RegisterEndpoint { + endpoint:EndpointInfo; +} + +table UnregisterEndpoint { + endpoint:EndpointId; +} + +/// HAL->CHRE, indicates the HAL is coming up +table GetMessageHubsAndEndpointsRequest {} +table GetMessageHubsAndEndpointsResponse { + hubs:[MessageHub]; + endpoints:[EndpointInfo]; +} + +table OpenEndpointSessionRequest { + id:ushort; + fromEndpoint:EndpointId; + toEndpoint:EndpointId; + + /// If present, describes the service definition used over the session + serviceDescriptor:[byte]; +} + +table EndpointSessionOpened { + id:ushort; +} + +/// "Reason"s for stopping an endpoint or session over an endpoint. +enum Reason : ubyte { + /// Unspecified reason. + UNSPECIFIED = 0, + /// Out of memory. There's not enough memory to perform this operation. + OUT_OF_MEMORY, + /// Timeout. This operation timed out. + TIMEOUT, + /// Endpoint rejected this openEndpointSession request. + OPEN_ENDPOINT_SESSION_REQUEST_REJECTED, + /// Endpoint requested closeEndpointSession. + CLOSE_ENDPOINT_SESSION_REQUESTED, + /// Invalid endpoint. + ENDPOINT_INVALID, + /// Endpoint is now stopped. + ENDPOINT_GONE, + /// Endpoint crashed. + ENDPOINT_CRASHED, + /// Hub was reset or is resetting. + HUB_RESET, +} + +table EndpointSessionClosed { + id:ushort; + reason:Reason; +} + +table EndpointSessionMessage { + /// Id of session this message is being sent within + session_id:ushort; + + /// Type of the message, specific to the Session protocol + type:uint; + + /// Values from CHRE_MESSAGE_PERMISSION_*. Permissions required to read the + /// message. + permissions:uint; + data:[ubyte]; + + /// Bitmask of additional flags applied to the message: + /// - 0x1: Message delivery status required within 1s + flags:uint; + sequence_number:uint; +} + +table EndpointSessionMessageDeliveryStatus { + /// Id of session the message was sent within + session_id:ushort; + status:MessageDeliveryStatus; +} + /// A union that joins together all possible messages. Note that in FlatBuffers, /// unions have an implicit type union ChreMessage { @@ -538,6 +813,27 @@ NanoappTokenDatabaseInfo, MessageDeliveryStatus, + + BtSocketOpen, + BtSocketOpenResponse, + BtSocketClose, + BtSocketCloseResponse, + + GetMessageHubsAndEndpointsRequest, + GetMessageHubsAndEndpointsResponse, + + RegisterMessageHub, + UnregisterMessageHub, + + RegisterEndpoint, + UnregisterEndpoint, + + OpenEndpointSessionRequest, + EndpointSessionOpened, + EndpointSessionClosed, + + EndpointSessionMessage, + EndpointSessionMessageDeliveryStatus, } struct HostAddress {
diff --git a/platform/shared/include/chre/platform/shared/generated/host_messages_generated.h b/platform/shared/include/chre/platform/shared/generated/host_messages_generated.h index 86c6cbc..4101439 100644 --- a/platform/shared/include/chre/platform/shared/generated/host_messages_generated.h +++ b/platform/shared/include/chre/platform/shared/generated/host_messages_generated.h
@@ -111,6 +111,69 @@ struct PulseResponse; struct PulseResponseBuilder; +struct LeCocChannelInfo; +struct LeCocChannelInfoBuilder; + +struct BtSocketOpen; +struct BtSocketOpenBuilder; + +struct BtSocketOpenResponse; +struct BtSocketOpenResponseBuilder; + +struct BtSocketClose; +struct BtSocketCloseBuilder; + +struct BtSocketCloseResponse; +struct BtSocketCloseResponseBuilder; + +struct VendorHubInfo; +struct VendorHubInfoBuilder; + +struct MessageHub; +struct MessageHubBuilder; + +struct RegisterMessageHub; +struct RegisterMessageHubBuilder; + +struct UnregisterMessageHub; +struct UnregisterMessageHubBuilder; + +struct EndpointId; +struct EndpointIdBuilder; + +struct Service; +struct ServiceBuilder; + +struct EndpointInfo; +struct EndpointInfoBuilder; + +struct RegisterEndpoint; +struct RegisterEndpointBuilder; + +struct UnregisterEndpoint; +struct UnregisterEndpointBuilder; + +struct GetMessageHubsAndEndpointsRequest; +struct GetMessageHubsAndEndpointsRequestBuilder; + +struct GetMessageHubsAndEndpointsResponse; +struct GetMessageHubsAndEndpointsResponseBuilder; + +struct OpenEndpointSessionRequest; +struct OpenEndpointSessionRequestBuilder; + +struct EndpointSessionOpened; +struct EndpointSessionOpenedBuilder; + +struct EndpointSessionClosed; +struct EndpointSessionClosedBuilder; + +struct EndpointSessionMessage; +struct EndpointSessionMessageBuilder; + +struct EndpointSessionMessageDeliveryStatus; +struct EndpointSessionMessageDeliveryStatusBuilder; + struct HostAddress; struct MessageContainer; @@ -292,6 +355,270 @@ return EnumNamesBtSnoopDirection()[index]; } +enum class ChannelInfo : uint8_t { + NONE = 0, + LeCocChannelInfo = 1, + MIN = NONE, + MAX = LeCocChannelInfo +}; + +inline const ChannelInfo (&EnumValuesChannelInfo())[2] { + static const ChannelInfo values[] = { + ChannelInfo::NONE, + ChannelInfo::LeCocChannelInfo + }; + return values; +} + +inline const char * const *EnumNamesChannelInfo() { + static const char * const names[3] = { + "NONE", + "LeCocChannelInfo", + nullptr + }; + return names; +} + +inline const char *EnumNameChannelInfo(ChannelInfo e) { + if (flatbuffers::IsOutRange(e, ChannelInfo::NONE, ChannelInfo::LeCocChannelInfo)) return ""; + const size_t index = static_cast<size_t>(e); + return EnumNamesChannelInfo()[index]; +} + +template<typename T> struct ChannelInfoTraits { + static const ChannelInfo enum_value = ChannelInfo::NONE; +}; + +template<> struct ChannelInfoTraits<chre::fbs::LeCocChannelInfo> { + static const ChannelInfo enum_value = ChannelInfo::LeCocChannelInfo; +}; + +bool VerifyChannelInfo(flatbuffers::Verifier &verifier, const void *obj, ChannelInfo type); +bool VerifyChannelInfoVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types); + +enum class BtSocketOpenStatus : int8_t { + SUCCESS = 0, + FAILURE = 1, + MIN = SUCCESS, + MAX = FAILURE +}; + +inline const BtSocketOpenStatus (&EnumValuesBtSocketOpenStatus())[2] { + static const BtSocketOpenStatus values[] = { + BtSocketOpenStatus::SUCCESS, + BtSocketOpenStatus::FAILURE + }; + return values; +} + +inline const char * const *EnumNamesBtSocketOpenStatus() { + static const char * const names[3] = { + "SUCCESS", + "FAILURE", + nullptr + }; + return names; +} + +inline const char *EnumNameBtSocketOpenStatus(BtSocketOpenStatus e) { + if (flatbuffers::IsOutRange(e, BtSocketOpenStatus::SUCCESS, BtSocketOpenStatus::FAILURE)) return ""; + const size_t index = static_cast<size_t>(e); + return EnumNamesBtSocketOpenStatus()[index]; +} + +enum class MessageHubDetails : uint8_t { + NONE = 0, + HubInfoResponse = 1, + VendorHubInfo = 2, + MIN = NONE, + MAX = VendorHubInfo +}; + +inline const MessageHubDetails (&EnumValuesMessageHubDetails())[3] { + static const MessageHubDetails values[] = { + MessageHubDetails::NONE, + MessageHubDetails::HubInfoResponse, + MessageHubDetails::VendorHubInfo + }; + return values; +} + +inline const char * const *EnumNamesMessageHubDetails() { + static const char * const names[4] = { + "NONE", + "HubInfoResponse", + "VendorHubInfo", + nullptr + }; + return names; +} + +inline const char *EnumNameMessageHubDetails(MessageHubDetails e) { + if (flatbuffers::IsOutRange(e, MessageHubDetails::NONE, MessageHubDetails::VendorHubInfo)) return ""; + const size_t index = static_cast<size_t>(e); + return EnumNamesMessageHubDetails()[index]; +} + +template<typename T> struct MessageHubDetailsTraits { + static const MessageHubDetails enum_value = MessageHubDetails::NONE; +}; + +template<> struct MessageHubDetailsTraits<chre::fbs::HubInfoResponse> { + static const MessageHubDetails enum_value = MessageHubDetails::HubInfoResponse; +}; + +template<> struct MessageHubDetailsTraits<chre::fbs::VendorHubInfo> { + static const MessageHubDetails enum_value = MessageHubDetails::VendorHubInfo; +}; + +bool VerifyMessageHubDetails(flatbuffers::Verifier &verifier, const void *obj, MessageHubDetails type); +bool VerifyMessageHubDetailsVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types); + +/// An enum describing the type of an endpoint. +enum class EndpointType : uint8_t { + INVALID = 0, + /// The endpoint is part of the Android Framework + FRAMEWORK = 1, + /// The endpoint is an Android app + APP = 2, + /// The endpoint is a native Android program + NATIVE = 3, + /// The endpoint is a nanoapp + NANOAPP = 4, + /// A generic, non-nanoapp endpoint + GENERIC = 5, + MIN = INVALID, + MAX = GENERIC +}; + +inline const EndpointType (&EnumValuesEndpointType())[6] { + static const EndpointType values[] = { + EndpointType::INVALID, + EndpointType::FRAMEWORK, + EndpointType::APP, + EndpointType::NATIVE, + EndpointType::NANOAPP, + EndpointType::GENERIC + }; + return values; +} + +inline const char * const *EnumNamesEndpointType() { + static const char * const names[7] = { + "INVALID", + "FRAMEWORK", + "APP", + "NATIVE", + "NANOAPP", + "GENERIC", + nullptr + }; + return names; +} + +inline const char *EnumNameEndpointType(EndpointType e) { + if (flatbuffers::IsOutRange(e, EndpointType::INVALID, EndpointType::GENERIC)) return ""; + const size_t index = static_cast<size_t>(e); + return EnumNamesEndpointType()[index]; +} + +enum class RpcFormat : uint8_t { + /// Fully custom format + CUSTOM = 0, + /// Stable AIDL defined interface using Binder marshalling + AIDL = 1, + /// Pigweed RPC defined interface using Protobuf marshalling + PW_RPC = 2, + MIN = CUSTOM, + MAX = PW_RPC +}; + +inline const RpcFormat (&EnumValuesRpcFormat())[3] { + static const RpcFormat values[] = { + RpcFormat::CUSTOM, + RpcFormat::AIDL, + RpcFormat::PW_RPC + }; + return values; +} + +inline const char * const *EnumNamesRpcFormat() { + static const char * const names[4] = { + "CUSTOM", + "AIDL", + "PW_RPC", + nullptr + }; + return names; +} + +inline const char *EnumNameRpcFormat(RpcFormat e) { + if (flatbuffers::IsOutRange(e, RpcFormat::CUSTOM, RpcFormat::PW_RPC)) return ""; + const size_t index = static_cast<size_t>(e); + return EnumNamesRpcFormat()[index]; +} + +/// "Reason"s for stopping an endpoint or session over an endpoint. +enum class Reason : uint8_t { + /// Unspecified reason. + UNSPECIFIED = 0, + /// Out of memory. There's not enough memory to perform this operation. + OUT_OF_MEMORY = 1, + /// Timeout. This operation timed out. + TIMEOUT = 2, + /// Endpoint rejected this openEndpointSession request. + OPEN_ENDPOINT_SESSION_REQUEST_REJECTED = 3, + /// Endpoint requested closeEndpointSession. + CLOSE_ENDPOINT_SESSION_REQUESTED = 4, + /// Invalid endpoint. + ENDPOINT_INVALID = 5, + /// Endpoint is now stopped. + ENDPOINT_GONE = 6, + /// Endpoint crashed. + ENDPOINT_CRASHED = 7, + /// Hub was reset or is resetting. + HUB_RESET = 8, + MIN = UNSPECIFIED, + MAX = HUB_RESET +}; + +inline const Reason (&EnumValuesReason())[9] { + static const Reason values[] = { + Reason::UNSPECIFIED, + Reason::OUT_OF_MEMORY, + Reason::TIMEOUT, + Reason::OPEN_ENDPOINT_SESSION_REQUEST_REJECTED, + Reason::CLOSE_ENDPOINT_SESSION_REQUESTED, + Reason::ENDPOINT_INVALID, + Reason::ENDPOINT_GONE, + Reason::ENDPOINT_CRASHED, + Reason::HUB_RESET + }; + return values; +} + +inline const char * const *EnumNamesReason() { + static const char * const names[10] = { + "UNSPECIFIED", + "OUT_OF_MEMORY", + "TIMEOUT", + "OPEN_ENDPOINT_SESSION_REQUEST_REJECTED", + "CLOSE_ENDPOINT_SESSION_REQUESTED", + "ENDPOINT_INVALID", + "ENDPOINT_GONE", + "ENDPOINT_CRASHED", + "HUB_RESET", + nullptr + }; + return names; +} + +inline const char *EnumNameReason(Reason e) { + if (flatbuffers::IsOutRange(e, Reason::UNSPECIFIED, Reason::HUB_RESET)) return ""; + const size_t index = static_cast<size_t>(e); + return EnumNamesReason()[index]; +} + /// A union that joins together all possible messages. Note that in FlatBuffers, /// unions have an implicit type enum class ChreMessage : uint8_t { @@ -328,11 +655,26 @@ PulseResponse = 30, NanoappTokenDatabaseInfo = 31, MessageDeliveryStatus = 32, + BtSocketOpen = 33, + BtSocketOpenResponse = 34, + BtSocketClose = 35, + BtSocketCloseResponse = 36, + GetMessageHubsAndEndpointsRequest = 37, + GetMessageHubsAndEndpointsResponse = 38, + RegisterMessageHub = 39, + UnregisterMessageHub = 40, + RegisterEndpoint = 41, + UnregisterEndpoint = 42, + OpenEndpointSessionRequest = 43, + EndpointSessionOpened = 44, + EndpointSessionClosed = 45, + EndpointSessionMessage = 46, + EndpointSessionMessageDeliveryStatus = 47, MIN = NONE, - MAX = MessageDeliveryStatus + MAX = EndpointSessionMessageDeliveryStatus }; -inline const ChreMessage (&EnumValuesChreMessage())[33] { +inline const ChreMessage (&EnumValuesChreMessage())[48] { static const ChreMessage values[] = { ChreMessage::NONE, ChreMessage::NanoappMessage, @@ -366,13 +708,28 @@ ChreMessage::PulseRequest, ChreMessage::PulseResponse, ChreMessage::NanoappTokenDatabaseInfo, - ChreMessage::MessageDeliveryStatus + ChreMessage::MessageDeliveryStatus, + ChreMessage::BtSocketOpen, + ChreMessage::BtSocketOpenResponse, + ChreMessage::BtSocketClose, + ChreMessage::BtSocketCloseResponse, + ChreMessage::GetMessageHubsAndEndpointsRequest, + ChreMessage::GetMessageHubsAndEndpointsResponse, + ChreMessage::RegisterMessageHub, + ChreMessage::UnregisterMessageHub, + ChreMessage::RegisterEndpoint, + ChreMessage::UnregisterEndpoint, + ChreMessage::OpenEndpointSessionRequest, + ChreMessage::EndpointSessionOpened, + ChreMessage::EndpointSessionClosed, + ChreMessage::EndpointSessionMessage, + ChreMessage::EndpointSessionMessageDeliveryStatus }; return values; } inline const char * const *EnumNamesChreMessage() { - static const char * const names[34] = { + static const char * const names[49] = { "NONE", "NanoappMessage", "HubInfoRequest", @@ -406,13 +763,28 @@ "PulseResponse", "NanoappTokenDatabaseInfo", "MessageDeliveryStatus", + "BtSocketOpen", + "BtSocketOpenResponse", + "BtSocketClose", + "BtSocketCloseResponse", + "GetMessageHubsAndEndpointsRequest", + "GetMessageHubsAndEndpointsResponse", + "RegisterMessageHub", + "UnregisterMessageHub", + "RegisterEndpoint", + "UnregisterEndpoint", + "OpenEndpointSessionRequest", + "EndpointSessionOpened", + "EndpointSessionClosed", + "EndpointSessionMessage", + "EndpointSessionMessageDeliveryStatus", nullptr }; return names; } inline const char *EnumNameChreMessage(ChreMessage e) { - if (flatbuffers::IsOutRange(e, ChreMessage::NONE, ChreMessage::MessageDeliveryStatus)) return ""; + if (flatbuffers::IsOutRange(e, ChreMessage::NONE, ChreMessage::EndpointSessionMessageDeliveryStatus)) return ""; const size_t index = static_cast<size_t>(e); return EnumNamesChreMessage()[index]; } @@ -549,6 +921,66 @@ static const ChreMessage enum_value = ChreMessage::MessageDeliveryStatus; }; +template<> struct ChreMessageTraits<chre::fbs::BtSocketOpen> { + static const ChreMessage enum_value = ChreMessage::BtSocketOpen; +}; + +template<> struct ChreMessageTraits<chre::fbs::BtSocketOpenResponse> { + static const ChreMessage enum_value = ChreMessage::BtSocketOpenResponse; +}; + +template<> struct ChreMessageTraits<chre::fbs::BtSocketClose> { + static const ChreMessage enum_value = ChreMessage::BtSocketClose; +}; + +template<> struct ChreMessageTraits<chre::fbs::BtSocketCloseResponse> { + static const ChreMessage enum_value = ChreMessage::BtSocketCloseResponse; +}; + +template<> struct ChreMessageTraits<chre::fbs::GetMessageHubsAndEndpointsRequest> { + static const ChreMessage enum_value = ChreMessage::GetMessageHubsAndEndpointsRequest; +}; + +template<> struct ChreMessageTraits<chre::fbs::GetMessageHubsAndEndpointsResponse> { + static const ChreMessage enum_value = ChreMessage::GetMessageHubsAndEndpointsResponse; +}; + +template<> struct ChreMessageTraits<chre::fbs::RegisterMessageHub> { + static const ChreMessage enum_value = ChreMessage::RegisterMessageHub; +}; + +template<> struct ChreMessageTraits<chre::fbs::UnregisterMessageHub> { + static const ChreMessage enum_value = ChreMessage::UnregisterMessageHub; +}; + +template<> struct ChreMessageTraits<chre::fbs::RegisterEndpoint> { + static const ChreMessage enum_value = ChreMessage::RegisterEndpoint; +}; + +template<> struct ChreMessageTraits<chre::fbs::UnregisterEndpoint> { + static const ChreMessage enum_value = ChreMessage::UnregisterEndpoint; +}; + +template<> struct ChreMessageTraits<chre::fbs::OpenEndpointSessionRequest> { + static const ChreMessage enum_value = ChreMessage::OpenEndpointSessionRequest; +}; + +template<> struct ChreMessageTraits<chre::fbs::EndpointSessionOpened> { + static const ChreMessage enum_value = ChreMessage::EndpointSessionOpened; +}; + +template<> struct ChreMessageTraits<chre::fbs::EndpointSessionClosed> { + static const ChreMessage enum_value = ChreMessage::EndpointSessionClosed; +}; + +template<> struct ChreMessageTraits<chre::fbs::EndpointSessionMessage> { + static const ChreMessage enum_value = ChreMessage::EndpointSessionMessage; +}; + +template<> struct ChreMessageTraits<chre::fbs::EndpointSessionMessageDeliveryStatus> { + static const ChreMessage enum_value = ChreMessage::EndpointSessionMessageDeliveryStatus; +}; + bool VerifyChreMessage(flatbuffers::Verifier &verifier, const void *obj, ChreMessage type); bool VerifyChreMessageVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types); @@ -2787,6 +3219,1501 @@ return builder_.Finish(); } +struct LeCocChannelInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef LeCocChannelInfoBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_LOCALCID = 4, + VT_REMOTECID = 6, + VT_PSM = 8, + VT_LOCALMTU = 10, + VT_REMOTEMTU = 12, + VT_LOCALMPS = 14, + VT_REMOTEMPS = 16, + VT_INITIALRXCREDITS = 18, + VT_INITIALTXCREDITS = 20 + }; + int32_t localCid() const { + return GetField<int32_t>(VT_LOCALCID, 0); + } + int32_t remoteCid() const { + return GetField<int32_t>(VT_REMOTECID, 0); + } + int32_t psm() const { + return GetField<int32_t>(VT_PSM, 0); + } + int32_t localMtu() const { + return GetField<int32_t>(VT_LOCALMTU, 0); + } + int32_t remoteMtu() const { + return GetField<int32_t>(VT_REMOTEMTU, 0); + } + int32_t localMps() const { + return GetField<int32_t>(VT_LOCALMPS, 0); + } + int32_t remoteMps() const { + return GetField<int32_t>(VT_REMOTEMPS, 0); + } + int32_t initialRxCredits() const { + return GetField<int32_t>(VT_INITIALRXCREDITS, 0); + } + int32_t initialTxCredits() const { + return GetField<int32_t>(VT_INITIALTXCREDITS, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<int32_t>(verifier, VT_LOCALCID) && + VerifyField<int32_t>(verifier, VT_REMOTECID) && + VerifyField<int32_t>(verifier, VT_PSM) && + VerifyField<int32_t>(verifier, VT_LOCALMTU) && + VerifyField<int32_t>(verifier, VT_REMOTEMTU) && + VerifyField<int32_t>(verifier, VT_LOCALMPS) && + VerifyField<int32_t>(verifier, VT_REMOTEMPS) && + VerifyField<int32_t>(verifier, VT_INITIALRXCREDITS) && + VerifyField<int32_t>(verifier, VT_INITIALTXCREDITS) && + verifier.EndTable(); + } +}; + +struct LeCocChannelInfoBuilder { + typedef LeCocChannelInfo Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_localCid(int32_t localCid) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_LOCALCID, localCid, 0); + } + void add_remoteCid(int32_t remoteCid) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_REMOTECID, remoteCid, 0); + } + void add_psm(int32_t psm) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_PSM, psm, 0); + } + void add_localMtu(int32_t localMtu) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_LOCALMTU, localMtu, 0); + } + void add_remoteMtu(int32_t remoteMtu) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_REMOTEMTU, remoteMtu, 0); + } + void add_localMps(int32_t localMps) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_LOCALMPS, localMps, 0); + } + void add_remoteMps(int32_t remoteMps) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_REMOTEMPS, remoteMps, 0); + } + void add_initialRxCredits(int32_t initialRxCredits) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_INITIALRXCREDITS, initialRxCredits, 0); + } + void add_initialTxCredits(int32_t initialTxCredits) { + fbb_.AddElement<int32_t>(LeCocChannelInfo::VT_INITIALTXCREDITS, initialTxCredits, 0); + } + explicit LeCocChannelInfoBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + LeCocChannelInfoBuilder &operator=(const LeCocChannelInfoBuilder &); + flatbuffers::Offset<LeCocChannelInfo> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<LeCocChannelInfo>(end); + return o; + } +}; + +inline flatbuffers::Offset<LeCocChannelInfo> CreateLeCocChannelInfo( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t localCid = 0, + int32_t remoteCid = 0, + int32_t psm = 0, + int32_t localMtu = 0, + int32_t remoteMtu = 0, + int32_t localMps = 0, + int32_t remoteMps = 0, + int32_t initialRxCredits = 0, + int32_t initialTxCredits = 0) { + LeCocChannelInfoBuilder builder_(_fbb); + builder_.add_initialTxCredits(initialTxCredits); + builder_.add_initialRxCredits(initialRxCredits); + builder_.add_remoteMps(remoteMps); + builder_.add_localMps(localMps); + builder_.add_remoteMtu(remoteMtu); + builder_.add_localMtu(localMtu); + builder_.add_psm(psm); + builder_.add_remoteCid(remoteCid); + builder_.add_localCid(localCid); + return builder_.Finish(); +} + +struct BtSocketOpen FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef BtSocketOpenBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SOCKETID = 4, + VT_NAME = 6, + VT_ACLCONNECTIONHANDLE = 8, + VT_CHANNELINFO_TYPE = 10, + VT_CHANNELINFO = 12, + VT_HUBID = 14, + VT_ENDPOINTID = 16 + }; + int64_t socketId() const { + return GetField<int64_t>(VT_SOCKETID, 0); + } + const flatbuffers::Vector<int8_t> *name() const { + return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_NAME); + } + int32_t aclConnectionHandle() const { + return GetField<int32_t>(VT_ACLCONNECTIONHANDLE, 0); + } + chre::fbs::ChannelInfo channelInfo_type() const { + return static_cast<chre::fbs::ChannelInfo>(GetField<uint8_t>(VT_CHANNELINFO_TYPE, 0)); + } + const void *channelInfo() const { + return GetPointer<const void *>(VT_CHANNELINFO); + } + template<typename T> const T *channelInfo_as() const; + const chre::fbs::LeCocChannelInfo *channelInfo_as_LeCocChannelInfo() const { + return channelInfo_type() == chre::fbs::ChannelInfo::LeCocChannelInfo ? static_cast<const chre::fbs::LeCocChannelInfo *>(channelInfo()) : nullptr; + } + int64_t hubId() const { + return GetField<int64_t>(VT_HUBID, 0); + } + int64_t endpointId() const { + return GetField<int64_t>(VT_ENDPOINTID, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<int64_t>(verifier, VT_SOCKETID) && + VerifyOffset(verifier, VT_NAME) && + verifier.VerifyVector(name()) && + VerifyField<int32_t>(verifier, VT_ACLCONNECTIONHANDLE) && + VerifyField<uint8_t>(verifier, VT_CHANNELINFO_TYPE) && + VerifyOffset(verifier, VT_CHANNELINFO) && + VerifyChannelInfo(verifier, channelInfo(), channelInfo_type()) && + VerifyField<int64_t>(verifier, VT_HUBID) && + VerifyField<int64_t>(verifier, VT_ENDPOINTID) && + verifier.EndTable(); + } +}; + +template<> inline const chre::fbs::LeCocChannelInfo *BtSocketOpen::channelInfo_as<chre::fbs::LeCocChannelInfo>() const { + return channelInfo_as_LeCocChannelInfo(); +} + +struct BtSocketOpenBuilder { + typedef BtSocketOpen Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_socketId(int64_t socketId) { + fbb_.AddElement<int64_t>(BtSocketOpen::VT_SOCKETID, socketId, 0); + } + void add_name(flatbuffers::Offset<flatbuffers::Vector<int8_t>> name) { + fbb_.AddOffset(BtSocketOpen::VT_NAME, name); + } + void add_aclConnectionHandle(int32_t aclConnectionHandle) { + fbb_.AddElement<int32_t>(BtSocketOpen::VT_ACLCONNECTIONHANDLE, aclConnectionHandle, 0); + } + void add_channelInfo_type(chre::fbs::ChannelInfo channelInfo_type) { + fbb_.AddElement<uint8_t>(BtSocketOpen::VT_CHANNELINFO_TYPE, static_cast<uint8_t>(channelInfo_type), 0); + } + void add_channelInfo(flatbuffers::Offset<void> channelInfo) { + fbb_.AddOffset(BtSocketOpen::VT_CHANNELINFO, channelInfo); + } + void add_hubId(int64_t hubId) { + fbb_.AddElement<int64_t>(BtSocketOpen::VT_HUBID, hubId, 0); + } + void add_endpointId(int64_t endpointId) { + fbb_.AddElement<int64_t>(BtSocketOpen::VT_ENDPOINTID, endpointId, 0); + } + explicit BtSocketOpenBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + BtSocketOpenBuilder &operator=(const BtSocketOpenBuilder &); + flatbuffers::Offset<BtSocketOpen> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<BtSocketOpen>(end); + return o; + } +}; + +inline flatbuffers::Offset<BtSocketOpen> CreateBtSocketOpen( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t socketId = 0, + flatbuffers::Offset<flatbuffers::Vector<int8_t>> name = 0, + int32_t aclConnectionHandle = 0, + chre::fbs::ChannelInfo channelInfo_type = chre::fbs::ChannelInfo::NONE, + flatbuffers::Offset<void> channelInfo = 0, + int64_t hubId = 0, + int64_t endpointId = 0) { + BtSocketOpenBuilder builder_(_fbb); + builder_.add_endpointId(endpointId); + builder_.add_hubId(hubId); + builder_.add_socketId(socketId); + builder_.add_channelInfo(channelInfo); + builder_.add_aclConnectionHandle(aclConnectionHandle); + builder_.add_name(name); + builder_.add_channelInfo_type(channelInfo_type); + return builder_.Finish(); +} + +inline flatbuffers::Offset<BtSocketOpen> CreateBtSocketOpenDirect( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t socketId = 0, + const std::vector<int8_t> *name = nullptr, + int32_t aclConnectionHandle = 0, + chre::fbs::ChannelInfo channelInfo_type = chre::fbs::ChannelInfo::NONE, + flatbuffers::Offset<void> channelInfo = 0, + int64_t hubId = 0, + int64_t endpointId = 0) { + auto name__ = name ? _fbb.CreateVector<int8_t>(*name) : 0; + return chre::fbs::CreateBtSocketOpen( + _fbb, + socketId, + name__, + aclConnectionHandle, + channelInfo_type, + channelInfo, + hubId, + endpointId); +} + +struct BtSocketOpenResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef BtSocketOpenResponseBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SOCKETID = 4, + VT_STATUS = 6, + VT_REASON = 8 + }; + int64_t socketId() const { + return GetField<int64_t>(VT_SOCKETID, 0); + } + chre::fbs::BtSocketOpenStatus status() const { + return static_cast<chre::fbs::BtSocketOpenStatus>(GetField<int8_t>(VT_STATUS, 0)); + } + const flatbuffers::Vector<int8_t> *reason() const { + return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_REASON); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<int64_t>(verifier, VT_SOCKETID) && + VerifyField<int8_t>(verifier, VT_STATUS) && + VerifyOffset(verifier, VT_REASON) && + verifier.VerifyVector(reason()) && + verifier.EndTable(); + } +}; + +struct BtSocketOpenResponseBuilder { + typedef BtSocketOpenResponse Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_socketId(int64_t socketId) { + fbb_.AddElement<int64_t>(BtSocketOpenResponse::VT_SOCKETID, socketId, 0); + } + void add_status(chre::fbs::BtSocketOpenStatus status) { + fbb_.AddElement<int8_t>(BtSocketOpenResponse::VT_STATUS, static_cast<int8_t>(status), 0); + } + void add_reason(flatbuffers::Offset<flatbuffers::Vector<int8_t>> reason) { + fbb_.AddOffset(BtSocketOpenResponse::VT_REASON, reason); + } + explicit BtSocketOpenResponseBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + BtSocketOpenResponseBuilder &operator=(const BtSocketOpenResponseBuilder &); + flatbuffers::Offset<BtSocketOpenResponse> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<BtSocketOpenResponse>(end); + return o; + } +}; + +inline flatbuffers::Offset<BtSocketOpenResponse> CreateBtSocketOpenResponse( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t socketId = 0, + chre::fbs::BtSocketOpenStatus status = chre::fbs::BtSocketOpenStatus::SUCCESS, + flatbuffers::Offset<flatbuffers::Vector<int8_t>> reason = 0) { + BtSocketOpenResponseBuilder builder_(_fbb); + builder_.add_socketId(socketId); + builder_.add_reason(reason); + builder_.add_status(status); + return builder_.Finish(); +} + +inline flatbuffers::Offset<BtSocketOpenResponse> CreateBtSocketOpenResponseDirect( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t socketId = 0, + chre::fbs::BtSocketOpenStatus status = chre::fbs::BtSocketOpenStatus::SUCCESS, + const std::vector<int8_t> *reason = nullptr) { + auto reason__ = reason ? _fbb.CreateVector<int8_t>(*reason) : 0; + return chre::fbs::CreateBtSocketOpenResponse( + _fbb, + socketId, + status, + reason__); +} + +struct BtSocketClose FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef BtSocketCloseBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SOCKETID = 4, + VT_REASON = 6 + }; + int64_t socketId() const { + return GetField<int64_t>(VT_SOCKETID, 0); + } + const flatbuffers::Vector<int8_t> *reason() const { + return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_REASON); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<int64_t>(verifier, VT_SOCKETID) && + VerifyOffset(verifier, VT_REASON) && + verifier.VerifyVector(reason()) && + verifier.EndTable(); + } +}; + +struct BtSocketCloseBuilder { + typedef BtSocketClose Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_socketId(int64_t socketId) { + fbb_.AddElement<int64_t>(BtSocketClose::VT_SOCKETID, socketId, 0); + } + void add_reason(flatbuffers::Offset<flatbuffers::Vector<int8_t>> reason) { + fbb_.AddOffset(BtSocketClose::VT_REASON, reason); + } + explicit BtSocketCloseBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + BtSocketCloseBuilder &operator=(const BtSocketCloseBuilder &); + flatbuffers::Offset<BtSocketClose> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<BtSocketClose>(end); + return o; + } +}; + +inline flatbuffers::Offset<BtSocketClose> CreateBtSocketClose( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t socketId = 0, + flatbuffers::Offset<flatbuffers::Vector<int8_t>> reason = 0) { + BtSocketCloseBuilder builder_(_fbb); + builder_.add_socketId(socketId); + builder_.add_reason(reason); + return builder_.Finish(); +} + +inline flatbuffers::Offset<BtSocketClose> CreateBtSocketCloseDirect( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t socketId = 0, + const std::vector<int8_t> *reason = nullptr) { + auto reason__ = reason ? _fbb.CreateVector<int8_t>(*reason) : 0; + return chre::fbs::CreateBtSocketClose( + _fbb, + socketId, + reason__); +} + +struct BtSocketCloseResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef BtSocketCloseResponseBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SOCKETID = 4 + }; + int64_t socketId() const { + return GetField<int64_t>(VT_SOCKETID, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<int64_t>(verifier, VT_SOCKETID) && + verifier.EndTable(); + } +}; + +struct BtSocketCloseResponseBuilder { + typedef BtSocketCloseResponse Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_socketId(int64_t socketId) { + fbb_.AddElement<int64_t>(BtSocketCloseResponse::VT_SOCKETID, socketId, 0); + } + explicit BtSocketCloseResponseBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + BtSocketCloseResponseBuilder &operator=(const BtSocketCloseResponseBuilder &); + flatbuffers::Offset<BtSocketCloseResponse> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<BtSocketCloseResponse>(end); + return o; + } +}; + +inline flatbuffers::Offset<BtSocketCloseResponse> CreateBtSocketCloseResponse( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t socketId = 0) { + BtSocketCloseResponseBuilder builder_(_fbb); + builder_.add_socketId(socketId); + return builder_.Finish(); +} + +struct VendorHubInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef VendorHubInfoBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NAME = 4, + VT_VERSION = 6, + VT_EXTENDED_INFO = 8 + }; + /// The name of the hub. Nominally a UTF-8 string, but note that we're not + /// using the built-in "string" data type from FlatBuffers here, because the + /// generated C++ uses std::string which is not well-supported in CHRE. + const flatbuffers::Vector<int8_t> *name() const { + return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_NAME); + } + /// Hub version + uint32_t version() const { + return GetField<uint32_t>(VT_VERSION, 0); + } + /// Additional vendor-defined data + const flatbuffers::Vector<uint8_t> *extended_info() const { + return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_EXTENDED_INFO); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_NAME) && + verifier.VerifyVector(name()) && + VerifyField<uint32_t>(verifier, VT_VERSION) && + VerifyOffset(verifier, VT_EXTENDED_INFO) && + verifier.VerifyVector(extended_info()) && + verifier.EndTable(); + } +}; + +struct VendorHubInfoBuilder { + typedef VendorHubInfo Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_name(flatbuffers::Offset<flatbuffers::Vector<int8_t>> name) { + fbb_.AddOffset(VendorHubInfo::VT_NAME, name); + } + void add_version(uint32_t version) { + fbb_.AddElement<uint32_t>(VendorHubInfo::VT_VERSION, version, 0); + } + void add_extended_info(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> extended_info) { + fbb_.AddOffset(VendorHubInfo::VT_EXTENDED_INFO, extended_info); + } + explicit VendorHubInfoBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + VendorHubInfoBuilder &operator=(const VendorHubInfoBuilder &); + flatbuffers::Offset<VendorHubInfo> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<VendorHubInfo>(end); + return o; + } +}; + +inline flatbuffers::Offset<VendorHubInfo> CreateVendorHubInfo( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<flatbuffers::Vector<int8_t>> name = 0, + uint32_t version = 0, + flatbuffers::Offset<flatbuffers::Vector<uint8_t>> extended_info = 0) { + VendorHubInfoBuilder builder_(_fbb); + builder_.add_extended_info(extended_info); + builder_.add_version(version); + builder_.add_name(name); + return builder_.Finish(); +} + +inline flatbuffers::Offset<VendorHubInfo> CreateVendorHubInfoDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector<int8_t> *name = nullptr, + uint32_t version = 0, + const std::vector<uint8_t> *extended_info = nullptr) { + auto name__ = name ? _fbb.CreateVector<int8_t>(*name) : 0; + auto extended_info__ = extended_info ? _fbb.CreateVector<uint8_t>(*extended_info) : 0; + return chre::fbs::CreateVendorHubInfo( + _fbb, + name__, + version, + extended_info__); +} + +struct MessageHub FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef MessageHubBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ID = 4, + VT_DETAILS_TYPE = 6, + VT_DETAILS = 8 + }; + /// The hub id. -1 is reserved and 0 is invalid. 0x416e64726f696400 represents + /// the ContextHub service. + int64_t id() const { + return GetField<int64_t>(VT_ID, 0); + } + chre::fbs::MessageHubDetails details_type() const { + return static_cast<chre::fbs::MessageHubDetails>(GetField<uint8_t>(VT_DETAILS_TYPE, 0)); + } + /// Details of the message hub. + const void *details() const { + return GetPointer<const void *>(VT_DETAILS); + } + template<typename T> const T *details_as() const; + const chre::fbs::HubInfoResponse *details_as_HubInfoResponse() const { + return details_type() == chre::fbs::MessageHubDetails::HubInfoResponse ? static_cast<const chre::fbs::HubInfoResponse *>(details()) : nullptr; + } + const chre::fbs::VendorHubInfo *details_as_VendorHubInfo() const { + return details_type() == chre::fbs::MessageHubDetails::VendorHubInfo ? static_cast<const chre::fbs::VendorHubInfo *>(details()) : nullptr; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<int64_t>(verifier, VT_ID) && + VerifyField<uint8_t>(verifier, VT_DETAILS_TYPE) && + VerifyOffset(verifier, VT_DETAILS) && + VerifyMessageHubDetails(verifier, details(), details_type()) && + verifier.EndTable(); + } +}; + +template<> inline const chre::fbs::HubInfoResponse *MessageHub::details_as<chre::fbs::HubInfoResponse>() const { + return details_as_HubInfoResponse(); +} + +template<> inline const chre::fbs::VendorHubInfo *MessageHub::details_as<chre::fbs::VendorHubInfo>() const { + return details_as_VendorHubInfo(); +} + +struct MessageHubBuilder { + typedef MessageHub Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_id(int64_t id) { + fbb_.AddElement<int64_t>(MessageHub::VT_ID, id, 0); + } + void add_details_type(chre::fbs::MessageHubDetails details_type) { + fbb_.AddElement<uint8_t>(MessageHub::VT_DETAILS_TYPE, static_cast<uint8_t>(details_type), 0); + } + void add_details(flatbuffers::Offset<void> details) { + fbb_.AddOffset(MessageHub::VT_DETAILS, details); + } + explicit MessageHubBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + MessageHubBuilder &operator=(const MessageHubBuilder &); + flatbuffers::Offset<MessageHub> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<MessageHub>(end); + return o; + } +}; + +inline flatbuffers::Offset<MessageHub> CreateMessageHub( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t id = 0, + chre::fbs::MessageHubDetails details_type = chre::fbs::MessageHubDetails::NONE, + flatbuffers::Offset<void> details = 0) { + MessageHubBuilder builder_(_fbb); + builder_.add_id(id); + builder_.add_details(details); + builder_.add_details_type(details_type); + return builder_.Finish(); +} + +struct RegisterMessageHub FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RegisterMessageHubBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_HUB = 4 + }; + const chre::fbs::MessageHub *hub() const { + return GetPointer<const chre::fbs::MessageHub *>(VT_HUB); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_HUB) && + verifier.VerifyTable(hub()) && + verifier.EndTable(); + } +}; + +struct RegisterMessageHubBuilder { + typedef RegisterMessageHub Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_hub(flatbuffers::Offset<chre::fbs::MessageHub> hub) { + fbb_.AddOffset(RegisterMessageHub::VT_HUB, hub); + } + explicit RegisterMessageHubBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + RegisterMessageHubBuilder &operator=(const RegisterMessageHubBuilder &); + flatbuffers::Offset<RegisterMessageHub> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<RegisterMessageHub>(end); + return o; + } +}; + +inline flatbuffers::Offset<RegisterMessageHub> CreateRegisterMessageHub( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<chre::fbs::MessageHub> hub = 0) { + RegisterMessageHubBuilder builder_(_fbb); + builder_.add_hub(hub); + return builder_.Finish(); +} + +struct UnregisterMessageHub FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef UnregisterMessageHubBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ID = 4 + }; + int64_t id() const { + return GetField<int64_t>(VT_ID, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<int64_t>(verifier, VT_ID) && + verifier.EndTable(); + } +}; + +struct UnregisterMessageHubBuilder { + typedef UnregisterMessageHub Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_id(int64_t id) { + fbb_.AddElement<int64_t>(UnregisterMessageHub::VT_ID, id, 0); + } + explicit UnregisterMessageHubBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + UnregisterMessageHubBuilder &operator=(const UnregisterMessageHubBuilder &); + flatbuffers::Offset<UnregisterMessageHub> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<UnregisterMessageHub>(end); + return o; + } +}; + +inline flatbuffers::Offset<UnregisterMessageHub> CreateUnregisterMessageHub( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t id = 0) { + UnregisterMessageHubBuilder builder_(_fbb); + builder_.add_id(id); + return builder_.Finish(); +} + +struct EndpointId FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef EndpointIdBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_HUBID = 4, + VT_ID = 6 + }; + /// Id of the hub hosting the endpoint + int64_t hubId() const { + return GetField<int64_t>(VT_HUBID, 0); + } + /// The id of the endpoint scoped to the hub + int64_t id() const { + return GetField<int64_t>(VT_ID, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<int64_t>(verifier, VT_HUBID) && + VerifyField<int64_t>(verifier, VT_ID) && + verifier.EndTable(); + } +}; + +struct EndpointIdBuilder { + typedef EndpointId Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_hubId(int64_t hubId) { + fbb_.AddElement<int64_t>(EndpointId::VT_HUBID, hubId, 0); + } + void add_id(int64_t id) { + fbb_.AddElement<int64_t>(EndpointId::VT_ID, id, 0); + } + explicit EndpointIdBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + EndpointIdBuilder &operator=(const EndpointIdBuilder &); + flatbuffers::Offset<EndpointId> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<EndpointId>(end); + return o; + } +}; + +inline flatbuffers::Offset<EndpointId> CreateEndpointId( + flatbuffers::FlatBufferBuilder &_fbb, + int64_t hubId = 0, + int64_t id = 0) { + EndpointIdBuilder builder_(_fbb); + builder_.add_id(id); + builder_.add_hubId(hubId); + return builder_.Finish(); +} + +struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ServiceBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_FORMAT = 4, + VT_DESCRIPTOR = 6, + VT_MAJOR_VERSION = 8, + VT_MINOR_VERSION = 10 + }; + chre::fbs::RpcFormat format() const { + return static_cast<chre::fbs::RpcFormat>(GetField<uint8_t>(VT_FORMAT, 0)); + } + /// Service descriptor. Nominally a UTF-8 string, but note that we're not + /// using the built-in "string" data type from FlatBuffers here, because the + /// generated C++ uses std::string which is not well-supported in CHRE. + const flatbuffers::Vector<int8_t> *descriptor() const { + return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_DESCRIPTOR); + } + /// Breaking changes should bump the major version. + uint32_t major_version() const { + return GetField<uint32_t>(VT_MAJOR_VERSION, 0); + } + /// Monotonically increasing minor version. + uint32_t minor_version() const { + return GetField<uint32_t>(VT_MINOR_VERSION, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<uint8_t>(verifier, VT_FORMAT) && + VerifyOffset(verifier, VT_DESCRIPTOR) && + verifier.VerifyVector(descriptor()) && + VerifyField<uint32_t>(verifier, VT_MAJOR_VERSION) && + VerifyField<uint32_t>(verifier, VT_MINOR_VERSION) && + verifier.EndTable(); + } +}; + +struct ServiceBuilder { + typedef Service Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_format(chre::fbs::RpcFormat format) { + fbb_.AddElement<uint8_t>(Service::VT_FORMAT, static_cast<uint8_t>(format), 0); + } + void add_descriptor(flatbuffers::Offset<flatbuffers::Vector<int8_t>> descriptor) { + fbb_.AddOffset(Service::VT_DESCRIPTOR, descriptor); + } + void add_major_version(uint32_t major_version) { + fbb_.AddElement<uint32_t>(Service::VT_MAJOR_VERSION, major_version, 0); + } + void add_minor_version(uint32_t minor_version) { + fbb_.AddElement<uint32_t>(Service::VT_MINOR_VERSION, minor_version, 0); + } + explicit ServiceBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ServiceBuilder &operator=(const ServiceBuilder &); + flatbuffers::Offset<Service> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<Service>(end); + return o; + } +}; + +inline flatbuffers::Offset<Service> CreateService( + flatbuffers::FlatBufferBuilder &_fbb, + chre::fbs::RpcFormat format = chre::fbs::RpcFormat::CUSTOM, + flatbuffers::Offset<flatbuffers::Vector<int8_t>> descriptor = 0, + uint32_t major_version = 0, + uint32_t minor_version = 0) { + ServiceBuilder builder_(_fbb); + builder_.add_minor_version(minor_version); + builder_.add_major_version(major_version); + builder_.add_descriptor(descriptor); + builder_.add_format(format); + return builder_.Finish(); +} + +inline flatbuffers::Offset<Service> CreateServiceDirect( + flatbuffers::FlatBufferBuilder &_fbb, + chre::fbs::RpcFormat format = chre::fbs::RpcFormat::CUSTOM, + const std::vector<int8_t> *descriptor = nullptr, + uint32_t major_version = 0, + uint32_t minor_version = 0) { + auto descriptor__ = descriptor ? _fbb.CreateVector<int8_t>(*descriptor) : 0; + return chre::fbs::CreateService( + _fbb, + format, + descriptor__, + major_version, + minor_version); +} + +struct EndpointInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef EndpointInfoBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ID = 4, + VT_TYPE = 6, + VT_NAME = 8, + VT_VERSION = 10, + VT_REQUIRED_PERMISSIONS = 12, + VT_SERVICES = 14 + }; + const chre::fbs::EndpointId *id() const { + return GetPointer<const chre::fbs::EndpointId *>(VT_ID); + } + chre::fbs::EndpointType type() const { + return static_cast<chre::fbs::EndpointType>(GetField<uint8_t>(VT_TYPE, 0)); + } + /// Endpoing name. Nominally a UTF-8 string, but note that we're not using + /// the built-in "string" data type from FlatBuffers here, because the + /// generated C++ uses std::string which is not well-supported in CHRE. + const flatbuffers::Vector<int8_t> *name() const { + return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_NAME); + } + uint32_t version() const { + return GetField<uint32_t>(VT_VERSION, 0); + } + /// Values from CHRE_MESSAGE_PERMISSION_* + uint32_t required_permissions() const { + return GetField<uint32_t>(VT_REQUIRED_PERMISSIONS, 0); + } + const flatbuffers::Vector<flatbuffers::Offset<chre::fbs::Service>> *services() const { + return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<chre::fbs::Service>> *>(VT_SERVICES); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_ID) && + verifier.VerifyTable(id()) && + VerifyField<uint8_t>(verifier, VT_TYPE) && + VerifyOffset(verifier, VT_NAME) && + verifier.VerifyVector(name()) && + VerifyField<uint32_t>(verifier, VT_VERSION) && + VerifyField<uint32_t>(verifier, VT_REQUIRED_PERMISSIONS) && + VerifyOffset(verifier, VT_SERVICES) && + verifier.VerifyVector(services()) && + verifier.VerifyVectorOfTables(services()) && + verifier.EndTable(); + } +}; + +struct EndpointInfoBuilder { + typedef EndpointInfo Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_id(flatbuffers::Offset<chre::fbs::EndpointId> id) { + fbb_.AddOffset(EndpointInfo::VT_ID, id); + } + void add_type(chre::fbs::EndpointType type) { + fbb_.AddElement<uint8_t>(EndpointInfo::VT_TYPE, static_cast<uint8_t>(type), 0); + } + void add_name(flatbuffers::Offset<flatbuffers::Vector<int8_t>> name) { + fbb_.AddOffset(EndpointInfo::VT_NAME, name); + } + void add_version(uint32_t version) { + fbb_.AddElement<uint32_t>(EndpointInfo::VT_VERSION, version, 0); + } + void add_required_permissions(uint32_t required_permissions) { + fbb_.AddElement<uint32_t>(EndpointInfo::VT_REQUIRED_PERMISSIONS, required_permissions, 0); + } + void add_services(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<chre::fbs::Service>>> services) { + fbb_.AddOffset(EndpointInfo::VT_SERVICES, services); + } + explicit EndpointInfoBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + EndpointInfoBuilder &operator=(const EndpointInfoBuilder &); + flatbuffers::Offset<EndpointInfo> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<EndpointInfo>(end); + return o; + } +}; + +inline flatbuffers::Offset<EndpointInfo> CreateEndpointInfo( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<chre::fbs::EndpointId> id = 0, + chre::fbs::EndpointType type = chre::fbs::EndpointType::INVALID, + flatbuffers::Offset<flatbuffers::Vector<int8_t>> name = 0, + uint32_t version = 0, + uint32_t required_permissions = 0, + flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<chre::fbs::Service>>> services = 0) { + EndpointInfoBuilder builder_(_fbb); + builder_.add_services(services); + builder_.add_required_permissions(required_permissions); + builder_.add_version(version); + builder_.add_name(name); + builder_.add_id(id); + builder_.add_type(type); + return builder_.Finish(); +} + +inline flatbuffers::Offset<EndpointInfo> CreateEndpointInfoDirect( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<chre::fbs::EndpointId> id = 0, + chre::fbs::EndpointType type = chre::fbs::EndpointType::INVALID, + const std::vector<int8_t> *name = nullptr, + uint32_t version = 0, + uint32_t required_permissions = 0, + const std::vector<flatbuffers::Offset<chre::fbs::Service>> *services = nullptr) { + auto name__ = name ? _fbb.CreateVector<int8_t>(*name) : 0; + auto services__ = services ? _fbb.CreateVector<flatbuffers::Offset<chre::fbs::Service>>(*services) : 0; + return chre::fbs::CreateEndpointInfo( + _fbb, + id, + type, + name__, + version, + required_permissions, + services__); +} + +struct RegisterEndpoint FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RegisterEndpointBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ENDPOINT = 4 + }; + const chre::fbs::EndpointInfo *endpoint() const { + return GetPointer<const chre::fbs::EndpointInfo *>(VT_ENDPOINT); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_ENDPOINT) && + verifier.VerifyTable(endpoint()) && + verifier.EndTable(); + } +}; + +struct RegisterEndpointBuilder { + typedef RegisterEndpoint Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_endpoint(flatbuffers::Offset<chre::fbs::EndpointInfo> endpoint) { + fbb_.AddOffset(RegisterEndpoint::VT_ENDPOINT, endpoint); + } + explicit RegisterEndpointBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + RegisterEndpointBuilder &operator=(const RegisterEndpointBuilder &); + flatbuffers::Offset<RegisterEndpoint> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<RegisterEndpoint>(end); + return o; + } +}; + +inline flatbuffers::Offset<RegisterEndpoint> CreateRegisterEndpoint( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<chre::fbs::EndpointInfo> endpoint = 0) { + RegisterEndpointBuilder builder_(_fbb); + builder_.add_endpoint(endpoint); + return builder_.Finish(); +} + +struct UnregisterEndpoint FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef UnregisterEndpointBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ENDPOINT = 4 + }; + const chre::fbs::EndpointId *endpoint() const { + return GetPointer<const chre::fbs::EndpointId *>(VT_ENDPOINT); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_ENDPOINT) && + verifier.VerifyTable(endpoint()) && + verifier.EndTable(); + } +}; + +struct UnregisterEndpointBuilder { + typedef UnregisterEndpoint Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_endpoint(flatbuffers::Offset<chre::fbs::EndpointId> endpoint) { + fbb_.AddOffset(UnregisterEndpoint::VT_ENDPOINT, endpoint); + } + explicit UnregisterEndpointBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + UnregisterEndpointBuilder &operator=(const UnregisterEndpointBuilder &); + flatbuffers::Offset<UnregisterEndpoint> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<UnregisterEndpoint>(end); + return o; + } +}; + +inline flatbuffers::Offset<UnregisterEndpoint> CreateUnregisterEndpoint( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<chre::fbs::EndpointId> endpoint = 0) { + UnregisterEndpointBuilder builder_(_fbb); + builder_.add_endpoint(endpoint); + return builder_.Finish(); +} + +/// HAL->CHRE, indicates the HAL is coming up +struct GetMessageHubsAndEndpointsRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef GetMessageHubsAndEndpointsRequestBuilder Builder; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } +}; + +struct GetMessageHubsAndEndpointsRequestBuilder { + typedef GetMessageHubsAndEndpointsRequest Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit GetMessageHubsAndEndpointsRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + GetMessageHubsAndEndpointsRequestBuilder &operator=(const GetMessageHubsAndEndpointsRequestBuilder &); + flatbuffers::Offset<GetMessageHubsAndEndpointsRequest> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<GetMessageHubsAndEndpointsRequest>(end); + return o; + } +}; + +inline flatbuffers::Offset<GetMessageHubsAndEndpointsRequest> CreateGetMessageHubsAndEndpointsRequest( + flatbuffers::FlatBufferBuilder &_fbb) { + GetMessageHubsAndEndpointsRequestBuilder builder_(_fbb); + return builder_.Finish(); +} + +struct GetMessageHubsAndEndpointsResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef GetMessageHubsAndEndpointsResponseBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_HUBS = 4, + VT_ENDPOINTS = 6 + }; + const flatbuffers::Vector<flatbuffers::Offset<chre::fbs::MessageHub>> *hubs() const { + return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<chre::fbs::MessageHub>> *>(VT_HUBS); + } + const flatbuffers::Vector<flatbuffers::Offset<chre::fbs::EndpointInfo>> *endpoints() const { + return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<chre::fbs::EndpointInfo>> *>(VT_ENDPOINTS); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_HUBS) && + verifier.VerifyVector(hubs()) && + verifier.VerifyVectorOfTables(hubs()) && + VerifyOffset(verifier, VT_ENDPOINTS) && + verifier.VerifyVector(endpoints()) && + verifier.VerifyVectorOfTables(endpoints()) && + verifier.EndTable(); + } +}; + +struct GetMessageHubsAndEndpointsResponseBuilder { + typedef GetMessageHubsAndEndpointsResponse Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_hubs(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<chre::fbs::MessageHub>>> hubs) { + fbb_.AddOffset(GetMessageHubsAndEndpointsResponse::VT_HUBS, hubs); + } + void add_endpoints(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<chre::fbs::EndpointInfo>>> endpoints) { + fbb_.AddOffset(GetMessageHubsAndEndpointsResponse::VT_ENDPOINTS, endpoints); + } + explicit GetMessageHubsAndEndpointsResponseBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + GetMessageHubsAndEndpointsResponseBuilder &operator=(const GetMessageHubsAndEndpointsResponseBuilder &); + flatbuffers::Offset<GetMessageHubsAndEndpointsResponse> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<GetMessageHubsAndEndpointsResponse>(end); + return o; + } +}; + +inline flatbuffers::Offset<GetMessageHubsAndEndpointsResponse> CreateGetMessageHubsAndEndpointsResponse( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<chre::fbs::MessageHub>>> hubs = 0, + flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<chre::fbs::EndpointInfo>>> endpoints = 0) { + GetMessageHubsAndEndpointsResponseBuilder builder_(_fbb); + builder_.add_endpoints(endpoints); + builder_.add_hubs(hubs); + return builder_.Finish(); +} + +inline flatbuffers::Offset<GetMessageHubsAndEndpointsResponse> CreateGetMessageHubsAndEndpointsResponseDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector<flatbuffers::Offset<chre::fbs::MessageHub>> *hubs = nullptr, + const std::vector<flatbuffers::Offset<chre::fbs::EndpointInfo>> *endpoints = nullptr) { + auto hubs__ = hubs ? _fbb.CreateVector<flatbuffers::Offset<chre::fbs::MessageHub>>(*hubs) : 0; + auto endpoints__ = endpoints ? _fbb.CreateVector<flatbuffers::Offset<chre::fbs::EndpointInfo>>(*endpoints) : 0; + return chre::fbs::CreateGetMessageHubsAndEndpointsResponse( + _fbb, + hubs__, + endpoints__); +} + +struct OpenEndpointSessionRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef OpenEndpointSessionRequestBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ID = 4, + VT_FROMENDPOINT = 6, + VT_TOENDPOINT = 8, + VT_SERVICEDESCRIPTOR = 10 + }; + uint16_t id() const { + return GetField<uint16_t>(VT_ID, 0); + } + const chre::fbs::EndpointId *fromEndpoint() const { + return GetPointer<const chre::fbs::EndpointId *>(VT_FROMENDPOINT); + } + const chre::fbs::EndpointId *toEndpoint() const { + return GetPointer<const chre::fbs::EndpointId *>(VT_TOENDPOINT); + } + /// If present, describes the service definition used over the session + const flatbuffers::Vector<int8_t> *serviceDescriptor() const { + return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_SERVICEDESCRIPTOR); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<uint16_t>(verifier, VT_ID) && + VerifyOffset(verifier, VT_FROMENDPOINT) && + verifier.VerifyTable(fromEndpoint()) && + VerifyOffset(verifier, VT_TOENDPOINT) && + verifier.VerifyTable(toEndpoint()) && + VerifyOffset(verifier, VT_SERVICEDESCRIPTOR) && + verifier.VerifyVector(serviceDescriptor()) && + verifier.EndTable(); + } +}; + +struct OpenEndpointSessionRequestBuilder { + typedef OpenEndpointSessionRequest Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_id(uint16_t id) { + fbb_.AddElement<uint16_t>(OpenEndpointSessionRequest::VT_ID, id, 0); + } + void add_fromEndpoint(flatbuffers::Offset<chre::fbs::EndpointId> fromEndpoint) { + fbb_.AddOffset(OpenEndpointSessionRequest::VT_FROMENDPOINT, fromEndpoint); + } + void add_toEndpoint(flatbuffers::Offset<chre::fbs::EndpointId> toEndpoint) { + fbb_.AddOffset(OpenEndpointSessionRequest::VT_TOENDPOINT, toEndpoint); + } + void add_serviceDescriptor(flatbuffers::Offset<flatbuffers::Vector<int8_t>> serviceDescriptor) { + fbb_.AddOffset(OpenEndpointSessionRequest::VT_SERVICEDESCRIPTOR, serviceDescriptor); + } + explicit OpenEndpointSessionRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + OpenEndpointSessionRequestBuilder &operator=(const OpenEndpointSessionRequestBuilder &); + flatbuffers::Offset<OpenEndpointSessionRequest> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<OpenEndpointSessionRequest>(end); + return o; + } +}; + +inline flatbuffers::Offset<OpenEndpointSessionRequest> CreateOpenEndpointSessionRequest( + flatbuffers::FlatBufferBuilder &_fbb, + uint16_t id = 0, + flatbuffers::Offset<chre::fbs::EndpointId> fromEndpoint = 0, + flatbuffers::Offset<chre::fbs::EndpointId> toEndpoint = 0, + flatbuffers::Offset<flatbuffers::Vector<int8_t>> serviceDescriptor = 0) { + OpenEndpointSessionRequestBuilder builder_(_fbb); + builder_.add_serviceDescriptor(serviceDescriptor); + builder_.add_toEndpoint(toEndpoint); + builder_.add_fromEndpoint(fromEndpoint); + builder_.add_id(id); + return builder_.Finish(); +} + +inline flatbuffers::Offset<OpenEndpointSessionRequest> CreateOpenEndpointSessionRequestDirect( + flatbuffers::FlatBufferBuilder &_fbb, + uint16_t id = 0, + flatbuffers::Offset<chre::fbs::EndpointId> fromEndpoint = 0, + flatbuffers::Offset<chre::fbs::EndpointId> toEndpoint = 0, + const std::vector<int8_t> *serviceDescriptor = nullptr) { + auto serviceDescriptor__ = serviceDescriptor ? _fbb.CreateVector<int8_t>(*serviceDescriptor) : 0; + return chre::fbs::CreateOpenEndpointSessionRequest( + _fbb, + id, + fromEndpoint, + toEndpoint, + serviceDescriptor__); +} + +struct EndpointSessionOpened FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef EndpointSessionOpenedBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ID = 4 + }; + uint16_t id() const { + return GetField<uint16_t>(VT_ID, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<uint16_t>(verifier, VT_ID) && + verifier.EndTable(); + } +}; + +struct EndpointSessionOpenedBuilder { + typedef EndpointSessionOpened Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_id(uint16_t id) { + fbb_.AddElement<uint16_t>(EndpointSessionOpened::VT_ID, id, 0); + } + explicit EndpointSessionOpenedBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + EndpointSessionOpenedBuilder &operator=(const EndpointSessionOpenedBuilder &); + flatbuffers::Offset<EndpointSessionOpened> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<EndpointSessionOpened>(end); + return o; + } +}; + +inline flatbuffers::Offset<EndpointSessionOpened> CreateEndpointSessionOpened( + flatbuffers::FlatBufferBuilder &_fbb, + uint16_t id = 0) { + EndpointSessionOpenedBuilder builder_(_fbb); + builder_.add_id(id); + return builder_.Finish(); +} + +struct EndpointSessionClosed FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef EndpointSessionClosedBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ID = 4, + VT_REASON = 6 + }; + uint16_t id() const { + return GetField<uint16_t>(VT_ID, 0); + } + chre::fbs::Reason reason() const { + return static_cast<chre::fbs::Reason>(GetField<uint8_t>(VT_REASON, 0)); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<uint16_t>(verifier, VT_ID) && + VerifyField<uint8_t>(verifier, VT_REASON) && + verifier.EndTable(); + } +}; + +struct EndpointSessionClosedBuilder { + typedef EndpointSessionClosed Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_id(uint16_t id) { + fbb_.AddElement<uint16_t>(EndpointSessionClosed::VT_ID, id, 0); + } + void add_reason(chre::fbs::Reason reason) { + fbb_.AddElement<uint8_t>(EndpointSessionClosed::VT_REASON, static_cast<uint8_t>(reason), 0); + } + explicit EndpointSessionClosedBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + EndpointSessionClosedBuilder &operator=(const EndpointSessionClosedBuilder &); + flatbuffers::Offset<EndpointSessionClosed> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<EndpointSessionClosed>(end); + return o; + } +}; + +inline flatbuffers::Offset<EndpointSessionClosed> CreateEndpointSessionClosed( + flatbuffers::FlatBufferBuilder &_fbb, + uint16_t id = 0, + chre::fbs::Reason reason = chre::fbs::Reason::UNSPECIFIED) { + EndpointSessionClosedBuilder builder_(_fbb); + builder_.add_id(id); + builder_.add_reason(reason); + return builder_.Finish(); +} + +struct EndpointSessionMessage FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef EndpointSessionMessageBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SESSION_ID = 4, + VT_TYPE = 6, + VT_PERMISSIONS = 8, + VT_DATA = 10, + VT_FLAGS = 12, + VT_SEQUENCE_NUMBER = 14 + }; + /// Id of session this message is being sent within + uint16_t session_id() const { + return GetField<uint16_t>(VT_SESSION_ID, 0); + } + /// Type of the message, specific to the Session protocol + uint32_t type() const { + return GetField<uint32_t>(VT_TYPE, 0); + } + /// Values from CHRE_MESSAGE_PERMISSION_*. Permissions required to read the + /// message. + uint32_t permissions() const { + return GetField<uint32_t>(VT_PERMISSIONS, 0); + } + const flatbuffers::Vector<uint8_t> *data() const { + return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_DATA); + } + /// Bitmask of additional flags applied to the message: + /// - 0x1: Message delivery status required within 1s + uint32_t flags() const { + return GetField<uint32_t>(VT_FLAGS, 0); + } + uint32_t sequence_number() const { + return GetField<uint32_t>(VT_SEQUENCE_NUMBER, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<uint16_t>(verifier, VT_SESSION_ID) && + VerifyField<uint32_t>(verifier, VT_TYPE) && + VerifyField<uint32_t>(verifier, VT_PERMISSIONS) && + VerifyOffset(verifier, VT_DATA) && + verifier.VerifyVector(data()) && + VerifyField<uint32_t>(verifier, VT_FLAGS) && + VerifyField<uint32_t>(verifier, VT_SEQUENCE_NUMBER) && + verifier.EndTable(); + } +}; + +struct EndpointSessionMessageBuilder { + typedef EndpointSessionMessage Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_session_id(uint16_t session_id) { + fbb_.AddElement<uint16_t>(EndpointSessionMessage::VT_SESSION_ID, session_id, 0); + } + void add_type(uint32_t type) { + fbb_.AddElement<uint32_t>(EndpointSessionMessage::VT_TYPE, type, 0); + } + void add_permissions(uint32_t permissions) { + fbb_.AddElement<uint32_t>(EndpointSessionMessage::VT_PERMISSIONS, permissions, 0); + } + void add_data(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> data) { + fbb_.AddOffset(EndpointSessionMessage::VT_DATA, data); + } + void add_flags(uint32_t flags) { + fbb_.AddElement<uint32_t>(EndpointSessionMessage::VT_FLAGS, flags, 0); + } + void add_sequence_number(uint32_t sequence_number) { + fbb_.AddElement<uint32_t>(EndpointSessionMessage::VT_SEQUENCE_NUMBER, sequence_number, 0); + } + explicit EndpointSessionMessageBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + EndpointSessionMessageBuilder &operator=(const EndpointSessionMessageBuilder &); + flatbuffers::Offset<EndpointSessionMessage> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<EndpointSessionMessage>(end); + return o; + } +}; + +inline flatbuffers::Offset<EndpointSessionMessage> CreateEndpointSessionMessage( + flatbuffers::FlatBufferBuilder &_fbb, + uint16_t session_id = 0, + uint32_t type = 0, + uint32_t permissions = 0, + flatbuffers::Offset<flatbuffers::Vector<uint8_t>> data = 0, + uint32_t flags = 0, + uint32_t sequence_number = 0) { + EndpointSessionMessageBuilder builder_(_fbb); + builder_.add_sequence_number(sequence_number); + builder_.add_flags(flags); + builder_.add_data(data); + builder_.add_permissions(permissions); + builder_.add_type(type); + builder_.add_session_id(session_id); + return builder_.Finish(); +} + +inline flatbuffers::Offset<EndpointSessionMessage> CreateEndpointSessionMessageDirect( + flatbuffers::FlatBufferBuilder &_fbb, + uint16_t session_id = 0, + uint32_t type = 0, + uint32_t permissions = 0, + const std::vector<uint8_t> *data = nullptr, + uint32_t flags = 0, + uint32_t sequence_number = 0) { + auto data__ = data ? _fbb.CreateVector<uint8_t>(*data) : 0; + return chre::fbs::CreateEndpointSessionMessage( + _fbb, + session_id, + type, + permissions, + data__, + flags, + sequence_number); +} + +struct EndpointSessionMessageDeliveryStatus FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef EndpointSessionMessageDeliveryStatusBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SESSION_ID = 4, + VT_STATUS = 6 + }; + /// Id of session the message was sent within + uint16_t session_id() const { + return GetField<uint16_t>(VT_SESSION_ID, 0); + } + const chre::fbs::MessageDeliveryStatus *status() const { + return GetPointer<const chre::fbs::MessageDeliveryStatus *>(VT_STATUS); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField<uint16_t>(verifier, VT_SESSION_ID) && + VerifyOffset(verifier, VT_STATUS) && + verifier.VerifyTable(status()) && + verifier.EndTable(); + } +}; + +struct EndpointSessionMessageDeliveryStatusBuilder { + typedef EndpointSessionMessageDeliveryStatus Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_session_id(uint16_t session_id) { + fbb_.AddElement<uint16_t>(EndpointSessionMessageDeliveryStatus::VT_SESSION_ID, session_id, 0); + } + void add_status(flatbuffers::Offset<chre::fbs::MessageDeliveryStatus> status) { + fbb_.AddOffset(EndpointSessionMessageDeliveryStatus::VT_STATUS, status); + } + explicit EndpointSessionMessageDeliveryStatusBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + EndpointSessionMessageDeliveryStatusBuilder &operator=(const EndpointSessionMessageDeliveryStatusBuilder &); + flatbuffers::Offset<EndpointSessionMessageDeliveryStatus> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<EndpointSessionMessageDeliveryStatus>(end); + return o; + } +}; + +inline flatbuffers::Offset<EndpointSessionMessageDeliveryStatus> CreateEndpointSessionMessageDeliveryStatus( + flatbuffers::FlatBufferBuilder &_fbb, + uint16_t session_id = 0, + flatbuffers::Offset<chre::fbs::MessageDeliveryStatus> status = 0) { + EndpointSessionMessageDeliveryStatusBuilder builder_(_fbb); + builder_.add_status(status); + builder_.add_session_id(session_id); + return builder_.Finish(); +} + /// The top-level container that encapsulates all possible messages. Note that /// per FlatBuffers requirements, we can't use a union as the top-level /// structure (root type), so we must wrap it in a table. @@ -2900,6 +4827,51 @@ const chre::fbs::MessageDeliveryStatus *message_as_MessageDeliveryStatus() const { return message_type() == chre::fbs::ChreMessage::MessageDeliveryStatus ? static_cast<const chre::fbs::MessageDeliveryStatus *>(message()) : nullptr; } + const chre::fbs::BtSocketOpen *message_as_BtSocketOpen() const { + return message_type() == chre::fbs::ChreMessage::BtSocketOpen ? static_cast<const chre::fbs::BtSocketOpen *>(message()) : nullptr; + } + const chre::fbs::BtSocketOpenResponse *message_as_BtSocketOpenResponse() const { + return message_type() == chre::fbs::ChreMessage::BtSocketOpenResponse ? static_cast<const chre::fbs::BtSocketOpenResponse *>(message()) : nullptr; + } + const chre::fbs::BtSocketClose *message_as_BtSocketClose() const { + return message_type() == chre::fbs::ChreMessage::BtSocketClose ? static_cast<const chre::fbs::BtSocketClose *>(message()) : nullptr; + } + const chre::fbs::BtSocketCloseResponse *message_as_BtSocketCloseResponse() const { + return message_type() == chre::fbs::ChreMessage::BtSocketCloseResponse ? static_cast<const chre::fbs::BtSocketCloseResponse *>(message()) : nullptr; + } + const chre::fbs::GetMessageHubsAndEndpointsRequest *message_as_GetMessageHubsAndEndpointsRequest() const { + return message_type() == chre::fbs::ChreMessage::GetMessageHubsAndEndpointsRequest ? static_cast<const chre::fbs::GetMessageHubsAndEndpointsRequest *>(message()) : nullptr; + } + const chre::fbs::GetMessageHubsAndEndpointsResponse *message_as_GetMessageHubsAndEndpointsResponse() const { + return message_type() == chre::fbs::ChreMessage::GetMessageHubsAndEndpointsResponse ? static_cast<const chre::fbs::GetMessageHubsAndEndpointsResponse *>(message()) : nullptr; + } + const chre::fbs::RegisterMessageHub *message_as_RegisterMessageHub() const { + return message_type() == chre::fbs::ChreMessage::RegisterMessageHub ? static_cast<const chre::fbs::RegisterMessageHub *>(message()) : nullptr; + } + const chre::fbs::UnregisterMessageHub *message_as_UnregisterMessageHub() const { + return message_type() == chre::fbs::ChreMessage::UnregisterMessageHub ? static_cast<const chre::fbs::UnregisterMessageHub *>(message()) : nullptr; + } + const chre::fbs::RegisterEndpoint *message_as_RegisterEndpoint() const { + return message_type() == chre::fbs::ChreMessage::RegisterEndpoint ? static_cast<const chre::fbs::RegisterEndpoint *>(message()) : nullptr; + } + const chre::fbs::UnregisterEndpoint *message_as_UnregisterEndpoint() const { + return message_type() == chre::fbs::ChreMessage::UnregisterEndpoint ? static_cast<const chre::fbs::UnregisterEndpoint *>(message()) : nullptr; + } + const chre::fbs::OpenEndpointSessionRequest *message_as_OpenEndpointSessionRequest() const { + return message_type() == chre::fbs::ChreMessage::OpenEndpointSessionRequest ? static_cast<const chre::fbs::OpenEndpointSessionRequest *>(message()) : nullptr; + } + const chre::fbs::EndpointSessionOpened *message_as_EndpointSessionOpened() const { + return message_type() == chre::fbs::ChreMessage::EndpointSessionOpened ? static_cast<const chre::fbs::EndpointSessionOpened *>(message()) : nullptr; + } + const chre::fbs::EndpointSessionClosed *message_as_EndpointSessionClosed() const { + return message_type() == chre::fbs::ChreMessage::EndpointSessionClosed ? static_cast<const chre::fbs::EndpointSessionClosed *>(message()) : nullptr; + } + const chre::fbs::EndpointSessionMessage *message_as_EndpointSessionMessage() const { + return message_type() == chre::fbs::ChreMessage::EndpointSessionMessage ? static_cast<const chre::fbs::EndpointSessionMessage *>(message()) : nullptr; + } + const chre::fbs::EndpointSessionMessageDeliveryStatus *message_as_EndpointSessionMessageDeliveryStatus() const { + return message_type() == chre::fbs::ChreMessage::EndpointSessionMessageDeliveryStatus ? static_cast<const chre::fbs::EndpointSessionMessageDeliveryStatus *>(message()) : nullptr; + } /// The originating or destination client ID on the host side, used to direct /// responses only to the client that sent the request. Although initially /// populated by the requesting client, this is enforced to be the correct @@ -3047,6 +5019,66 @@ return message_as_MessageDeliveryStatus(); } +template<> inline const chre::fbs::BtSocketOpen *MessageContainer::message_as<chre::fbs::BtSocketOpen>() const { + return message_as_BtSocketOpen(); +} + +template<> inline const chre::fbs::BtSocketOpenResponse *MessageContainer::message_as<chre::fbs::BtSocketOpenResponse>() const { + return message_as_BtSocketOpenResponse(); +} + +template<> inline const chre::fbs::BtSocketClose *MessageContainer::message_as<chre::fbs::BtSocketClose>() const { + return message_as_BtSocketClose(); +} + +template<> inline const chre::fbs::BtSocketCloseResponse *MessageContainer::message_as<chre::fbs::BtSocketCloseResponse>() const { + return message_as_BtSocketCloseResponse(); +} + +template<> inline const chre::fbs::GetMessageHubsAndEndpointsRequest *MessageContainer::message_as<chre::fbs::GetMessageHubsAndEndpointsRequest>() const { + return message_as_GetMessageHubsAndEndpointsRequest(); +} + +template<> inline const chre::fbs::GetMessageHubsAndEndpointsResponse *MessageContainer::message_as<chre::fbs::GetMessageHubsAndEndpointsResponse>() const { + return message_as_GetMessageHubsAndEndpointsResponse(); +} + +template<> inline const chre::fbs::RegisterMessageHub *MessageContainer::message_as<chre::fbs::RegisterMessageHub>() const { + return message_as_RegisterMessageHub(); +} + +template<> inline const chre::fbs::UnregisterMessageHub *MessageContainer::message_as<chre::fbs::UnregisterMessageHub>() const { + return message_as_UnregisterMessageHub(); +} + +template<> inline const chre::fbs::RegisterEndpoint *MessageContainer::message_as<chre::fbs::RegisterEndpoint>() const { + return message_as_RegisterEndpoint(); +} + +template<> inline const chre::fbs::UnregisterEndpoint *MessageContainer::message_as<chre::fbs::UnregisterEndpoint>() const { + return message_as_UnregisterEndpoint(); +} + +template<> inline const chre::fbs::OpenEndpointSessionRequest *MessageContainer::message_as<chre::fbs::OpenEndpointSessionRequest>() const { + return message_as_OpenEndpointSessionRequest(); +} + +template<> inline const chre::fbs::EndpointSessionOpened *MessageContainer::message_as<chre::fbs::EndpointSessionOpened>() const { + return message_as_EndpointSessionOpened(); +} + +template<> inline const chre::fbs::EndpointSessionClosed *MessageContainer::message_as<chre::fbs::EndpointSessionClosed>() const { + return message_as_EndpointSessionClosed(); +} + +template<> inline const chre::fbs::EndpointSessionMessage *MessageContainer::message_as<chre::fbs::EndpointSessionMessage>() const { + return message_as_EndpointSessionMessage(); +} + +template<> inline const chre::fbs::EndpointSessionMessageDeliveryStatus *MessageContainer::message_as<chre::fbs::EndpointSessionMessageDeliveryStatus>() const { + return message_as_EndpointSessionMessageDeliveryStatus(); +} + struct MessageContainerBuilder { typedef MessageContainer Table; flatbuffers::FlatBufferBuilder &fbb_; @@ -3086,6 +5118,60 @@ return builder_.Finish(); } +inline bool VerifyChannelInfo(flatbuffers::Verifier &verifier, const void *obj, ChannelInfo type) { + switch (type) { + case ChannelInfo::NONE: { + return true; + } + case ChannelInfo::LeCocChannelInfo: { + auto ptr = reinterpret_cast<const chre::fbs::LeCocChannelInfo *>(obj); + return verifier.VerifyTable(ptr); + } + default: return true; + } +} + +inline bool VerifyChannelInfoVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) { + if (!values || !types) return !values && !types; + if (values->size() != types->size()) return false; + for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) { + if (!VerifyChannelInfo( + verifier, values->Get(i), types->GetEnum<ChannelInfo>(i))) { + return false; + } + } + return true; +} + +inline bool VerifyMessageHubDetails(flatbuffers::Verifier &verifier, const void *obj, MessageHubDetails type) { + switch (type) { + case MessageHubDetails::NONE: { + return true; + } + case MessageHubDetails::HubInfoResponse: { + auto ptr = reinterpret_cast<const chre::fbs::HubInfoResponse *>(obj); + return verifier.VerifyTable(ptr); + } + case MessageHubDetails::VendorHubInfo: { + auto ptr = reinterpret_cast<const chre::fbs::VendorHubInfo *>(obj); + return verifier.VerifyTable(ptr); + } + default: return true; + } +} + +inline bool VerifyMessageHubDetailsVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) { + if (!values || !types) return !values && !types; + if (values->size() != types->size()) return false; + for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) { + if (!VerifyMessageHubDetails( + verifier, values->Get(i), types->GetEnum<MessageHubDetails>(i))) { + return false; + } + } + return true; +} + inline bool VerifyChreMessage(flatbuffers::Verifier &verifier, const void *obj, ChreMessage type) { switch (type) { case ChreMessage::NONE: { @@ -3219,6 +5305,66 @@ auto ptr = reinterpret_cast<const chre::fbs::MessageDeliveryStatus *>(obj); return verifier.VerifyTable(ptr); } + case ChreMessage::BtSocketOpen: { + auto ptr = reinterpret_cast<const chre::fbs::BtSocketOpen *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::BtSocketOpenResponse: { + auto ptr = reinterpret_cast<const chre::fbs::BtSocketOpenResponse *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::BtSocketClose: { + auto ptr = reinterpret_cast<const chre::fbs::BtSocketClose *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::BtSocketCloseResponse: { + auto ptr = reinterpret_cast<const chre::fbs::BtSocketCloseResponse *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::GetMessageHubsAndEndpointsRequest: { + auto ptr = reinterpret_cast<const chre::fbs::GetMessageHubsAndEndpointsRequest *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::GetMessageHubsAndEndpointsResponse: { + auto ptr = reinterpret_cast<const chre::fbs::GetMessageHubsAndEndpointsResponse *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::RegisterMessageHub: { + auto ptr = reinterpret_cast<const chre::fbs::RegisterMessageHub *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::UnregisterMessageHub: { + auto ptr = reinterpret_cast<const chre::fbs::UnregisterMessageHub *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::RegisterEndpoint: { + auto ptr = reinterpret_cast<const chre::fbs::RegisterEndpoint *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::UnregisterEndpoint: { + auto ptr = reinterpret_cast<const chre::fbs::UnregisterEndpoint *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::OpenEndpointSessionRequest: { + auto ptr = reinterpret_cast<const chre::fbs::OpenEndpointSessionRequest *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::EndpointSessionOpened: { + auto ptr = reinterpret_cast<const chre::fbs::EndpointSessionOpened *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::EndpointSessionClosed: { + auto ptr = reinterpret_cast<const chre::fbs::EndpointSessionClosed *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::EndpointSessionMessage: { + auto ptr = reinterpret_cast<const chre::fbs::EndpointSessionMessage *>(obj); + return verifier.VerifyTable(ptr); + } + case ChreMessage::EndpointSessionMessageDeliveryStatus: { + auto ptr = reinterpret_cast<const chre::fbs::EndpointSessionMessageDeliveryStatus *>(obj); + return verifier.VerifyTable(ptr); + } default: return true; } }
diff --git a/platform/shared/include/chre/platform/shared/host_protocol_chre.h b/platform/shared/include/chre/platform/shared/host_protocol_chre.h index 62421c0..8857fad 100644 --- a/platform/shared/include/chre/platform/shared/host_protocol_chre.h +++ b/platform/shared/include/chre/platform/shared/host_protocol_chre.h
@@ -18,6 +18,7 @@ #define CHRE_PLATFORM_SHARED_HOST_PROTOCOL_CHRE_H_ #include <stdint.h> +#include <cstdint> #include "chre/core/event_loop_common.h" #include "chre/core/nanoapp.h" @@ -100,6 +101,15 @@ static void handleNanConfigurationUpdate(bool enabled); + static void handleBtSocketOpen(uint16_t hostClientId, uint64_t socketId, + const char *name, uint64_t endpointId, + uint64_t hubId, uint32_t aclConnectionHandle, + uint32_t localCid, uint32_t remoteCid, + uint32_t psm, uint32_t localMtu, + uint32_t remoteMtu, uint32_t localMps, + uint32_t remoteMps, uint32_t initialRxCredits, + uint32_t initialTxCredits); + private: static void sendFragmentResponse(uint16_t hostClientId, uint32_t transactionId, uint32_t fragmentId, @@ -153,10 +163,11 @@ static bool decodeMessageFromHost(const void *message, size_t messageLen); /** - * Refer to the context hub HAL definition for a details of these parameters. + * Refer to the context hub HAL definition for a details of these + * parameters. * - * @param builder A newly constructed ChreFlatBufferBuilder that will be used - * to encode the message + * @param builder A newly constructed ChreFlatBufferBuilder that will be + * used to encode the message */ static void encodeHubInfoResponse( ChreFlatBufferBuilder &builder, const char *name, const char *vendor, @@ -324,6 +335,32 @@ */ static void encodeNanConfigurationRequest(ChreFlatBufferBuilder &builder, bool enable); + + /** + * Encodes a BT socket open response. + * + * @param builder An instance of the CHRE Flatbuffer builder. + * @param hostClientId Host client identifier. + * @param success Whether the socket open request was successful. + * @param reason Failure reason if success is false. + * @param socketId BT socket identifier. + */ + static void encodeBtSocketOpenResponse(ChreFlatBufferBuilder &builder, + uint16_t hostClientId, + uint64_t socketId, bool success, + const char *reason); + + /** + * Encodes a BT socket close request. + * + * @param builder An instance of the CHRE Flatbuffer builder. + * @param hostClientId Host client identifier. + * @param reason Reason socket is being closed. + * @param socketId BT socket identifier. + */ + static void encodeBtSocketClose(ChreFlatBufferBuilder &builder, + uint16_t hostClientId, uint64_t socketId, + const char *reason); }; } // namespace chre
diff --git a/platform/shared/include/chre/target_platform/platform_cache_management.h b/platform/shared/include/chre/platform/shared/platform_cache_management.h similarity index 100% rename from platform/shared/include/chre/target_platform/platform_cache_management.h rename to platform/shared/include/chre/platform/shared/platform_cache_management.h
diff --git a/platform/shared/log_buffer_manager.cc b/platform/shared/log_buffer_manager.cc index e408d0c..d090068 100644 --- a/platform/shared/log_buffer_manager.cc +++ b/platform/shared/log_buffer_manager.cc
@@ -22,6 +22,13 @@ #include "chre/platform/shared/generated/host_messages_generated.h" #include "chre/util/lock_guard.h" +#ifdef CHRE_TOKENIZED_LOGGING_ENABLED +#include "chre/platform/log.h" +#include "pw_log_tokenized/config.h" +#include "pw_tokenizer/encode_args.h" +#include "pw_tokenizer/tokenize.h" +#endif // CHRE_TOKENIZED_LOGGING_ENABLED + void chrePlatformLogToBuffer(chreLogLevel chreLogLevel, const char *format, ...) { va_list args; @@ -44,6 +51,23 @@ chre::LogBufferManagerSingleton::get()->logBtSnoop(direction, buffer, size); } +#ifdef CHRE_TOKENIZED_LOGGING_ENABLED +// The callback function that must be defined to handle an encoded +// tokenizer message. +void EncodeTokenizedMessage(uint32_t level, pw_tokenizer_Token token, + pw_tokenizer_ArgTypes types, ...) { + va_list args; + va_start(args, types); + pw::tokenizer::EncodedMessage<pw::log_tokenized::kEncodingBufferSizeBytes> + encodedMessage(token, types, args); + va_end(args); + + chrePlatformEncodedLogToBuffer(static_cast<chreLogLevel>(level), + encodedMessage.data_as_uint8(), + encodedMessage.size()); +} +#endif // CHRE_TOKENIZED_LOGGING_ENABLED + namespace chre { using LogType = fbs::LogType;
diff --git a/platform/shared/nanoapp_load_manager.cc b/platform/shared/nanoapp_load_manager.cc index 67de637..f786823 100644 --- a/platform/shared/nanoapp_load_manager.cc +++ b/platform/shared/nanoapp_load_manager.cc
@@ -23,12 +23,6 @@ uint32_t appVersion, uint32_t appFlags, size_t totalBinaryLen, uint32_t targetApiVersion) { - if (hasPendingLoadTransaction()) { - LOGW( - "Pending load transaction already exists. Overriding previous" - " transaction."); - } - mCurrentLoadInfo.hostClientId = hostClientId; mCurrentLoadInfo.transactionId = transactionId; mCurrentLoadInfo.nextFragmentId = 1;
diff --git a/platform/shared/nanoapp_loader.cc b/platform/shared/nanoapp_loader.cc index 9fce9ac..5eea156 100644 --- a/platform/shared/nanoapp_loader.cc +++ b/platform/shared/nanoapp_loader.cc
@@ -27,7 +27,7 @@ #include "chre/platform/shared/debug_dump.h" #include "chre/platform/shared/memory.h" #include "chre/platform/shared/nanoapp/tokenized_log.h" -#include "chre/target_platform/platform_cache_management.h" +#include "chre/platform/shared/platform_cache_management.h" #include "chre/util/dynamic_vector.h" #include "chre/util/macros.h" @@ -133,7 +133,7 @@ return cos(rad); } -float sqrtOverride(float val) { +double sqrtOverride(double val) { return sqrt(val); } @@ -178,6 +178,7 @@ ADD_EXPORTED_C_SYMBOL(fmaxf), ADD_EXPORTED_C_SYMBOL(fminf), ADD_EXPORTED_C_SYMBOL(fmodf), + ADD_EXPORTED_C_SYMBOL(ldexpf), ADD_EXPORTED_C_SYMBOL(log10f), ADD_EXPORTED_C_SYMBOL(log1pf), ADD_EXPORTED_C_SYMBOL(log2f),
diff --git a/platform/shared/pal_ble_stub.cc b/platform/shared/pal_ble_stub.cc index f34fdca..77f22f7 100644 --- a/platform/shared/pal_ble_stub.cc +++ b/platform/shared/pal_ble_stub.cc
@@ -16,10 +16,7 @@ #include "chre/pal/ble.h" -#include "chre/util/macros.h" - -const struct chrePalBleApi *chrePalBleGetApi(uint32_t requestedApiVersion) { - UNUSED_VAR(requestedApiVersion); +const struct chrePalBleApi *chrePalBleGetApi(uint32_t /*requestedApiVersion*/) { // This stub implementation of the CHRE PAL returns nullptr to indicate that // it is not supplied by this platform. return nullptr;
diff --git a/platform/shared/pal_gnss_stub.cc b/platform/shared/pal_gnss_stub.cc index 6b46b99..d279a15 100644 --- a/platform/shared/pal_gnss_stub.cc +++ b/platform/shared/pal_gnss_stub.cc
@@ -16,7 +16,8 @@ #include "chre/pal/gnss.h" -const struct chrePalGnssApi *chrePalGnssGetApi(uint32_t requestedApiVersion) { +const struct chrePalGnssApi *chrePalGnssGetApi( + uint32_t /*requestedApiVersion*/) { // This stub implementation of the CHRE PAL returns nullptr to indicate that // it is not supplied by this platform. return nullptr;
diff --git a/platform/shared/pal_sensor_stub.cc b/platform/shared/pal_sensor_stub.cc index 235d023..10d27e7 100644 --- a/platform/shared/pal_sensor_stub.cc +++ b/platform/shared/pal_sensor_stub.cc
@@ -16,11 +16,8 @@ #include "chre/pal/sensor.h" -#include "chre/util/macros.h" - const struct chrePalSensorApi *chrePalSensorGetApi( - uint32_t requestedApiVersion) { - UNUSED_VAR(requestedApiVersion); + uint32_t /*requestedApiVersion*/) { // This stub implementation of the CHRE PAL returns nullptr to indicate that // it is not supplied by this platform.
diff --git a/platform/shared/pal_wifi_stub.cc b/platform/shared/pal_wifi_stub.cc index 19d76aa..ef3059a 100644 --- a/platform/shared/pal_wifi_stub.cc +++ b/platform/shared/pal_wifi_stub.cc
@@ -16,7 +16,8 @@ #include "chre/pal/wifi.h" -const struct chrePalWifiApi *chrePalWifiGetApi(uint32_t requestedApiVersion) { +const struct chrePalWifiApi *chrePalWifiGetApi( + uint32_t /*requestedApiVersion*/) { // This stub implementation of the CHRE PAL returns nullptr to indicate that // it is not supplied by this platform. return nullptr;
diff --git a/platform/shared/pal_wwan_stub.cc b/platform/shared/pal_wwan_stub.cc index 4233534..7908d12 100644 --- a/platform/shared/pal_wwan_stub.cc +++ b/platform/shared/pal_wwan_stub.cc
@@ -16,7 +16,8 @@ #include "chre/pal/wwan.h" -const struct chrePalWwanApi *chrePalWwanGetApi(uint32_t requestedApiVersion) { +const struct chrePalWwanApi *chrePalWwanGetApi( + uint32_t /*requestedApiVersion*/) { // This stub implementation of the CHRE PAL returns nullptr to indicate that // it is not supplied by this platform. return nullptr;
diff --git a/platform/shared/platform_ble.cc b/platform/shared/platform_ble.cc index 54e5f1e..bf1f1cb 100644 --- a/platform/shared/platform_ble.cc +++ b/platform/shared/platform_ble.cc
@@ -14,6 +14,8 @@ * limitations under the License. */ +#ifdef CHRE_BLE_SUPPORT_ENABLED + #include "chre/platform/platform_ble.h" #include <cinttypes> @@ -166,3 +168,5 @@ } } // namespace chre + +#endif // CHRE_BLE_SUPPORT_ENABLED
diff --git a/platform/shared/platform_gnss.cc b/platform/shared/platform_gnss.cc index 2c712bf..f667a63 100644 --- a/platform/shared/platform_gnss.cc +++ b/platform/shared/platform_gnss.cc
@@ -14,6 +14,8 @@ * limitations under the License. */ +#ifdef CHRE_GNSS_SUPPORT_ENABLED + #include "chre/platform/platform_gnss.h" #include <cinttypes> @@ -158,3 +160,5 @@ } } // namespace chre + +#endif // CHRE_GNSS_SUPPORT_ENABLED
diff --git a/platform/shared/platform_wifi.cc b/platform/shared/platform_wifi.cc index 84c9a3c..17681fb 100644 --- a/platform/shared/platform_wifi.cc +++ b/platform/shared/platform_wifi.cc
@@ -14,6 +14,8 @@ * limitations under the License. */ +#ifdef CHRE_WIFI_SUPPORT_ENABLED + #include "chre/platform/platform_wifi.h" #include <cinttypes> @@ -257,3 +259,5 @@ } } // namespace chre + +#endif // CHRE_WIFI_SUPPORT_ENABLED
diff --git a/platform/shared/platform_wwan.cc b/platform/shared/platform_wwan.cc index 2e1119a..67f1ddc 100644 --- a/platform/shared/platform_wwan.cc +++ b/platform/shared/platform_wwan.cc
@@ -14,6 +14,8 @@ * limitations under the License. */ +#ifdef CHRE_WWAN_SUPPORT_ENABLED + #include "chre/platform/platform_wwan.h" #include <cinttypes> @@ -92,3 +94,5 @@ } } // namespace chre + +#endif // CHRE_WWAN_SUPPORT_ENABLED
diff --git a/platform/shared/include/chre/target_platform/platform_ble_base.h b/platform/shared/public_platform_ble_pal/chre/target_platform/platform_ble_base.h similarity index 100% rename from platform/shared/include/chre/target_platform/platform_ble_base.h rename to platform/shared/public_platform_ble_pal/chre/target_platform/platform_ble_base.h
diff --git a/platform/shared/include/chre/target_platform/platform_debug_dump_manager_base.h b/platform/shared/public_platform_debug_dump_manager/chre/target_platform/platform_debug_dump_manager_base.h similarity index 100% rename from platform/shared/include/chre/target_platform/platform_debug_dump_manager_base.h rename to platform/shared/public_platform_debug_dump_manager/chre/target_platform/platform_debug_dump_manager_base.h
diff --git a/platform/shared/include/chre/target_platform/platform_gnss_base.h b/platform/shared/public_platform_gnss_pal/chre/target_platform/platform_gnss_base.h similarity index 100% rename from platform/shared/include/chre/target_platform/platform_gnss_base.h rename to platform/shared/public_platform_gnss_pal/chre/target_platform/platform_gnss_base.h
diff --git a/platform/shared/include/chre/target_platform/platform_wifi_base.h b/platform/shared/public_platform_wifi_pal/chre/target_platform/platform_wifi_base.h similarity index 100% rename from platform/shared/include/chre/target_platform/platform_wifi_base.h rename to platform/shared/public_platform_wifi_pal/chre/target_platform/platform_wifi_base.h
diff --git a/platform/shared/include/chre/target_platform/platform_wwan_base.h b/platform/shared/public_platform_wwan_pal/chre/target_platform/platform_wwan_base.h similarity index 100% rename from platform/shared/include/chre/target_platform/platform_wwan_base.h rename to platform/shared/public_platform_wwan_pal/chre/target_platform/platform_wwan_base.h
diff --git a/platform/slpi/host_link.cc b/platform/slpi/host_link.cc index 3e07a07..a32f9e6 100644 --- a/platform/slpi/host_link.cc +++ b/platform/slpi/host_link.cc
@@ -36,10 +36,10 @@ #include "chre/platform/slpi/power_control_util.h" #include "chre/platform/system_time.h" #include "chre/platform/system_timer.h" -#include "chre/util/fixed_size_blocking_queue.h" #include "chre/util/flatbuffers/helpers.h" #include "chre/util/macros.h" #include "chre/util/nested_data_ptr.h" +#include "chre/util/system/fixed_size_blocking_queue.h" #include "chre/util/unique_ptr.h" #include "chre_api/chre/version.h" @@ -928,4 +928,14 @@ #endif // CHRE_WIFI_NAN_SUPPORT_ENABLED } +void HostMessageHandlers::handleBtSocketOpen( + uint16_t /* hostClientId */, uint64_t /* socketId */, + const char * /* name */, uint64_t /* endpointId */, uint64_t /* hubId */, + uint32_t /* aclConnectionHandle */, uint32_t /* localCid */, + uint32_t /* remoteCid */, uint32_t /* psm */, uint32_t /* localMtu */, + uint32_t /* remoteMtu */, uint32_t /* localMps */, uint32_t /* remoteMps */, + uint32_t /* initialRxCredits */, uint32_t /* initialTxCredits */) { + LOGE("BT Socket offload not supported"); +} + } // namespace chre
diff --git a/platform/tinysys/chre_init.cc b/platform/tinysys/chre_init.cc index 90989de..83abb87 100644 --- a/platform/tinysys/chre_init.cc +++ b/platform/tinysys/chre_init.cc
@@ -15,8 +15,12 @@ */ #include "chre/target_platform/chre_init.h" +#include "chre/platform/shared/dram_vote_client.h" BaseType_t chreTinysysInit() { + chre::DramVoteClientSingleton::init(); + chre::freertos::initLogger(); + return chre::freertos::init(); }
diff --git a/platform/tinysys/host_link.cc b/platform/tinysys/host_link.cc index a393da9..f6f4712 100644 --- a/platform/tinysys/host_link.cc +++ b/platform/tinysys/host_link.cc
@@ -84,24 +84,32 @@ // SCP get ack data from AP (SCP to AP) SRAM_REGION_BSS int gChreIpiAckFromHost[2]; +#ifdef SCP_CHRE_USE_DMA +// The min total size of a message to trigger DMA for sending/receiving. +constexpr uint32_t kMinMessageSizeForDma = 0x1000; // 4k +#endif + +// The buffer used to receive messages from AP. +// The size should be consistent with the max sending size on the host side. +constexpr uint32_t kChreIpiRecvBufferSize = 0x8000; // 32k +DRAM_REGION_VARIABLE uint8_t gChreRecvBuffer[kChreIpiRecvBufferSize] + __attribute__((aligned(CACHE_LINE_SIZE))); + +#ifdef SCP_CHRE_USE_DMA +// Rounds up the value to be aligned with CACHE_LINE_SIZE. +static inline uint32_t alignToCacheLine(uint32_t value) { + // alignment must be a power of 2. + static_assert(CACHE_LINE_SIZE > 0 && + (CACHE_LINE_SIZE & (CACHE_LINE_SIZE - 1)) == 0); + return (value + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1); +} +#endif + void *gChreSubregionRecvAddr; size_t gChreSubregionRecvSize; void *gChreSubregionSendAddr; size_t gChreSubregionSendSize; -// TODO(b/277235389): move it to HostLinkBase, and revisit buffer size -// payload buffers -#define CHRE_IPI_RECV_BUFFER_SIZE (CHRE_MESSAGE_TO_HOST_MAX_SIZE + 128) -DRAM_REGION_VARIABLE uint32_t - gChreRecvBuffer[CHRE_IPI_RECV_BUFFER_SIZE / sizeof(uint32_t)] - __attribute__((aligned(CACHE_LINE_SIZE))); - -#ifdef SCP_CHRE_USE_DMA -static inline uint32_t align(uint32_t target, uint32_t size) { - return (target + size - 1) & ~(size - 1); -} -#endif - #define SCP_CHRE_MAGIC 0x67728269 struct ScpChreIpiMsg { uint32_t magic; @@ -132,6 +140,8 @@ NanConfigurationRequest, PulseRequest, PulseResponse, + NanoappTokenDatabaseInfo, + MessageDeliveryStatus, }; struct PendingMessage { @@ -160,7 +170,7 @@ }; constexpr size_t kOutboundQueueSize = 100; -DRAM_REGION_VARIABLE FixedSizeBlockingQueue<PendingMessage, kOutboundQueueSize> +SRAM_REGION_VARIABLE FixedSizeBlockingQueue<PendingMessage, kOutboundQueueSize> gOutboundQueue; typedef void(MessageBuilderFunction)(ChreFlatBufferBuilder &builder, @@ -243,25 +253,9 @@ case PendingMessageType::HubInfoResponse: result = generateHubInfoResponse(pendingMsg.data.hostClientId); break; - - case PendingMessageType::NanoappListResponse: - case PendingMessageType::LoadNanoappResponse: - case PendingMessageType::UnloadNanoappResponse: - case PendingMessageType::DebugDumpData: - case PendingMessageType::DebugDumpResponse: - case PendingMessageType::TimeSyncRequest: - case PendingMessageType::LowPowerMicAccessRequest: - case PendingMessageType::LowPowerMicAccessRelease: - case PendingMessageType::EncodedLogMessage: - case PendingMessageType::SelfTestResponse: - case PendingMessageType::MetricLog: - case PendingMessageType::NanConfigurationRequest: - case PendingMessageType::PulseResponse: + default: result = generateMessageFromBuilder(pendingMsg.data.builder); break; - - default: - CHRE_ASSERT_LOG(false, "Unexpected pending message type"); } return result; } @@ -479,9 +473,9 @@ struct ScpChreIpiMsg msg = *(struct ScpChreIpiMsg *)data; // check the magic number and payload size need to be copy(if need) */ - LOGV("%s: msg.magic=0x%x, msg.size=%u", __func__, msg.magic, msg.size); + LOGD("%s: Received a message from AP. Size=%u", __func__, msg.size); if (msg.magic != SCP_CHRE_MAGIC) { - LOGE("Invalid magic number, skip message"); + LOGE("Invalid magic number: 0x%x, skip message", msg.magic); gChreIpiAckToHost[0] = IPI_NO_MEMORY; gChreIpiAckToHost[1] = 0; return; @@ -492,25 +486,38 @@ ap_to_scp(reinterpret_cast<uint32_t>(gChreSubregionRecvAddr)); #ifdef SCP_CHRE_USE_DMA - // Using SCP DMA HW to copy the data from share memory to SCP side, ex: - // gChreRecvBuffer gChreRecvBuffer could be a global variables or a SCP heap - // memory at SRAM/DRAM - scp_dma_transaction_dram(reinterpret_cast<uint32_t>(&gChreRecvBuffer[0]), - srcAddr, msg.size, DMA_MEM_ID, NO_RESERVED); + if (msg.size < kMinMessageSizeForDma) { + dvfs_enable_DRAM_resource(CHRE_MEM_ID); + memcpy(static_cast<void *>(gChreRecvBuffer), + reinterpret_cast<void *>(srcAddr), msg.size); + dvfs_disable_DRAM_resource(CHRE_MEM_ID); + } else { + auto dstAddr = reinterpret_cast<uint32_t>(gChreRecvBuffer); - // Invalid cache to update the newest data before using - mrv_dcache_invalid_multi_addr(reinterpret_cast<uint32_t>(&gChreRecvBuffer[0]), - align(msg.size, CACHE_LINE_SIZE)); -#else + // destination address for receiving data is in a cacheable memory, it + // should be invalidated/flushed before transferring from share buffer to + // SCP + scp_dcache_flush(dstAddr, alignToCacheLine(msg.size)); + + // Using SCP DMA HW to copy the data from share memory to SCP side. + // The dstAddr could be a global variables or a SCP heap memory at SRAM/DRAM + DMA_RESULT result = scp_dma_transaction_dram(dstAddr, srcAddr, msg.size, + DMA_MEM_ID, NO_RESERVED); + + if (result != DMA_RESULT_DONE) { + LOGE("Failed to receive a message from AP using DMA"); + } + } +#else // SCP_CHRE_USE_DMA + dvfs_enable_DRAM_resource(CHRE_MEM_ID); memcpy(static_cast<void *>(gChreRecvBuffer), reinterpret_cast<void *>(srcAddr), msg.size); dvfs_disable_DRAM_resource(CHRE_MEM_ID); -#endif + +#endif // SCP_CHRE_USE_DMA // process the message - LOGV("chre_rcvbuf: 0x%x 0x%x 0x%x 0x%x", gChreRecvBuffer[0], - gChreRecvBuffer[1], gChreRecvBuffer[2], gChreRecvBuffer[3]); receive(static_cast<HostLinkBase *>(prdata), gChreRecvBuffer, msg.size); // After finishing the job, akc the message to host @@ -519,11 +526,15 @@ } DRAM_REGION_FUNCTION void HostLinkBase::initializeIpi(void) { - LOGV("%s", __func__); bool success = false; int ret; constexpr size_t kBackgroundTaskStackSize = 1024; + +#ifdef PRI_CHRE_BACKGROUND + constexpr UBaseType_t kBackgroundTaskPriority = PRI_CHRE_BACKGROUND; +#else constexpr UBaseType_t kBackgroundTaskPriority = 2; +#endif // prepared share memory information and register the callback functions if (!(ret = scp_get_reserve_mem_by_id(SCP_CHRE_FROM_MEM_ID, @@ -585,20 +596,49 @@ msg.magic = SCP_CHRE_MAGIC; msg.size = dataLen; - // Mapping the physical address of share memory for SCP - void *dstAddr = reinterpret_cast<void *>( - ap_to_scp(reinterpret_cast<uint32_t>(gChreSubregionSendAddr))); + uint32_t dstAddr = + ap_to_scp(reinterpret_cast<uint32_t>(gChreSubregionSendAddr)); #ifdef SCP_CHRE_USE_DMA - // TODO(b/288415339): use DMA for larger payload - // No need cache operation, because src_dst handled by SCP CPU and dstAddr is - // non-cacheable + if (dataLen < kMinMessageSizeForDma) { + dvfs_enable_DRAM_resource(CHRE_MEM_ID); + memcpy(reinterpret_cast<void *>(dstAddr), data, dataLen); + dvfs_disable_DRAM_resource(CHRE_MEM_ID); + } else { + auto srcAddr = reinterpret_cast<uint32_t>(data); + auto msgSize = reinterpret_cast<uint32_t>(msg.size); + + // Separate the message into 2 parts, copySize and dmaSize, and use memcpy + // and dma to transfer them respectively. This is needed due to the + // alignment requirement of the dma transfer. + uint32_t dmaStartSrcAddr = alignToCacheLine(srcAddr); + uint32_t copySize = dmaStartSrcAddr - srcAddr; + uint32_t dmaSize = msgSize - copySize; + + if (copySize > 0) { + dvfs_enable_DRAM_resource(CHRE_MEM_ID); + memcpy(reinterpret_cast<void *>(dstAddr), data, copySize); + dvfs_disable_DRAM_resource(CHRE_MEM_ID); + } + + // source address for sending data is in a cacheable memory, it should + // be invalidated/flushed before transferring from SCP to shared buffer + scp_dcache_flush(dmaStartSrcAddr, alignToCacheLine(dmaSize)); + + // Using SCP DMA HW to copy the data from SCP to shared memory. + // The dstAddr could be a global variables or a SCP heap memory at SRAM/DRAM + DMA_RESULT result = scp_dma_transaction_dram( + dstAddr + copySize, dmaStartSrcAddr, dmaSize, DMA_MEM_ID, NO_RESERVED); + + if (result != DMA_RESULT_DONE) { + LOGE("Failed to receive a message from AP using DMA"); + } + } #else dvfs_enable_DRAM_resource(CHRE_MEM_ID); - memcpy(dstAddr, data, dataLen); + memcpy(reinterpret_cast<void *>(dstAddr), data, dataLen); dvfs_disable_DRAM_resource(CHRE_MEM_ID); #endif - // NB: len param for ipi_send is in number of 32-bit words int ret = ipi_send_compl( IPI_OUT_C_SCP_HOST_CHRE, &msg, sizeof(msg) / sizeof(uint32_t), @@ -607,18 +647,17 @@ LOGE("chre ipi send fail(%d)", ret); } else { /* check ack data for make sure IPI wasn't busy */ - LOGV("chre ipi send, check ack data: 0x%x", gChreIpiAckFromHost[0]); if (gChreIpiAckFromHost[0] == IPI_ACTION_DONE) { LOGV("chre ipi send done, you can send another IPI"); } else if (gChreIpiAckFromHost[0] == IPI_PIN_BUSY) { /* you may have to re-send the IPI, or drop this one */ - LOGV( + LOGW( "chre ipi send busy, user thread has not wait the IPI until job " "finished"); } else if (gChreIpiAckFromHost[0] == IPI_NO_MEMORY) { - LOGV("chre ipi send with wrong size(%zu)", dataLen); + LOGW("chre ipi send with wrong size(%zu)", dataLen); } else { - LOGV("chre ipi send unknown case"); + LOGW("chre ipi send unknown case: 0x%x", gChreIpiAckFromHost[0]); } } @@ -680,9 +719,21 @@ return success; } -bool HostLink::sendMessageDeliveryStatus(uint32_t /* messageSequenceNumber */, - uint8_t /* errorCode */) { - return false; +DRAM_REGION_FUNCTION bool HostLink::sendMessageDeliveryStatus( + uint32_t messageSequenceNumber, uint8_t errorCode) { + struct DeliveryStatusData { + uint32_t messageSequenceNumber; + uint8_t errorCode; + } args{messageSequenceNumber, errorCode}; + + auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) { + auto args = static_cast<const DeliveryStatusData *>(cookie); + HostProtocolChre::encodeMessageDeliveryStatus( + builder, args->messageSequenceNumber, args->errorCode); + }; + + return buildAndEnqueueMessage(PendingMessageType::MessageDeliveryStatus, + /* initialBufferSize= */ 64, msgBuilder, &args); } // TODO(b/285219398): HostMessageHandlers member function implementations are @@ -704,7 +755,9 @@ } DRAM_REGION_FUNCTION void HostMessageHandlers::handleMessageDeliveryStatus( - uint32_t /* messageSequenceNumber */, uint8_t /* errorCode */) {} + uint32_t messageSequenceNumber, uint8_t errorCode) { + getHostCommsManager().completeTransaction(messageSequenceNumber, errorCode); +} DRAM_REGION_FUNCTION void HostMessageHandlers::handleHubInfoRequest( uint16_t hostClientId) { @@ -817,19 +870,25 @@ DRAM_REGION_FUNCTION void HostLinkBase::sendNanoappTokenDatabaseInfo( uint64_t appId, uint32_t tokenDatabaseOffset, size_t tokenDatabaseSize) { constexpr size_t kInitialBufferSize = 56; - ChreFlatBufferBuilder builder(kInitialBufferSize); - uint16_t instanceId; - EventLoopManagerSingleton::get()->getEventLoop().findNanoappInstanceIdByAppId( - appId, &instanceId); - HostProtocolChre::encodeNanoappTokenDatabaseInfo( - builder, instanceId, appId, tokenDatabaseOffset, tokenDatabaseSize); + struct DatabaseInfoArgs { + uint64_t appId; + uint32_t tokenDatabaseOffset; + size_t tokenDatabaseSize; + } args{appId, tokenDatabaseOffset, tokenDatabaseSize}; - if (!getHostCommsManager().send(builder.GetBufferPointer(), - builder.GetSize())) { - LOGE("Failed to send nanoapp token database info for AppID: 0x%016" PRIx64 - " InstanceID: %" PRIu16, - appId, instanceId); - } + auto msgBuilder = [](ChreFlatBufferBuilder &builder, void *cookie) { + DatabaseInfoArgs *args = static_cast<DatabaseInfoArgs *>(cookie); + uint16_t instanceId; + EventLoopManagerSingleton::get() + ->getEventLoop() + .findNanoappInstanceIdByAppId(args->appId, &instanceId); + HostProtocolChre::encodeNanoappTokenDatabaseInfo( + builder, instanceId, args->appId, args->tokenDatabaseOffset, + args->tokenDatabaseSize); + }; + + buildAndEnqueueMessage(PendingMessageType::NanoappTokenDatabaseInfo, + kInitialBufferSize, msgBuilder, &args); } DRAM_REGION_FUNCTION void HostLink::flushMessagesSentByNanoapp( @@ -876,6 +935,16 @@ LOGE("%s is unsupported", __func__); } +DRAM_REGION_FUNCTION void HostMessageHandlers::handleBtSocketOpen( + uint16_t /* hostClientId */, uint64_t /* socketId */, + const char * /* name */, uint64_t /* endpointId */, uint64_t /* hubId */, + uint32_t /* aclConnectionHandle */, uint32_t /* localCid */, + uint32_t /* remoteCid */, uint32_t /* psm */, uint32_t /* localMtu */, + uint32_t /* remoteMtu */, uint32_t /* localMps */, uint32_t /* remoteMps */, + uint32_t /* initialRxCredits */, uint32_t /* initialTxCredits */) { + LOGE("BT Socket offload not supported"); +} + DRAM_REGION_FUNCTION void sendAudioRequest() { auto msgBuilder = [](ChreFlatBufferBuilder &builder, void * /*cookie*/) { HostProtocolChre::encodeLowPowerMicAccessRequest(builder);
diff --git a/platform/tinysys/include/chre/target_platform/system_timer_base.h b/platform/tinysys/include/chre/target_platform/system_timer_base.h index 2713085..5ecdb05 100644 --- a/platform/tinysys/include/chre/target_platform/system_timer_base.h +++ b/platform/tinysys/include/chre/target_platform/system_timer_base.h
@@ -25,6 +25,7 @@ extern "C" { #endif +#include "FreeRTOS.h" #include "sensorhub/rt_timer.h" #include "task.h" @@ -40,7 +41,11 @@ static constexpr uint32_t kStackDepthWords = 0x200; // 2K stack size /** Priority of the callback runner task */ +#ifdef PRI_CHRE_SYS_TIMER + static constexpr UBaseType_t kTaskPriority = PRI_CHRE_SYS_TIMER; +#else static constexpr UBaseType_t kTaskPriority = tskIDLE_PRIORITY + 4; +#endif /** Name of the callback runner task */ static constexpr char kTaskName[] = "ChreTimerCbRunner"; @@ -74,4 +79,4 @@ struct rt_timer rtSystemTimer; }; } // namespace chre -#endif // CHRE_PLATFORM_TINYSYS_SYSTEM_TIMER_BASE_H_ \ No newline at end of file +#endif // CHRE_PLATFORM_TINYSYS_SYSTEM_TIMER_BASE_H_
diff --git a/platform/tinysys/memory.cc b/platform/tinysys/memory.cc index 4bfd5d0..b67c836 100644 --- a/platform/tinysys/memory.cc +++ b/platform/tinysys/memory.cc
@@ -30,7 +30,6 @@ #include "encoding.h" #include "mt_heap.h" #include "resource_req.h" -#include "sensorhub/heap.h" #ifdef __cplusplus } // extern "C" @@ -80,7 +79,7 @@ } void *memoryAlloc(size_t size) { - void *address = heap_alloc(size); + void *address = pvPortMalloc(size); if (address == nullptr && size > 0) { // Try dram if allocation from sram fails. // DramVoteClient tracks the duration of the allocations falling back to @@ -103,7 +102,7 @@ vPortDramFree(pointer); DramVoteClientSingleton::get()->decrementDramVoteCount(); } else { - heap_free(pointer); + vPortFree(pointer); } } } // namespace chre
diff --git a/platform/tinysys/platform_cache_management.cc b/platform/tinysys/platform_cache_management.cc index da2ba11..3e12ed1 100644 --- a/platform/tinysys/platform_cache_management.cc +++ b/platform/tinysys/platform_cache_management.cc
@@ -16,8 +16,8 @@ #include "FreeRTOS.h" -#include "chre/target_platform/platform_cache_management.h" #include "chre/platform/shared/nanoapp_loader.h" +#include "chre/platform/shared/platform_cache_management.h" #include "dma_api.h"
diff --git a/test/simulation/chre_message_hub_test.cc b/test/simulation/chre_message_hub_test.cc new file mode 100644 index 0000000..7b3a0d3 --- /dev/null +++ b/test/simulation/chre_message_hub_test.cc
@@ -0,0 +1,359 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cstdint> +#include <cstring> +#include <optional> + +#include "chre/core/event_loop_manager.h" +#include "chre/util/dynamic_vector.h" +#include "chre/util/system/message_common.h" +#include "chre/util/system/message_router.h" +#include "chre/util/system/napp_permissions.h" +#include "chre_api/chre/event.h" + +#include "pw_allocator/allocator.h" +#include "pw_allocator/libc_allocator.h" +#include "pw_allocator/unique_ptr.h" +#include "pw_function/function.h" + +#include "gtest/gtest.h" +#include "inc/test_util.h" +#include "test_base.h" +#include "test_util.h" + +namespace chre::message { +namespace { + +constexpr size_t kNumEndpoints = 3; +constexpr size_t kMessageSize = 5; +constexpr MessageHubId kOtherMessageHubId = 0xDEADBEEFBEEFDEAD; + +EndpointInfo kEndpointInfos[kNumEndpoints] = { + EndpointInfo(/* id= */ 1, /* name= */ "endpoint1", /* version= */ 1, + EndpointType::NANOAPP, CHRE_MESSAGE_PERMISSION_NONE), + EndpointInfo(/* id= */ 2, /* name= */ "endpoint2", /* version= */ 10, + EndpointType::HOST_NATIVE, CHRE_MESSAGE_PERMISSION_BLE), + EndpointInfo(/* id= */ 3, /* name= */ "endpoint3", /* version= */ 100, + EndpointType::GENERIC, CHRE_MESSAGE_PERMISSION_AUDIO)}; + +//! Base class for MessageHubCallbacks used in tests +class MessageHubCallbackBase : public MessageRouter::MessageHubCallback { + public: + void forEachEndpoint( + const pw::Function<bool(const EndpointInfo &)> &function) override { + for (const EndpointInfo &endpointInfo : kEndpointInfos) { + if (function(endpointInfo)) { + return; + } + } + } + + std::optional<EndpointInfo> getEndpointInfo(EndpointId endpointId) override { + for (const EndpointInfo &endpointInfo : kEndpointInfos) { + if (endpointInfo.id == endpointId) { + return endpointInfo; + } + } + return std::nullopt; + } +}; + +//! MessageHubCallback that stores the data passed to onMessageReceived and +//! onSessionClosed +class MessageHubCallbackStoreData : public MessageHubCallbackBase { + public: + MessageHubCallbackStoreData(Message *message, Session *session) + : mMessage(message), mSession(session) {} + + bool onMessageReceived(pw::UniquePtr<std::byte[]> &&data, size_t length, + uint32_t messageType, uint32_t messagePermissions, + const Session &session, + bool sentBySessionInitiator) override { + if (mMessage != nullptr) { + mMessage->sender = + sentBySessionInitiator ? session.initiator : session.peer; + mMessage->recipient = + sentBySessionInitiator ? session.peer : session.initiator; + mMessage->sessionId = session.sessionId; + mMessage->data = std::move(data); + mMessage->length = length; + mMessage->messageType = messageType; + mMessage->messagePermissions = messagePermissions; + } + return true; + } + + void onSessionClosed(const Session &session) override { + if (mSession != nullptr) { + *mSession = session; + } + } + + private: + Message *mMessage; + Session *mSession; +}; + +class ChreMessageHubTest : public TestBase {}; + +TEST_F(ChreMessageHubTest, MessageRouterNanoappsAreEndpointsToChreMessageHub) { + class App : public TestNanoapp { + public: + App() : TestNanoapp(TestNanoappInfo{.name = "TEST1", .id = 0x1234}) {} + }; + + uint64_t appId = loadNanoapp(MakeUnique<App>()); + + std::optional<EndpointInfo> endpointInfoForApp = + MessageRouterSingleton::get()->getEndpointInfo( + EventLoopManagerSingleton::get() + ->getChreMessageHubManager() + .kChreMessageHubId, + appId); + ASSERT_TRUE(endpointInfoForApp.has_value()); + + Nanoapp *nanoapp = getNanoappByAppId(appId); + ASSERT_NE(nanoapp, nullptr); + + EXPECT_EQ(endpointInfoForApp->id, nanoapp->getAppId()); + EXPECT_STREQ(endpointInfoForApp->name, nanoapp->getAppName()); + EXPECT_EQ(endpointInfoForApp->version, nanoapp->getAppVersion()); + EXPECT_EQ(endpointInfoForApp->type, EndpointType::NANOAPP); + EXPECT_EQ(endpointInfoForApp->requiredPermissions, + nanoapp->getAppPermissions()); +} + +TEST_F(ChreMessageHubTest, + MessageRouterMultipleNanoappsAreEndpointsToChreMessageHub) { + class App : public TestNanoapp { + public: + App() : TestNanoapp(TestNanoappInfo{.name = "TEST1", .id = 0x1234}) {} + }; + + class App2 : public TestNanoapp { + public: + App2() : TestNanoapp(TestNanoappInfo{.name = "TEST2", .id = 0x2}) {} + }; + + uint64_t appId = loadNanoapp(MakeUnique<App>()); + uint64_t appId2 = loadNanoapp(MakeUnique<App2>()); + constexpr size_t kNumNanoapps = 2; + Nanoapp *nanoapps[kNumNanoapps] = {getNanoappByAppId(appId), + getNanoappByAppId(appId2)}; + ASSERT_NE(nanoapps[0], nullptr); + ASSERT_NE(nanoapps[1], nullptr); + + DynamicVector<EndpointInfo> endpointInfos; + EXPECT_TRUE(MessageRouterSingleton::get()->forEachEndpointOfHub( + EventLoopManagerSingleton::get() + ->getChreMessageHubManager() + .kChreMessageHubId, + [&endpointInfos](const EndpointInfo &endpointInfo) { + endpointInfos.push_back(endpointInfo); + return false; + })); + EXPECT_EQ(endpointInfos.size(), 2); + + // Endpoint information should be nanoapp information + for (size_t i = 0; i < kNumNanoapps; ++i) { + EXPECT_EQ(endpointInfos[i].id, nanoapps[i]->getAppId()); + EXPECT_STREQ(endpointInfos[i].name, nanoapps[i]->getAppName()); + EXPECT_EQ(endpointInfos[i].version, nanoapps[i]->getAppVersion()); + EXPECT_EQ(endpointInfos[i].type, EndpointType::NANOAPP); + EXPECT_EQ(endpointInfos[i].requiredPermissions, + nanoapps[i]->getAppPermissions()); + } +} + +//! Nanoapp used to test sending messages from a generic endpoint to a nanoapp +class MessageTestApp : public TestNanoapp { + public: + MessageTestApp(std::mutex &mutex, std::condition_variable &condVar, + bool &messageReceivedAndValidated, bool &sessionClosed, + const TestNanoappInfo &info) + : TestNanoapp(info), + mMutex(mutex), + mCondVar(condVar), + mMessageReceivedAndValidated(messageReceivedAndValidated), + mSessionClosed(sessionClosed) {} + + void handleEvent(uint32_t, uint16_t eventType, + const void *eventData) override { + switch (eventType) { + case CHRE_EVENT_MESSAGE_FROM_ENDPOINT: { + { + std::unique_lock<std::mutex> lock(mMutex); + auto *message = + static_cast<const struct chreMessageFromEndpointData *>( + eventData); + EXPECT_EQ(message->messageType, 1); + EXPECT_EQ(message->messagePermissions, 0); + EXPECT_EQ(message->messageSize, kMessageSize); + + auto *messageData = static_cast<const std::byte *>(message->message); + for (size_t i = 0; i < kMessageSize; ++i) { + EXPECT_EQ(messageData[i], static_cast<std::byte>(i + 1)); + } + mMessageReceivedAndValidated = true; + } + mCondVar.notify_one(); + break; + } + case CHRE_EVENT_ENDPOINT_SESSION_CLOSED: { + { + std::unique_lock<std::mutex> lock(mMutex); + auto *session = + static_cast<const struct chreEndpointSessionClosedData *>( + eventData); + EXPECT_EQ(session->hubId, kOtherMessageHubId); + EXPECT_EQ(session->endpointId, kEndpointInfos[0].id); + mSessionClosed = true; + } + mCondVar.notify_one(); + break; + } + default: { + break; + } + } + } + + std::mutex &mMutex; + std::condition_variable &mCondVar; + bool &mMessageReceivedAndValidated; + bool &mSessionClosed; +}; + +TEST_F(ChreMessageHubTest, MessageRouterSendMessageToNanoapp) { + constexpr uint64_t kNanoappId = 0x1234; + std::mutex mutex; + std::condition_variable condVar; + bool messageReceivedAndValidated = false; + bool sessionClosed = false; + + pw::allocator::LibCAllocator allocator = pw::allocator::GetLibCAllocator(); + pw::UniquePtr<std::byte[]> messageData = + allocator.MakeUniqueArray<std::byte>(kMessageSize); + for (size_t i = 0; i < kMessageSize; ++i) { + messageData[i] = static_cast<std::byte>(i + 1); + } + + // Load the nanoapp + uint64_t appId = loadNanoapp(MakeUnique<MessageTestApp>( + mutex, condVar, messageReceivedAndValidated, sessionClosed, + TestNanoappInfo{.name = "TEST1", .id = kNanoappId})); + + // Create the other hub + MessageHubCallbackStoreData callback(/* message= */ nullptr, + /* session= */ nullptr); + std::optional<MessageRouter::MessageHub> messageHub = + MessageRouterSingleton::get()->registerMessageHub( + "OTHER_TEST_HUB", kOtherMessageHubId, callback); + ASSERT_TRUE(messageHub.has_value()); + + // Open the session from the other hub:1 to the nanoapp + SessionId sessionId = + messageHub->openSession(kEndpointInfos[0].id, + EventLoopManagerSingleton::get() + ->getChreMessageHubManager() + .kChreMessageHubId, + kNanoappId); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Send the message to the nanoapp + std::unique_lock<std::mutex> lock(mutex); + ASSERT_TRUE(messageHub->sendMessage(std::move(messageData), kMessageSize, + /* messageType= */ 1, + /* messagePermissions= */ 0, sessionId)); + condVar.wait(lock); + EXPECT_TRUE(messageReceivedAndValidated); + + // Close the session + EXPECT_TRUE(messageHub->closeSession(sessionId)); + condVar.wait(lock); + EXPECT_TRUE(sessionClosed); +} + +class MessagePermissionTestApp : public MessageTestApp { + public: + MessagePermissionTestApp(std::mutex &mutex, std::condition_variable &condVar, + bool &messageReceivedAndValidated, + bool &sessionClosed, const TestNanoappInfo &info) + : MessageTestApp(mutex, condVar, messageReceivedAndValidated, + sessionClosed, info) {} +}; + +TEST_F(ChreMessageHubTest, MessageRouterSendMessageToNanoappPermissionFailure) { + CREATE_CHRE_TEST_EVENT(TRIGGER_COND_VAR, 0); + + constexpr uint64_t kNanoappId = 0x1234; + std::mutex mutex; + std::condition_variable condVar; + bool messageReceivedAndValidated = false; + bool sessionClosed = false; + + pw::allocator::LibCAllocator allocator = pw::allocator::GetLibCAllocator(); + pw::UniquePtr<std::byte[]> messageData = + allocator.MakeUniqueArray<std::byte>(kMessageSize); + for (size_t i = 0; i < kMessageSize; ++i) { + messageData[i] = static_cast<std::byte>(i + 1); + } + + // Load the nanoapp + uint64_t appId = loadNanoapp(MakeUnique<MessagePermissionTestApp>( + mutex, condVar, messageReceivedAndValidated, sessionClosed, + TestNanoappInfo{ + .name = "TEST1", .id = kNanoappId, .perms = CHRE_PERMS_BLE})); + + // Create the other hub + MessageHubCallbackStoreData callback(/* message= */ nullptr, + /* session= */ nullptr); + std::optional<MessageRouter::MessageHub> messageHub = + MessageRouterSingleton::get()->registerMessageHub( + "OTHER_TEST_HUB", kOtherMessageHubId, callback); + ASSERT_TRUE(messageHub.has_value()); + + // Open the session from the other hub:1 to the nanoapp + SessionId sessionId = + messageHub->openSession(kEndpointInfos[0].id, + EventLoopManagerSingleton::get() + ->getChreMessageHubManager() + .kChreMessageHubId, + kNanoappId); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Send the message to the nanoapp + std::unique_lock<std::mutex> lock(mutex); + ASSERT_TRUE(messageHub->sendMessage( + std::move(messageData), kMessageSize, + /* messageType= */ 1, + /* messagePermissions= */ CHRE_PERMS_AUDIO | CHRE_PERMS_GNSS, sessionId)); + + // Send the trigger cond var event, which will be handled after the + // CHRE message from endpoint event (if it is sent erroneously). If the + // message event is not sent, this event will unlock the condition variable. + // If the message event is sent, the condition variable will be unlocked + // after the message event is processed, setting the + // messageReceivedAndValidated variable to true, which will fail the test. + sendEventToNanoapp(appId, TRIGGER_COND_VAR); + condVar.wait(lock); + EXPECT_FALSE(messageReceivedAndValidated); + EXPECT_TRUE(sessionClosed); +} + +} // namespace +} // namespace chre::message
diff --git a/test/simulation/inc/test_base.h b/test/simulation/inc/test_base.h index 6638cd6..2b5dd0a 100644 --- a/test/simulation/inc/test_base.h +++ b/test/simulation/inc/test_base.h
@@ -25,6 +25,7 @@ #include "chre/core/nanoapp.h" #include "chre/platform/system_time.h" #include "chre/platform/system_timer.h" +#include "chre/util/system/message_router.h" #include "chre/util/time.h" #include "test_event_queue.h" @@ -126,6 +127,7 @@ MemberInitLogger mInitLogger; std::thread mChreThread; SystemTimer mSystemTimer; + message::MessageRouter::MessageHub mChreMessageHub; }; } // namespace chre
diff --git a/test/simulation/inc/test_event_queue.h b/test/simulation/inc/test_event_queue.h index 03c1364..0b22f7a 100644 --- a/test/simulation/inc/test_event_queue.h +++ b/test/simulation/inc/test_event_queue.h
@@ -22,10 +22,10 @@ #include <cinttypes> #include "chre/platform/memory.h" -#include "chre/util/fixed_size_blocking_queue.h" #include "chre/util/memory.h" #include "chre/util/non_copyable.h" #include "chre/util/singleton.h" +#include "chre/util/system/fixed_size_blocking_queue.h" #include "test_event.h" namespace chre {
diff --git a/test/simulation/test_base.cc b/test/simulation/test_base.cc index 5c0329e..985295f 100644 --- a/test/simulation/test_base.cc +++ b/test/simulation/test_base.cc
@@ -17,18 +17,33 @@ #include "test_base.h" #include <gtest/gtest.h> +#include <pw_containers/vector.h> #include "chre/core/event_loop_manager.h" #include "chre/core/init.h" #include "chre/platform/linux/platform_log.h" #include "chre/platform/linux/task_util/task_manager.h" +#include "chre/util/system/message_router.h" #include "chre/util/time.h" #include "chre_api/chre/version.h" #include "inc/test_util.h" #include "test_util.h" +using ::chre::message::MessageRouter; +using ::chre::message::MessageRouterSingleton; +using ::chre::message::Session; + namespace chre { +namespace { + +constexpr size_t kMaxMessageHubs = 2; +constexpr size_t kMaxSessions = 25; +pw::Vector<MessageRouter::MessageHubRecord, kMaxMessageHubs> gMessageHubs; +pw::Vector<Session, kMaxSessions> gSessions; + +} // anonymous namespace + /** * This base class initializes and runs the event loop. * @@ -44,14 +59,10 @@ * this test. */ void TestBase::SetUp() { - // TODO(b/346903946): remove these extra prints once init failure is resolved - printf("SetUp(): log\n"); + MessageRouterSingleton::init(gMessageHubs, gSessions); chre::PlatformLogSingleton::init(); - printf("SetUp(): TaskManager\n"); TaskManagerSingleton::init(); - printf("SetUp(): TestEventQueue\n"); TestEventQueueSingleton::init(); - printf("SetUp(): CHRE\n"); chre::init(); EventLoopManagerSingleton::get()->lateInit(); @@ -67,7 +78,6 @@ ASSERT_TRUE(mSystemTimer.init()); ASSERT_TRUE(mSystemTimer.set(callback, nullptr /*data*/, Nanoseconds(getTimeoutNs()))); - printf("SetUp() complete\n"); } void TestBase::TearDown() { @@ -83,6 +93,7 @@ deleteNanoappInfos(); unregisterAllTestNanoapps(); chre::PlatformLogSingleton::deinit(); + MessageRouterSingleton::deinit(); } TEST_F(TestBase, CanLoadAndStartSingleNanoapp) {
diff --git a/tools/common.sh b/tools/common.sh new file mode 100644 index 0000000..65d68cb --- /dev/null +++ b/tools/common.sh
@@ -0,0 +1,105 @@ +trap 'onExit $?' EXIT + +onExit() { + if [ "$1" != "0" ]; then + echo -e "\e[31m" + echo " ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ " + echo "▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌" + echo "▐░█▀▀▀▀▀▀▀▀▀ ▐░█▀▀▀▀▀▀▀█░▌▐░█▀▀▀▀▀▀▀█░▌▐░█▀▀▀▀▀▀▀█░▌▐░█▀▀▀▀▀▀▀█░▌" + echo "▐░▌ ▐░▌ ▐░▌▐░▌ ▐░▌▐░▌ ▐░▌▐░▌ ▐░▌" + echo "▐░█▄▄▄▄▄▄▄▄▄ ▐░█▄▄▄▄▄▄▄█░▌▐░█▄▄▄▄▄▄▄█░▌▐░▌ ▐░▌▐░█▄▄▄▄▄▄▄█░▌" + echo "▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░▌ ▐░▌▐░░░░░░░░░░░▌" + echo "▐░█▀▀▀▀▀▀▀▀▀ ▐░█▀▀▀▀█░█▀▀ ▐░█▀▀▀▀█░█▀▀ ▐░▌ ▐░▌▐░█▀▀▀▀█░█▀▀ " + echo "▐░▌ ▐░▌ ▐░▌ ▐░▌ ▐░▌ ▐░▌ ▐░▌▐░▌ ▐░▌ " + echo "▐░█▄▄▄▄▄▄▄▄▄ ▐░▌ ▐░▌ ▐░▌ ▐░▌ ▐░█▄▄▄▄▄▄▄█░▌▐░▌ ▐░▌ " + echo "▐░░░░░░░░░░░▌▐░▌ ▐░▌▐░▌ ▐░▌▐░░░░░░░░░░░▌▐░▌ ▐░▌" + echo " ▀▀▀▀▀▀▀▀▀▀▀ ▀ ▀ ▀ ▀ ▀▀▀▀▀▀▀▀▀▀▀ ▀ ▀ " + echo " " + echo -e "\e[0m" + fi +} + +onSuccess() { + echo -e "\e[92m\n" + echo "" + echo " ██████ ██ ██ ██ " + echo " ██ ██ ██ ██ ██ " + echo " ██ ██ █████ ██ " + echo " ██ ██ ██ ██ " + echo " ██████ ██ ██ ██ " + echo "" + echo -e "\e[0m" +} + +onWarning() { + echo -e "\e[33m\n" + echo " █████ ███ █████ █████████ ███████████ ██████ █████ █████ ██████ █████ █████████ " + echo " ░░███ ░███ ░░███ ███░░░░░███ ░░███░░░░░███ ░░██████ ░░███ ░░███ ░░██████ ░░███ ███░░░░░███ " + echo " ░███ ░███ ░███ ░███ ░███ ░███ ░███ ░███░███ ░███ ░███ ░███░███ ░███ ███ ░░░ " + echo " ░███ ░███ ░███ ░███████████ ░██████████ ░███░░███░███ ░███ ░███░░███░███ ░███ " + echo " ░░███ █████ ███ ░███░░░░░███ ░███░░░░░███ ░███ ░░██████ ░███ ░███ ░░██████ ░███ █████ " + echo " ░░░█████░█████░ ░███ ░███ ░███ ░███ ░███ ░░█████ ░███ ░███ ░░█████ ░░███ ░░███ " + echo " ░░███ ░░███ █████ █████ █████ █████ █████ ░░█████ █████ █████ ░░█████ ░░█████████ " + echo " ░░░ ░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░░░░░ " + echo -e "\e[0m" +} + +doRemount() { + $ADB root + sleep 3 + set +e + REMOUNT_OUTPUT="$($ADB remount -R 2>&1)" + REMOUNT_OUTPUT="${REMOUNT_OUTPUT,,}" + REMOUNT_RESULT=$? + echo "$REMOUNT_OUTPUT" + if [[ $REMOUNT_RESULT != 0 || "$REMOUNT_OUTPUT" == *"remount failed"* ]]; then + exit 1 + fi + set -e + if [[ "$REMOUNT_OUTPUT" == *"rebooting"* ]] + then + echo -e "\e[93m" + echo "██████╗ ███████╗██████╗ ██████╗ ██████╗ ████████╗██╗███╗ ██╗ ██████╗ " + echo "██╔══██╗██╔════╝██╔══██╗██╔═══██╗██╔═══██╗╚══██╔══╝██║████╗ ██║██╔════╝ " + echo "██████╔╝█████╗ ██████╔╝██║ ██║██║ ██║ ██║ ██║██╔██╗ ██║██║ ███╗" + echo "██╔══██╗██╔══╝ ██╔══██╗██║ ██║██║ ██║ ██║ ██║██║╚██╗██║██║ ██║" + echo "██║ ██║███████╗██████╔╝╚██████╔╝╚██████╔╝ ██║ ██║██║ ╚████║╚██████╔╝" + echo "╚═╝ ╚═╝╚══════╝╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ " + echo " " + echo -e "\e[0m" + sleep 5 + $ADB wait-for-device root && $ADB wait-for-device remount + fi +} + +connectedProduct() { + echo "$($ADB shell getprop ro.build.product)" +} + +checkConnectedProduct() { + checkDeviceRev + + # Make sure connected device matches $TARGET_PRODUCT + CONNECTED_PRODUCT="$(connectedProduct)" + if [ "$TARGET_PRODUCT" != "$CONNECTED_PRODUCT" ] + then + echo "ERROR: Connected device ($CONNECTED_PRODUCT) does not match TARGET_PRODUCT. Please lunch $CONNECTED_PRODUCT first" + exit 1 + fi +} + +checkDeviceRev() { + set +e + GETPROP_OUTPUT="$($ADB shell getprop ro.boot.hardware.revision 2>&1)" + GETPROP_RESULT=$? + if [ $GETPROP_RESULT -ne 0 ] + then + echo "Cannot check device status via adb, please check device connection" + exit 1 + elif [[ "$GETPROP_OUTPUT" =~ ^([DP]VT|MP).* ]] + then + echo "Device must be EVT or earlier for CHRE development" + exit 1 + fi + set -e +}
diff --git a/tools/find_improper_target_platform_files.py b/tools/find_improper_target_platform_files.py new file mode 100644 index 0000000..6b6bbd1 --- /dev/null +++ b/tools/find_improper_target_platform_files.py
@@ -0,0 +1,101 @@ +"""Finds header files in target_platform directories that should not be + +Some platform implementations have improperly used target_platform when they +should instead use platform/<platform_name>. This script helps identify those +files. + +Example usage: + + python find_improper_target_platform_files.py -p ../platform -c ../platform/include +""" +import argparse +import os +import sys + +def find_target_platform_files(directories): + """ + Lists all files recursively in the given directories and filters to those with + "target_platform" in their path. + + Args: + directories: A list of directories to search. + + Returns: + A list of file paths that contain "target_platform" in their path. + """ + target_files = [] + for directory in directories: + for root, _, files in os.walk(directory): + for file in files: + file_path = os.path.join(root, file) + if "target_platform" in file_path: + target_files.append(file_path) + return target_files + +def find_unincluded_files(target_files, include_directories): + """ + Flags target_platform files that are not included in any C/C++ #include + statements within files in the include_directories. + + Args: + target_files: A list of file paths to check. + include_directories: A list of directories containing files with + #include statements. + + Returns: + A list of target_platform file paths that are not included. + """ + unincluded_files = [] + included_files = set() + + for directory in include_directories: + for root, _, files in os.walk(directory): + for file in files: + file_path = os.path.join(root, file) + try: + with open(file_path, "r") as f: + for line in f: + if line.startswith("#include") and "target_platform" in line: + # Extract the included file name, accounting for variations in + # include syntax (e.g., quotes vs. angle brackets) + included_file = line.split()[1].strip('"<>') + included_files.add(included_file) + except UnicodeDecodeError: + # Skip non-text files + continue + + print(f"target_platform files referenced in {include_directories}:") + for file in sorted(included_files): + print(f" {file}") + + + for target_file in target_files: + target_file_name = "target_platform/" + os.path.basename(target_file) + found = False + for included_file in included_files: + if included_file.endswith(target_file_name): + found = True + break + if not found: + unincluded_files.append(target_file) + + return unincluded_files + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Find files in target_platform directories which are not included from common code.") + parser.add_argument("-p", "--platform", nargs="+", required=True, help="Directories containing target_platform subdirectories") + parser.add_argument("-c", "--common", nargs="+", required=True, help="Directories containing facades to platform code - all target_platform headers must appear in an #include statement in a file here") + args = parser.parse_args() + + target_directories = args.platform + include_directories = args.common + + target_files = find_target_platform_files(target_directories) + unincluded_files = find_unincluded_files(target_files, include_directories) + + if len(unincluded_files): + print("\nThe following target_platform files do not appear in the list above:") + for file in sorted(unincluded_files): + print(f" {file}") + else: + print("All target_platform files are included.")
diff --git a/tools/tinysys_nanoapp_signer.py b/tools/tinysys_nanoapp_signer.py new file mode 100755 index 0000000..9d57f6e --- /dev/null +++ b/tools/tinysys_nanoapp_signer.py
@@ -0,0 +1,125 @@ +#!/usr/bin/python + +# +# Copyright 2024, The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +"""A script to sign nanoapps for testing purpose on tinysys platforms.""" + +import argparse +import ctypes +import hashlib +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import ec +from cryptography.hazmat.primitives.asymmetric import utils + + +class HeaderInfo(ctypes.LittleEndianStructure): + _fields_ = [ + ("magic_number", ctypes.c_uint32), + ("header_version", ctypes.c_uint32), + ("rollback_info", ctypes.c_uint32), + ("binary_length", ctypes.c_uint32), + ("flags", ctypes.c_uint64 * 2), + ("binary_sha256", ctypes.c_uint8 * 32), + ("reserved_chip_id", ctypes.c_uint8 * 32), + ("reserved_auth_config", ctypes.c_uint8 * 256), + ("reserved_image_config", ctypes.c_uint8 * 256), + ] + + +def read_private_key(key_file, password): + with open(key_file, "rb") as file: + key_bytes = file.read() + try: + return serialization.load_der_private_key(key_bytes, password=password) + except ValueError as e: + pass # Not a DER private key + + try: + return serialization.load_pem_private_key(key_bytes, password=password) + except ValueError: + pass # Not a PEM private key + raise ValueError("Unable to parse the key file as DER or PEM") + + +def main(): + + parser = argparse.ArgumentParser( + description="Sign a binary to be authenticated on tinysys platforms" + ) + parser.add_argument( + "private_key_file", + help="The private key (DER or PEM format) used to sign the binary", + ) + parser.add_argument( + "-p", + "--password", + type=str, + help="Optional password encrypting the private key", + ) + parser.add_argument( + "nanoapp", help="The name of the nanoapp binary file to be signed" + ) + parser.add_argument( + "output_path", help="The path where the signed binary should be stored" + ) + args = parser.parse_args() + + # Load the binary file. + binary_data = None + with open(args.nanoapp, "rb") as binary_file: + binary_data = binary_file.read() + + # Load ECDSA private key. + password = args.password.encode() if args.password else None + private_key = read_private_key(args.private_key_file, password) + + # Generate a zero-filled header. + header = bytearray(0x1000) + + # Fill the public key. + public_key_numbers = private_key.public_key().public_numbers() + header[0x200:0x220] = public_key_numbers.x.to_bytes(32, "big") + header[0x220:0x240] = public_key_numbers.y.to_bytes(32, "big") + + # Fill header_info. + sha256_hasher = hashlib.sha256() + sha256_hasher.update(binary_data) + header_info = HeaderInfo( + magic_number=0x45524843, + header_version=1, + binary_length=len(binary_data), + binary_sha256=(ctypes.c_uint8 * 32)(*sha256_hasher.digest()), + ) + header_info_bytes = bytes(header_info) + header[0x400 : 0x400 + len(header_info_bytes)] = header_info_bytes + + # Generate the signature. + signature = private_key.sign(header[0x200:], ec.ECDSA(hashes.SHA256())) + r, s = utils.decode_dss_signature(signature) + r_bytes = r.to_bytes(32, "big") + s_bytes = s.to_bytes(32, "big") + header[:32] = r_bytes + header[32:64] = s_bytes + + with open(f"{args.output_path}/{args.nanoapp}", "wb") as output: + output.write(header) + output.write(binary_data) + + +if __name__ == "__main__": + main()
diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt new file mode 100644 index 0000000..3d4554f --- /dev/null +++ b/util/CMakeLists.txt
@@ -0,0 +1,201 @@ +include($ENV{PW_ROOT}/pw_build/pigweed.cmake) + +pw_add_library(chre.util STATIC + HEADERS + include/chre/util/always_false.h + include/chre/util/array_queue.h + include/chre/util/array_queue_impl.h + include/chre/util/blocking_segmented_queue.h + include/chre/util/buffer.h + include/chre/util/buffer_base.h + include/chre/util/conditional_lock_guard.h + include/chre/util/conditional_lock_guard_impl.h + include/chre/util/container_support.h + include/chre/util/copyable_fixed_size_vector.h + include/chre/util/duplicate_message_detector.h + include/chre/util/dynamic_vector.h + include/chre/util/dynamic_vector_base.h + include/chre/util/dynamic_vector_impl.h + include/chre/util/enum.h + include/chre/util/fixed_size_vector.h + include/chre/util/fixed_size_vector_impl.h + include/chre/util/fragmentation_manager.h + include/chre/util/fragmentation_manager_impl.h + include/chre/util/hash.h + include/chre/util/heap.h + include/chre/util/heap_impl.h + include/chre/util/host/assert.h + include/chre/util/intrusive_list.h + include/chre/util/intrusive_list_base.h + include/chre/util/intrusive_list_impl.h + include/chre/util/lock_guard.h + include/chre/util/lock_guard_impl.h + include/chre/util/log_common.h + include/chre/util/macros.h + include/chre/util/memory.h + include/chre/util/memory_impl.h + include/chre/util/memory_pool.h + include/chre/util/memory_pool_impl.h + include/chre/util/nested_data_ptr.h + include/chre/util/non_copyable.h + include/chre/util/optional.h + include/chre/util/optional_impl.h + include/chre/util/priority_queue.h + include/chre/util/priority_queue_impl.h + include/chre/util/raw_storage.h + include/chre/util/scope_timer.h + include/chre/util/scope_timer_impl.h + include/chre/util/segmented_queue.h + include/chre/util/segmented_queue_impl.h + include/chre/util/singleton.h + include/chre/util/singleton_impl.h + include/chre/util/throttle.h + include/chre/util/time.h + include/chre/util/time_impl.h + include/chre/util/toolchain.h + include/chre/util/unique_ptr.h + include/chre/util/unique_ptr_impl.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.chre_api + chre.platform.assert + chre.platform.memory + chre.platform.system_time + chre.util.nanoapp + chre.variant.config + + # TODO(b/376249597) Move the synchronized expandable memory pool, fixed + # size blocking queue, and synchronized memory pool to chre.util.system. + chre.platform.condition_variable + chre.platform.mutex + SOURCES + buffer_base.cc + duplicate_message_detector.cc + dynamic_vector_base.cc + hash.cc + intrusive_list_base.cc +) + +pw_add_library(chre.util.flatbuffers INTERFACE + HEADERS + include/chre/util/flatbuffers/helpers.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.util + chre.variant.config + chre_third_party.flatbuffers +) + +pw_add_library(chre.util.host INTERFACE + HEADERS + include/chre/util/host/assert.h + PUBLIC_INCLUDES + include +) + + +pw_add_library(chre.util.nanoapp STATIC + HEADERS + include/chre/util/nanoapp/app_id.h + include/chre/util/nanoapp/assert.h + include/chre/util/nanoapp/audio.h + include/chre/util/nanoapp/ble.h + include/chre/util/nanoapp/callbacks.h + include/chre/util/nanoapp/debug.h + include/chre/util/nanoapp/log.h + include/chre/util/nanoapp/math.h + include/chre/util/nanoapp/string.h + include/chre/util/nanoapp/tagged_log.h + include/chre/util/nanoapp/wifi.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.chre_api + chre.platform.assert + chre.platform.log + chre.util + chre.variant.config + pw_tokenizer + SOURCES + nanoapp/audio.cc + nanoapp/ble.cc + nanoapp/callbacks.cc + nanoapp/debug.cc + nanoapp/string.cc + nanoapp/wifi.cc +) + +pw_add_library(chre.util.pigweed STATIC + HEADERS + include/chre/util/pigweed/chre_channel_output.h + include/chre/util/pigweed/permission.h + include/chre/util/pigweed/rpc_client.h + include/chre/util/pigweed/rpc_common.h + include/chre/util/pigweed/rpc_helper.h + include/chre/util/pigweed/rpc_server.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.chre_api + chre.util + chre.util.nanoapp + chre.variant.config + pw_rpc.client + pw_rpc.common + pw_rpc.server + pw_span + SOURCES + pigweed/chre_channel_output.cc + pigweed/rpc_client.cc + pigweed/rpc_helper.cc + pigweed/rpc_server.cc + PRIVATE_DEPS + pw_status +) + +pw_add_library(chre.util.system STATIC + HEADERS + include/chre/util/system/atomic_spsc_queue.h + include/chre/util/system/ble_util.h + include/chre/util/system/debug_dump.h + include/chre/util/system/event_callbacks.h + include/chre/util/system/fixed_size_blocking_queue.h + include/chre/util/system/fixed_size_blocking_queue_impl.h + include/chre/util/system/message_common.h + include/chre/util/system/message_router.h + include/chre/util/system/napp_header_utils.h + include/chre/util/system/napp_permissions.h + include/chre/util/system/ref_base.h + include/chre/util/system/shared_ptr.h + include/chre/util/system/shared_ptr_impl.h + include/chre/util/system/synchronized_expandable_memory_pool.h + include/chre/util/system/synchronized_expandable_memory_pool_impl.h + include/chre/util/system/synchronized_memory_pool.h + include/chre/util/system/synchronized_memory_pool_impl.h + include/chre/util/system/stats_container.h + include/chre/util/system/transaction_manager.h + include/chre/util/system/transaction_manager_impl.h + include/chre/util/system/wifi_util.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + chre.chre_api + chre.core + chre.platform.assert + chre.platform.atomic + chre.platform.memory + chre.platform.mutex + chre.platform.system_time + chre.util + chre.variant.config + pw_allocator.deallocator + SOURCES + system/ble_util.cc + system/event_callbacks.cc + system/debug_dump.cc + system/message_router.cc + PRIVATE_DEPS + chre.platform.log +)
diff --git a/util/include/chre/util/blocking_segmented_queue.h b/util/include/chre/util/blocking_segmented_queue.h index 92d8dea..5ac45e2 100644 --- a/util/include/chre/util/blocking_segmented_queue.h +++ b/util/include/chre/util/blocking_segmented_queue.h
@@ -17,8 +17,8 @@ #ifndef CHRE_UTIL_BLOCKING_SEGMENTED_QUEUE_H_ #define CHRE_UTIL_BLOCKING_SEGMENTED_QUEUE_H_ -#include "chre/util/fixed_size_blocking_queue.h" #include "chre/util/segmented_queue.h" +#include "chre/util/system/fixed_size_blocking_queue.h" namespace chre { /** * Similar but memory efficient version of chre::FixedSizeBlockingQueue.
diff --git a/util/include/chre/util/intrusive_list.h b/util/include/chre/util/intrusive_list.h index 4a394d1..a74fa9c 100644 --- a/util/include/chre/util/intrusive_list.h +++ b/util/include/chre/util/intrusive_list.h
@@ -110,7 +110,7 @@ using Node = ::chre::intrusive_list_internal::Node; public: - Iterator(Node *node) : mNode(node){}; + Iterator(Node *node) : mNode(node) {} ListNode<ElementType> &operator*() const { return *reinterpret_cast<ListNode<ElementType> *>(mNode);
diff --git a/util/include/chre/util/log_common.h b/util/include/chre/util/log_common.h index 3032650..e00442a 100644 --- a/util/include/chre/util/log_common.h +++ b/util/include/chre/util/log_common.h
@@ -61,6 +61,6 @@ /** * Logs an out of memory error with file and line number. */ -#define LOG_OOM() LOGE("OOM at %s:%d", CHRE_FILENAME, __LINE__) +#define LOG_OOM() LOGE("OOM at " CHRE_FILENAME ":%d", __LINE__) #endif // CHRE_UTIL_LOG_COMMON_H_
diff --git a/util/include/chre/util/memory_impl.h b/util/include/chre/util/memory_impl.h index 96f08ca..fc5e6e2 100644 --- a/util/include/chre/util/memory_impl.h +++ b/util/include/chre/util/memory_impl.h
@@ -18,6 +18,7 @@ #define CHRE_UTIL_MEMORY_IMPL_H_ // IWYU pragma: private +#include <cstddef> #include <cstring> #include <new> #include <type_traits>
diff --git a/util/include/chre/util/nanoapp/assert.h b/util/include/chre/util/nanoapp/assert.h index ddc7afe..f4dbb85 100644 --- a/util/include/chre/util/nanoapp/assert.h +++ b/util/include/chre/util/nanoapp/assert.h
@@ -37,7 +37,7 @@ #define CHRE_ASSERT(condition) \ do { \ if (!(condition)) { \ - chreLog(CHRE_LOG_ERROR, "CHRE_ASSERT at %s:%d", CHRE_FILENAME, \ + chreLog(CHRE_LOG_ERROR, "CHRE_ASSERT at " CHRE_FILENAME ":%d", \ __LINE__); \ chreAbort(UINT32_MAX); \ } \
diff --git a/util/include/chre/util/nanoapp/ble.h b/util/include/chre/util/nanoapp/ble.h index fade65a..475d669 100644 --- a/util/include/chre/util/nanoapp/ble.h +++ b/util/include/chre/util/nanoapp/ble.h
@@ -48,6 +48,17 @@ /** Length of Google manufacturer data filter. */ constexpr uint16_t kGoogleManufactureDataLength = 4; +/** + * The public address of the known (bonded) BLE advertiser in big endian byte + * order. Change this address to the public identity address of the advertiser + * in the test. + * + * Example: To filter on the address (01:02:03:AB:CD:EF), use + * {0x01:0x02:0x03:0xAB:0xCD:0xEF}. + */ +constexpr uint8_t kBroadcasterAddress[CHRE_BLE_ADDRESS_LEN] = { + 0x01, 0x02, 0x03, 0xAB, 0xCD, 0xEF}; + /** The Google manufacturer ID followed by some data. */ constexpr uint8_t kGoogleManufactureData[kGoogleManufactureDataLength] = { 0xE0, 0x00, 0xAA, 0xFE}; @@ -58,10 +69,14 @@ /** The number of generic filters (equal to the number of known beacons). */ constexpr uint8_t kNumScanFilters = 2; - /** The number of manufacturer data filters. */ constexpr uint8_t kNumManufacturerDataFilters = 1; +/** + * The number of broadcaster address filters (equal to the number of known + * public advertiser addresses). + */ +constexpr uint8_t kNumBroadcasterFilters = 1; } // namespace ble_constants /** @@ -118,6 +133,24 @@ chreBleGenericFilter *genericFilters, struct chreBleScanFilterV1_9 &filter); +/** + * Creates a chreBleScanFilter that filters for the Google eddystone UUID, + * the Google nearby fastpair UUID, public identity address of a bonded device, + * and a RSSI threshold of kRssiThreshold. + * + * @param filter (out) the output filter. + * @param broadcasterFilters (out) the output broadcaster address filters + * array. + * @param numBroadcasterFilters the size of the broadcaster address filters + * array. must be >= kNumBroadcasterFilters. + * + * @return true the operation was successful + * @return false the operation was not successful + */ +bool createBleScanFilterForAdvertiser( + struct chreBleScanFilterV1_9 &filter, + chreBleBroadcasterAddressFilter *broadcasterFilters, + uint8_t numBroadcasterFilters); } // namespace chre #endif // CHRE_UTIL_NANOAPP_BLE_H_
diff --git a/util/include/chre/util/optional.h b/util/include/chre/util/optional.h index d3fc092..24394cc 100644 --- a/util/include/chre/util/optional.h +++ b/util/include/chre/util/optional.h
@@ -36,7 +36,7 @@ /** * Default constructs the optional object with no initial value. */ - Optional() = default; + constexpr Optional() : mObject() {} /** * Default copy constructor.
diff --git a/util/include/chre/util/fixed_size_blocking_queue.h b/util/include/chre/util/system/fixed_size_blocking_queue.h similarity index 93% rename from util/include/chre/util/fixed_size_blocking_queue.h rename to util/include/chre/util/system/fixed_size_blocking_queue.h index 58277fe..81e631e 100644 --- a/util/include/chre/util/fixed_size_blocking_queue.h +++ b/util/include/chre/util/system/fixed_size_blocking_queue.h
@@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef CHRE_UTIL_FIXED_SIZE_BLOCKING_QUEUE_H_ -#define CHRE_UTIL_FIXED_SIZE_BLOCKING_QUEUE_H_ +#ifndef CHRE_UTIL_SYSTEM_FIXED_SIZE_BLOCKING_QUEUE_H_ +#define CHRE_UTIL_SYSTEM_FIXED_SIZE_BLOCKING_QUEUE_H_ #include <deque> @@ -120,6 +120,6 @@ } // namespace chre -#include "chre/util/fixed_size_blocking_queue_impl.h" // IWYU pragma: export +#include "chre/util/system/fixed_size_blocking_queue_impl.h" // IWYU pragma: export -#endif // CHRE_UTIL_FIXED_SIZE_BLOCKING_QUEUE_H_ +#endif // CHRE_UTIL_SYSTEM_FIXED_SIZE_BLOCKING_QUEUE_H_
diff --git a/util/include/chre/util/fixed_size_blocking_queue_impl.h b/util/include/chre/util/system/fixed_size_blocking_queue_impl.h similarity index 94% rename from util/include/chre/util/fixed_size_blocking_queue_impl.h rename to util/include/chre/util/system/fixed_size_blocking_queue_impl.h index 43911df..adea3f8 100644 --- a/util/include/chre/util/fixed_size_blocking_queue_impl.h +++ b/util/include/chre/util/system/fixed_size_blocking_queue_impl.h
@@ -14,12 +14,12 @@ * limitations under the License. */ -#ifndef CHRE_UTIL_FIXED_SIZE_BLOCKING_QUEUE_IMPL_H_ -#define CHRE_UTIL_FIXED_SIZE_BLOCKING_QUEUE_IMPL_H_ +#ifndef CHRE_UTIL_SYSTEM_FIXED_SIZE_BLOCKING_QUEUE_IMPL_H_ +#define CHRE_UTIL_SYSTEM_FIXED_SIZE_BLOCKING_QUEUE_IMPL_H_ // IWYU pragma: private -#include "chre/util/fixed_size_blocking_queue.h" #include "chre/util/lock_guard.h" +#include "chre/util/system/fixed_size_blocking_queue.h" namespace chre {
diff --git a/util/include/chre/util/system/message_common.h b/util/include/chre/util/system/message_common.h new file mode 100644 index 0000000..f314f32 --- /dev/null +++ b/util/include/chre/util/system/message_common.h
@@ -0,0 +1,205 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CHRE_UTIL_SYSTEM_MESSAGE_COMMON_H_ +#define CHRE_UTIL_SYSTEM_MESSAGE_COMMON_H_ + +#include <pw_allocator/unique_ptr.h> +#include <pw_function/function.h> +#include <cstddef> +#include <cstdint> +#include <cstring> + +namespace chre::message { + +//! The ID of a MessageHub +using MessageHubId = uint64_t; + +//! The ID of an endpoint +using EndpointId = uint64_t; + +//! The ID of a session +using SessionId = uint16_t; + +//! An invalid MessageHub ID +constexpr MessageHubId MESSAGE_HUB_ID_INVALID = 0; + +//! An invalid endpoint ID +constexpr EndpointId ENDPOINT_ID_INVALID = 0; + +//! An invalid session ID +constexpr SessionId SESSION_ID_INVALID = UINT16_MAX; + +//! Endpoint types +enum class EndpointType : uint8_t { + HOST_FRAMEWORK = 1, + HOST_APP = 2, + HOST_NATIVE = 3, + NANOAPP = 4, + GENERIC = 5, +}; + +//! Endpoint permissions +//! This should match CHRE permissions. +// TODO(b/373417024): Update permissions to this typed name in all MessageRouter +// code +enum class EndpointPermission : uint32_t { + NONE = 0, + AUDIO = 1, + GNSS = 1 << 1, + WIFI = 1 << 2, + WWAN = 1 << 3, + BLE = 1 << 4, +}; + +//! Represents a single endpoint connected to a MessageHub +struct Endpoint { + MessageHubId messageHubId; + EndpointId endpointId; + + bool operator==(const Endpoint &other) const { + return messageHubId == other.messageHubId && endpointId == other.endpointId; + } + + bool operator!=(const Endpoint &other) const { + return !(*this == other); + } +}; + +//! Represents a session between two endpoints +struct Session { + SessionId sessionId; + Endpoint initiator; + Endpoint peer; + + bool operator==(const Session &other) const { + return sessionId == other.sessionId && initiator == other.initiator && + peer == other.peer; + } + + bool operator!=(const Session &other) const { + return !(*this == other); + } + + bool isEquivalent(const Session &other) const { + return (initiator == other.initiator && peer == other.peer) || + (initiator == other.peer && peer == other.initiator); + } +}; + +//! Represents a message sent using the MessageRouter +struct Message { + Endpoint sender; + Endpoint recipient; + SessionId sessionId; + pw::UniquePtr<std::byte[]> data; + size_t length; + uint32_t messageType; + uint32_t messagePermissions; + + Message() + : sessionId(SESSION_ID_INVALID), + data(nullptr), + length(0), + messageType(0), + messagePermissions(0) {} + Message(pw::UniquePtr<std::byte[]> &&data, size_t length, + uint32_t messageType, uint32_t messagePermissions, Session session, + bool sentBySessionInitiator) + : sender(sentBySessionInitiator ? session.initiator : session.peer), + recipient(sentBySessionInitiator ? session.peer : session.initiator), + sessionId(session.sessionId), + data(std::move(data)), + length(length), + messageType(messageType), + messagePermissions(messagePermissions) {} + Message(Message &&other) + : sender(other.sender), + recipient(other.recipient), + sessionId(other.sessionId), + data(std::move(other.data)), + length(other.length), + messageType(other.messageType), + messagePermissions(other.messagePermissions) {} + + Message(const Message &) = delete; + Message &operator=(const Message &) = delete; + + Message &operator=(Message &&other) { + sender = other.sender; + recipient = other.recipient; + sessionId = other.sessionId; + data = std::move(other.data); + length = other.length; + messageType = other.messageType; + messagePermissions = other.messagePermissions; + return *this; + } +}; + +//! Represents information about an endpoint +//! Service information is stored in ServiceManager +struct EndpointInfo { + static constexpr size_t kMaxNameLength = 50; + + EndpointInfo(EndpointId id, const char *name, uint32_t version, + EndpointType type, uint32_t requiredPermissions) + : id(id), + version(version), + type(type), + requiredPermissions(requiredPermissions) { + if (name != nullptr) { + std::strncpy(this->name, name, kMaxNameLength); + } else { + this->name[0] = '\0'; + } + this->name[kMaxNameLength] = '\0'; + } + + EndpointId id; + char name[kMaxNameLength + 1]; + uint32_t version; + EndpointType type; + uint32_t requiredPermissions; + + bool operator==(const EndpointInfo &other) const { + return id == other.id && version == other.version && type == other.type && + requiredPermissions == other.requiredPermissions && + std::strcmp(name, other.name) == 0; + } + + bool operator!=(const EndpointInfo &other) const { + return !(*this == other); + } +}; + +//! Represents information about a MessageHub +struct MessageHubInfo { + MessageHubId id; + const char *name; + + bool operator==(const MessageHubInfo &other) const { + return id == other.id && std::strcmp(name, other.name) == 0; + } + + bool operator!=(const MessageHubInfo &other) const { + return !(*this == other); + } +}; + +} // namespace chre::message + +#endif // CHRE_UTIL_SYSTEM_MESSAGE_COMMON_H_
diff --git a/util/include/chre/util/system/message_router.h b/util/include/chre/util/system/message_router.h new file mode 100644 index 0000000..089f149 --- /dev/null +++ b/util/include/chre/util/system/message_router.h
@@ -0,0 +1,298 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CHRE_UTIL_SYSTEM_MESSAGE_ROUTER_H_ +#define CHRE_UTIL_SYSTEM_MESSAGE_ROUTER_H_ + +#include <pw_allocator/unique_ptr.h> +#include <pw_containers/vector.h> +#include <pw_function/function.h> +#include <cstddef> +#include <cstdint> +#include <optional> + +#include "chre/platform/mutex.h" +#include "chre/util/singleton.h" +#include "chre/util/system/message_common.h" + +namespace chre::message { + +//! MessageRouter routes messages between endpoints connected to MessageHubs. It +//! provides an API for registering MessageHubs, opening and closing sessions, +//! and sending messages between endpoints. Each MessageHub is expected to +//! register a callback to handle messages sent to its endpoints and other +//! functions to provide information about the endpoints connected to it. +//! +//! MessageRouter is thread-safe. +//! +//! Usage: +//! 1. Create a MessageRouter instance. +//! 2. Register MessageHubs with the MessageRouter. Each MessageHub must have +//! a unique ID and a callback to handle messages sent to its endpoints. +//! 3. Open sessions from endpoints connected to MessageHubs to endpoints +//! connected to other MessageHubs. +//! 4. Send messages to endpoints using the MessageRouter API. +//! 5. Close sessions when they are no longer needed. +class MessageRouter { + public: + //! The callback used to register a MessageHub with the MessageRouter + class MessageHubCallback { + public: + virtual ~MessageHubCallback() = default; + + //! Message processing callback. If this function returns true, + //! the MessageHub received the message and will deliver it to the + //! receiving endpoint, or close the session if an error occurs. + //! @see sendMessage + //! @param session The session that the message was sent on (this reference + //! is only valid for the duration of the callback) + //! @param sentBySessionInitiator Whether the message was sent by the + //! initiator of the session + //! @return true if the message was accepted for processing + virtual bool onMessageReceived(pw::UniquePtr<std::byte[]> &&data, + size_t length, uint32_t messageType, + uint32_t messagePermissions, + const Session &session, + bool sentBySessionInitiator) = 0; + + //! Callback called when the session is closed + virtual void onSessionClosed(const Session &session) = 0; + + //! Callback called to iterate over all endpoints connected to the + //! MessageHub. Underlying endpoint storage must not change during this + //! callback. If function returns true, the MessageHub can stop iterating + //! over future endpoints. This function should not call any MessageRouter + //! or MessageHub functions. + virtual void forEachEndpoint( + const pw::Function<bool(const EndpointInfo &)> &function) = 0; + + //! @return The EndpointInfo for the given endpoint ID. This function should + //! not call any MessageRouter or MessageHub functions. + virtual std::optional<EndpointInfo> getEndpointInfo( + EndpointId endpointId) = 0; + }; + + //! The API returned when registering a MessageHub with the MessageRouter. + class MessageHub { + public: + //! Creates an empty MessageHub that is not usable, similar to a moved-from + //! MessageHub. Attempting to call any method on this object results in + //! undefined behavior. + MessageHub(); + + ~MessageHub() { + if (mRouter != nullptr) { + mRouter->unregisterMessageHub(mHubId); + } + } + // There can only be one live MessageHub instance for a given hub ID, so + // only move operations are supported. + MessageHub(const MessageHub &) = delete; + MessageHub &operator=(const MessageHub &) = delete; + MessageHub(MessageHub &&other); + MessageHub &operator=(MessageHub &&other); + + //! Opens a session from an endpoint connected to the current MessageHub + //! to the listed MessageHub ID and endpoint ID + //! @return The session ID or SESSION_ID_INVALID if the session could + //! not be opened + SessionId openSession(EndpointId fromEndpointId, + MessageHubId toMessageHubId, EndpointId toEndpointId); + + //! Closes the session with sessionId + //! @return true if the session was closed, false if the session was not + //! found + bool closeSession(SessionId sessionId); + + //! Returns a session if it exists + //! @return The session or std::nullopt if the session was not found + std::optional<Session> getSessionWithId(SessionId sessionId); + + //! Sends a message to the session specified by sessionId. + //! @see chreSendReliableMessageAsync. Sends the message in a reliable + //! manner if possible. If the message cannot be delivered, the session + //! is closed and subsequent calls to this function with the same sessionId + //! will return false. + //! @param data The data to send + //! @param length The length of the data to send + //! @param messageType The type of the message, a bit flagged value + //! @param messagePermissions The permissions of the message, a bit flagged + //! value + //! @param sessionId The session to send the message on + //! @return true if the message was sent, false if the message could not be + //! sent + bool sendMessage(pw::UniquePtr<std::byte[]> &&data, size_t length, + uint32_t messageType, uint32_t messagePermissions, + SessionId sessionId); + + //! @return The MessageHub ID of the currently connected MessageHub + MessageHubId getId(); + + private: + friend class MessageRouter; + + MessageHub(MessageRouter &router, MessageHubId id); + + //! The MessageRouter that this MessageHub is connected to + MessageRouter *mRouter; + + //! The id of this message hub + MessageHubId mHubId; + }; + + //! Represents a MessageHub and its connected endpoints + struct MessageHubRecord { + MessageHubInfo info; + MessageHubCallback *callback; + }; + + MessageRouter() = delete; + MessageRouter(pw::Vector<MessageHubRecord> &messageHubs, + pw::Vector<Session> &sessions) + : mMessageHubs(messageHubs), mSessions(sessions) {} + + //! Registers a MessageHub with the MessageRouter. + //! The provided name must be unique and not registered before and be a valid + //! C string. The data underlying name must outlive the MessageHub. The + //! callback must outlive the MessageHub. The ID must be unique and not + //! registered before. When the returned MessageHub is destroyed, it will + //! unregister itself from the MessageRouter. + //! @param name The name of the MessageHub + //! @param id The ID of the MessageHub + //! @param callback The callback to handle messages sent to the MessageHub + //! @return The MessageHub API or std::nullopt if the MessageHub could not be + //! registered + std::optional<MessageHub> registerMessageHub(const char *name, + MessageHubId id, + MessageHubCallback &callback); + + //! Executes the function for each endpoint connected to this MessageHub. + //! If function returns true, the iteration will stop. + //! @return true if the MessageHub is found, false otherwise + bool forEachEndpointOfHub( + MessageHubId messageHubId, + const pw::Function<bool(const EndpointInfo &)> &function); + + //! Executes the function for each endpoint connected to all Message Hubs. + //! The lock is held when calling the callback. + void forEachEndpoint( + const pw::Function<void(const MessageHubInfo &, const EndpointInfo &)> + &function); + + //! @return The EndpointInfo for the given hub and endpoint IDs + std::optional<EndpointInfo> getEndpointInfo(MessageHubId messageHubId, + EndpointId endpointId); + + //! Executes the function for each MessageHub connected to the MessageRouter. + //! If function returns true, the iteration will stop. + //! The lock is held when calling the callback. + void forEachMessageHub( + const pw::Function<bool(const MessageHubInfo &)> &function); + + private: + //! Unregisters a MessageHub from the MessageRouter. This function will + //! close all sessions that were initiated by or connected to the MessageHub + //! and destroy the MessageHubRecord. This function will call the callback + //! for each session that was closed only for the other message hub in the + //! session. + //! @return true if the MessageHub was unregistered, false if the MessageHub + //! was not found. + bool unregisterMessageHub(MessageHubId fromMessageHubId); + + //! Opens a session from an endpoint connected to the current MessageHub + //! to the listed MessageHub ID and endpoint ID + //! @return The session ID or SESSION_ID_INVALID if the session could not be + //! opened + SessionId openSession(MessageHubId fromMessageHubId, + EndpointId fromEndpointId, MessageHubId toMessageHubId, + EndpointId toEndpointId); + + //! Closes the session with sessionId + //! @return true if the session was closed, false if the session was not + //! found + bool closeSession(MessageHubId fromMessageHubId, SessionId sessionId); + + //! Returns a session if it exists + //! @return The session or std::nullopt if the session was not found + std::optional<Session> getSessionWithId(MessageHubId fromMessageHubId, + SessionId sessionId); + + //! Sends a message to the session specified by sessionId. + //! @see chreSendReliableMessageAsync. Sends the message in a reliable + //! manner if possible. If the message cannot be delivered, the session + //! is closed and subsequent calls to this function with the same sessionId + //! will return false. + //! @see MessageHub::sendMessage + //! @return true if the message was sent, false if the message could not be + //! sent + bool sendMessage(pw::UniquePtr<std::byte[]> &&data, size_t length, + uint32_t messageType, uint32_t messagePermissions, + SessionId sessionId, MessageHubId fromMessageHubId); + + //! @return The MessageHubRecord for the given MessageHub ID + const MessageHubRecord *getMessageHubRecordLocked(MessageHubId messageHubId); + + //! @return The index of the session if it exists + //! Requires the caller to hold the mutex + std::optional<size_t> findSessionIndexLocked(MessageHubId fromMessageHubId, + SessionId sessionId); + + //! @return The callback for the given MessageHub ID or nullptr if not found + //! Requires the caller to hold the mutex + MessageHubCallback *getCallbackFromMessageHubId(MessageHubId messageHubId); + + //! @return The callback for the given MessageHub ID or nullptr if not found + MessageHubCallback *getCallbackFromMessageHubIdLocked( + MessageHubId messageHubId); + + //! @return true if the endpoint exists in the MessageHub with the given + //! callback + bool checkIfEndpointExists(MessageHubCallback *callback, EndpointId endpointId); + + //! The mutex to protect MessageRouter state + Mutex mMutex; + + //! The next available Session ID + SessionId mNextSessionId = 0; + + //! The list of MessageHubs connected to the MessageRouter + pw::Vector<MessageHubRecord> &mMessageHubs; + + //! The list of sessions connected to the MessageRouter + pw::Vector<Session> &mSessions; +}; + +//! Define the singleton instance of the MessageRouter +typedef Singleton<MessageRouter> MessageRouterSingleton; + +//! Routes messages between MessageHubs +template <size_t kMaxMessageHubs, size_t kMaxSessions> +class MessageRouterWithStorage : public MessageRouter { + public: + MessageRouterWithStorage(): + MessageRouter(mMessageHubs, mSessions) {} + + private: + //! The list of MessageHubs connected to the MessageRouter + pw::Vector<MessageHubRecord, kMaxMessageHubs> mMessageHubs; + + //! The list of sessions connected to the MessageRouter + pw::Vector<Session, kMaxSessions> mSessions; +}; + +} // namespace chre::message + +#endif // CHRE_UTIL_SYSTEM_MESSAGE_ROUTER_H_
diff --git a/util/include/chre/util/system/message_router_callback_allocator.h b/util/include/chre/util/system/message_router_callback_allocator.h new file mode 100644 index 0000000..e3aabd8 --- /dev/null +++ b/util/include/chre/util/system/message_router_callback_allocator.h
@@ -0,0 +1,85 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CHRE_UTIL_SYSTEM_MESSAGE_ROUTER_CALLBACK_ALLOCATOR_H_ +#define CHRE_UTIL_SYSTEM_MESSAGE_ROUTER_CALLBACK_ALLOCATOR_H_ + +#include <pw_allocator/allocator.h> +#include <pw_allocator/capability.h> +#include <pw_allocator/unique_ptr.h> +#include <pw_containers/vector.h> +#include <pw_function/function.h> +#include <cstddef> +#include <optional> + +#include "chre/platform/mutex.h" + +namespace chre::message { + +//! An allocator for message free callbacks +//! This allocator is used to store message free callbacks in a vector +//! The allocator will call the free callback when the message is deallocated +//! This is used to create pw::UniquePtrs for messages that have a free +//! callback. +//! @param Metadata The metadata type for the callback function +template <typename Metadata> +class MessageRouterCallbackAllocator : public pw::Allocator { + public: + static constexpr Capabilities kCapabilities = 0; + + //! The callback used to free a message + using MessageFreeCallback = pw::Function<void( + std::byte *message, size_t length, const Metadata &metadata)>; + + //! A record of a message and its free callback + struct FreeCallbackRecord { + std::byte *message; + Metadata metadata; + size_t messageSize; + }; + + MessageRouterCallbackAllocator( + MessageFreeCallback &&callback, + pw::Vector<FreeCallbackRecord> &freeCallbackRecords); + + //! @see pw::Allocator::DoAllocate + virtual void *DoAllocate(Layout /* layout */) override; + + //! @see pw::Allocator::DoDeallocate + virtual void DoDeallocate(void *ptr) override; + + //! Creates a pw::UniquePtr for a message with a free callback. + //! The free callback will be called when the message is deallocated. + //! @return A pw::UniquePtr containing the message + [[nodiscard]] pw::UniquePtr<std::byte[]> MakeUniqueArrayWithCallback( + std::byte *ptr, size_t size, Metadata &&metadata); + + private: + //! The callback used to free a message + MessageFreeCallback mCallback; + + //! The mutex to protect mFreeCallbackRecords + Mutex mMutex; + + //! The map of message pointers to free callbacks + pw::Vector<FreeCallbackRecord> &mFreeCallbackRecords; +}; + +} // namespace chre::message + +#include "chre/util/system/message_router_callback_allocator_impl.h" + +#endif // CHRE_UTIL_SYSTEM_MESSAGE_ROUTER_CALLBACK_ALLOCATOR_H_
diff --git a/util/include/chre/util/system/message_router_callback_allocator_impl.h b/util/include/chre/util/system/message_router_callback_allocator_impl.h new file mode 100644 index 0000000..fc27e90 --- /dev/null +++ b/util/include/chre/util/system/message_router_callback_allocator_impl.h
@@ -0,0 +1,87 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CHRE_UTIL_SYSTEM_MESSAGE_ROUTER_CALLBACK_ALLOCATOR_IMPL_H_ +#define CHRE_UTIL_SYSTEM_MESSAGE_ROUTER_CALLBACK_ALLOCATOR_IMPL_H_ + +#include <pw_allocator/allocator.h> +#include <pw_allocator/capability.h> +#include <pw_allocator/unique_ptr.h> +#include <pw_containers/vector.h> +#include <pw_function/function.h> +#include <cstddef> +#include <optional> + +#include "chre/util/lock_guard.h" +#include "chre/util/system/message_common.h" +#include "chre/util/system/message_router_callback_allocator.h" + +namespace chre::message { + +template <typename Metadata> +MessageRouterCallbackAllocator<Metadata>::MessageRouterCallbackAllocator( + MessageFreeCallback &&callback, + pw::Vector<FreeCallbackRecord> &freeCallbackRecords) + : pw::Allocator(kCapabilities), + mCallback(std::move(callback)), + mFreeCallbackRecords(freeCallbackRecords) {} + +template <typename Metadata> +void *MessageRouterCallbackAllocator<Metadata>::DoAllocate( + Layout /* layout */) { + return nullptr; +} + +template <typename Metadata> +void MessageRouterCallbackAllocator<Metadata>::DoDeallocate(void *ptr) { + std::optional<FreeCallbackRecord> freeCallbackRecord; + { + LockGuard<Mutex> lock(mMutex); + for (FreeCallbackRecord &record : mFreeCallbackRecords) { + if (record.message == ptr) { + freeCallbackRecord = std::move(record); + mFreeCallbackRecords.erase(&record); + break; + } + } + } + + if (freeCallbackRecord.has_value()) { + mCallback(freeCallbackRecord->message, freeCallbackRecord->messageSize, + freeCallbackRecord->metadata); + } +} + +template <typename Metadata> +pw::UniquePtr<std::byte[]> +MessageRouterCallbackAllocator<Metadata>::MakeUniqueArrayWithCallback( + std::byte *ptr, size_t size, Metadata &&metadata) { + { + LockGuard<Mutex> lock(mMutex); + if (mFreeCallbackRecords.full()) { + return pw::UniquePtr<std::byte[]>(); + } + + mFreeCallbackRecords.push_back( + {.message = ptr, .metadata = std::move(metadata), .messageSize = size}); + } + + return WrapUniqueArray(ptr, size); +} + +} // namespace chre::message + +#endif // CHRE_UTIL_SYSTEM_MESSAGE_ROUTER_CALLBACK_ALLOCATOR_IMPL_H_
diff --git a/util/include/chre/util/synchronized_expandable_memory_pool.h b/util/include/chre/util/system/synchronized_expandable_memory_pool.h similarity index 93% rename from util/include/chre/util/synchronized_expandable_memory_pool.h rename to util/include/chre/util/system/synchronized_expandable_memory_pool.h index 72c8c62..3a5cd46 100644 --- a/util/include/chre/util/synchronized_expandable_memory_pool.h +++ b/util/include/chre/util/system/synchronized_expandable_memory_pool.h
@@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef CHRE_UTIL_SYNCHRONIZED_EXPANDABLE_MEMORY_POOL_H_ -#define CHRE_UTIL_SYNCHRONIZED_EXPANDABLE_MEMORY_POOL_H_ +#ifndef CHRE_UTIL_SYSTEM_SYNCHRONIZED_EXPANDABLE_MEMORY_POOL_H_ +#define CHRE_UTIL_SYSTEM_SYNCHRONIZED_EXPANDABLE_MEMORY_POOL_H_ #include "chre/platform/mutex.h" #include "chre/util/fixed_size_vector.h" @@ -124,6 +124,6 @@ } // namespace chre -#include "chre/util/synchronized_expandable_memory_pool_impl.h" // IWYU pragma: export +#include "chre/util/system/synchronized_expandable_memory_pool_impl.h" // IWYU pragma: export -#endif // CHRE_UTIL_SYNCHRONIZED_EXPANDABLE_MEMORY_POOL_H_ +#endif // CHRE_UTIL_SYSTEM_SYNCHRONIZED_EXPANDABLE_MEMORY_POOL_H_
diff --git a/util/include/chre/util/synchronized_expandable_memory_pool_impl.h b/util/include/chre/util/system/synchronized_expandable_memory_pool_impl.h similarity index 94% rename from util/include/chre/util/synchronized_expandable_memory_pool_impl.h rename to util/include/chre/util/system/synchronized_expandable_memory_pool_impl.h index 31b9007..f5698b4 100644 --- a/util/include/chre/util/synchronized_expandable_memory_pool_impl.h +++ b/util/include/chre/util/system/synchronized_expandable_memory_pool_impl.h
@@ -14,15 +14,15 @@ * limitations under the License. */ -#ifndef CHRE_UTIL_SYNCHRONIZED_EXPANDABLE_MEMORY_POOL_IMPL_H_ -#define CHRE_UTIL_SYNCHRONIZED_EXPANDABLE_MEMORY_POOL_IMPL_H_ +#ifndef CHRE_UTIL_SYSTEM_SYNCHRONIZED_EXPANDABLE_MEMORY_POOL_IMPL_H_ +#define CHRE_UTIL_SYSTEM_SYNCHRONIZED_EXPANDABLE_MEMORY_POOL_IMPL_H_ // IWYU pragma: private #include <algorithm> #include "chre/util/lock_guard.h" #include "chre/util/memory_pool.h" -#include "chre/util/synchronized_expandable_memory_pool.h" +#include "chre/util/system/synchronized_expandable_memory_pool.h" namespace chre { @@ -147,4 +147,4 @@ } } // namespace chre -#endif // CHRE_UTIL_SYNCHRONIZED_EXPANDABLE_MEMORY_POOL_IMPL_H_ +#endif // CHRE_UTIL_SYSTEM_SYNCHRONIZED_EXPANDABLE_MEMORY_POOL_IMPL_H_
diff --git a/util/include/chre/util/synchronized_memory_pool.h b/util/include/chre/util/system/synchronized_memory_pool.h similarity index 92% rename from util/include/chre/util/synchronized_memory_pool.h rename to util/include/chre/util/system/synchronized_memory_pool.h index 7e5294d..85cdaf6 100644 --- a/util/include/chre/util/synchronized_memory_pool.h +++ b/util/include/chre/util/system/synchronized_memory_pool.h
@@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef CHRE_UTIL_SYNCHRONIZED_MEMORY_POOL_H_ -#define CHRE_UTIL_SYNCHRONIZED_MEMORY_POOL_H_ +#ifndef CHRE_UTIL_SYSTEM_SYNCHRONIZED_MEMORY_POOL_H_ +#define CHRE_UTIL_SYSTEM_SYNCHRONIZED_MEMORY_POOL_H_ #include "chre/platform/mutex.h" #include "chre/util/memory_pool.h" @@ -94,6 +94,6 @@ } // namespace chre -#include "chre/util/synchronized_memory_pool_impl.h" // IWYU pragma: export +#include "chre/util/system/synchronized_memory_pool_impl.h" // IWYU pragma: export -#endif // CHRE_UTIL_SYNCHRONIZED_MEMORY_POOL_H_ +#endif // CHRE_UTIL_SYSTEM_SYNCHRONIZED_MEMORY_POOL_H_
diff --git a/util/include/chre/util/synchronized_memory_pool_impl.h b/util/include/chre/util/system/synchronized_memory_pool_impl.h similarity index 87% rename from util/include/chre/util/synchronized_memory_pool_impl.h rename to util/include/chre/util/system/synchronized_memory_pool_impl.h index 6856500..6d78686 100644 --- a/util/include/chre/util/synchronized_memory_pool_impl.h +++ b/util/include/chre/util/system/synchronized_memory_pool_impl.h
@@ -14,12 +14,12 @@ * limitations under the License. */ -#ifndef CHRE_UTIL_SYNCHRONIZED_MEMORY_POOL_IMPL_H_ -#define CHRE_UTIL_SYNCHRONIZED_MEMORY_POOL_IMPL_H_ +#ifndef CHRE_UTIL_SYSTEM_SYNCHRONIZED_MEMORY_POOL_IMPL_H_ +#define CHRE_UTIL_SYSTEM_SYNCHRONIZED_MEMORY_POOL_IMPL_H_ // IWYU pragma: private #include "chre/util/lock_guard.h" -#include "chre/util/synchronized_memory_pool.h" +#include "chre/util/system/synchronized_memory_pool.h" namespace chre { @@ -53,4 +53,4 @@ } // namespace chre -#endif // CHRE_UTIL_SYNCHRONIZED_MEMORY_POOL_IMPL_H_ +#endif // CHRE_UTIL_SYSTEM_SYNCHRONIZED_MEMORY_POOL_IMPL_H_
diff --git a/util/include/chre/util/transaction_manager.h b/util/include/chre/util/system/transaction_manager.h similarity index 97% rename from util/include/chre/util/transaction_manager.h rename to util/include/chre/util/system/transaction_manager.h index 7fd4b0e..28656b2 100644 --- a/util/include/chre/util/transaction_manager.h +++ b/util/include/chre/util/system/transaction_manager.h
@@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef CHRE_UTIL_TRANSACTION_MANAGER_H_ -#define CHRE_UTIL_TRANSACTION_MANAGER_H_ +#ifndef CHRE_UTIL_SYSTEM_TRANSACTION_MANAGER_H_ +#define CHRE_UTIL_SYSTEM_TRANSACTION_MANAGER_H_ #include <cstdint> @@ -226,6 +226,6 @@ } // namespace chre -#include "chre/util/transaction_manager_impl.h" // IWYU pragma: export +#include "chre/util/system/transaction_manager_impl.h" // IWYU pragma: export -#endif // CHRE_UTIL_TRANSACTION_MANAGER_H_ +#endif // CHRE_UTIL_SYSTEM_TRANSACTION_MANAGER_H_
diff --git a/util/include/chre/util/transaction_manager_impl.h b/util/include/chre/util/system/transaction_manager_impl.h similarity index 97% rename from util/include/chre/util/transaction_manager_impl.h rename to util/include/chre/util/system/transaction_manager_impl.h index 3aa5108..4d689b3 100644 --- a/util/include/chre/util/transaction_manager_impl.h +++ b/util/include/chre/util/system/transaction_manager_impl.h
@@ -14,11 +14,11 @@ * limitations under the License. */ -#ifndef CHRE_UTIL_TRANSACTION_MANAGER_IMPL_H_ -#define CHRE_UTIL_TRANSACTION_MANAGER_IMPL_H_ +#ifndef CHRE_UTIL_SYSTEM_TRANSACTION_MANAGER_IMPL_H_ +#define CHRE_UTIL_SYSTEM_TRANSACTION_MANAGER_IMPL_H_ // IWYU pragma: private -#include "chre/util/transaction_manager.h" +#include "chre/util/system/transaction_manager.h" #include "chre/core/event_loop_common.h" #include "chre/platform/system_time.h" @@ -230,4 +230,4 @@ } // namespace chre -#endif // CHRE_UTIL_TRANSACTION_MANAGER_IMPL_H_ +#endif // CHRE_UTIL_SYSTEM_TRANSACTION_MANAGER_IMPL_H_
diff --git a/util/include/chre/util/throttle.h b/util/include/chre/util/throttle.h index 5026afb..f6c54fd 100644 --- a/util/include/chre/util/throttle.h +++ b/util/include/chre/util/throttle.h
@@ -17,10 +17,6 @@ #ifndef CHRE_UTIL_THROTTLE_H_ #define CHRE_UTIL_THROTTLE_H_ -#include "chre/util/optional.h" - -using ::chre::Optional; - /** * Throttles an action to a given interval and maximum number of times. * The action will be called at most maxCount in every interval. @@ -30,20 +26,21 @@ * @param maxCount The maximum number of times to call the action * @param getTime A function to get the current time */ -#define CHRE_THROTTLE(action, interval, maxCount, getTime) \ - do { \ - static uint32_t _count = 0; \ - static Optional<Nanoseconds> _lastCallTime; \ - Nanoseconds _now = getTime; \ - if (!_lastCallTime.has_value() || \ - _now - _lastCallTime.value() >= interval) { \ - _count = 0; \ - _lastCallTime = _now; \ - } \ - if (++_count > maxCount) { \ - break; \ - } \ - action; \ +#define CHRE_THROTTLE(action, interval, maxCount, getTime) \ + do { \ + static uint32_t _count = 0; \ + static bool _hasLastCallTime = false; \ + static Nanoseconds _lastCallTime; \ + Nanoseconds _now = getTime; \ + if (!_hasLastCallTime || _now - _lastCallTime >= interval) { \ + _hasLastCallTime = true; \ + _count = 0; \ + _lastCallTime = _now; \ + } \ + if (++_count > maxCount) { \ + break; \ + } \ + action; \ } while (0) #endif // CHRE_UTIL_THROTTLE_H_
diff --git a/util/nanoapp/ble.cc b/util/nanoapp/ble.cc index 8283ab6..7a6c0fc 100644 --- a/util/nanoapp/ble.cc +++ b/util/nanoapp/ble.cc
@@ -19,6 +19,7 @@ namespace chre { +using ble_constants::kBroadcasterAddress; using ble_constants::kGoogleEddystoneUuid; using ble_constants::kGoogleManufactureData; using ble_constants::kGoogleManufactureDataLength; @@ -26,6 +27,7 @@ using ble_constants::kGoogleNearbyFastpairUuid; using ble_constants::kGoogleUuidDataLength; using ble_constants::kGoogleUuidMask; +using ble_constants::kNumBroadcasterFilters; using ble_constants::kNumManufacturerDataFilters; using ble_constants::kNumScanFilters; using ble_constants::kRssiThreshold; @@ -108,4 +110,25 @@ return true; } +bool createBleScanFilterForAdvertiser( + struct chreBleScanFilterV1_9 &filter, + chreBleBroadcasterAddressFilter *broadcasterFilters, + uint8_t numBroadcasterFilters) { + if (numBroadcasterFilters < kNumBroadcasterFilters) { + return false; + } + + memcpy(&broadcasterFilters[0], kBroadcasterAddress, + sizeof(broadcasterFilters[0])); + + memset(&filter, 0, sizeof(filter)); + filter.rssiThreshold = kRssiThreshold; + filter.genericFilterCount = 0; + filter.genericFilters = nullptr; + + filter.broadcasterAddressFilterCount = kNumBroadcasterFilters; + filter.broadcasterAddressFilters = broadcasterFilters; + return true; +} + } // namespace chre
diff --git a/util/pigweed/rpc_server.cc b/util/pigweed/rpc_server.cc index 42be93b..3fd6424 100644 --- a/util/pigweed/rpc_server.cc +++ b/util/pigweed/rpc_server.cc
@@ -102,8 +102,9 @@ hostMessage->messageSize); pw::Result<uint32_t> result = pw::rpc::ExtractChannelId(packet); - if (result.status() != PW_STATUS_OK) { - LOGE("Unable to extract channel ID from packet"); + if (!result.status().ok()) { + LOGE("Unable to extract channel ID from packet: %" PRIu8, + static_cast<uint8_t>(result.status().code())); return false; } @@ -124,13 +125,13 @@ mHostOutput.setHostEndpoint(hostMessage->hostEndpoint); pw::Status status = mServer.OpenChannel(result.value(), mHostOutput); if (status != pw::OkStatus() && status != pw::Status::AlreadyExists()) { - LOGE("Failed to open channel"); + LOGE("Failed to open channel: %" PRIu8, static_cast<uint8_t>(status.code())); return false; } status = mServer.ProcessPacket(packet); - if (status != pw::OkStatus()) { - LOGE("Failed to process the packet"); + if (!status.ok()) { + LOGE("Failed to process the packet: %" PRIu8, static_cast<uint8_t>(status.code())); return false; } @@ -145,8 +146,9 @@ data->msgSize); pw::Result<uint32_t> result = pw::rpc::ExtractChannelId(packet); - if (result.status() != PW_STATUS_OK) { - LOGE("Unable to extract channel ID from packet"); + if (!result.status().ok()) { + LOGE("Unable to extract channel ID from packet: %" PRIu8, + static_cast<uint8_t>(result.status().code())); return false; } @@ -159,13 +161,13 @@ mNanoappOutput.setClient(senderInstanceId); pw::Status status = mServer.OpenChannel(result.value(), mNanoappOutput); if (status != pw::OkStatus() && status != pw::Status::AlreadyExists()) { - LOGE("Failed to open channel"); + LOGE("Failed to open channel: %" PRIu8, static_cast<uint8_t>(status.code())); return false; } status = mServer.ProcessPacket(packet); - if (status != pw::OkStatus()) { - LOGE("Failed to process the packet"); + if (!status.ok()) { + LOGE("Failed to process the packet: %" PRIu8, static_cast<uint8_t>(status.code())); return false; } @@ -196,9 +198,12 @@ auto info = static_cast<const struct chreNanoappInfo *>(eventData); if (info->instanceId > kRpcNanoappMaxId) { - LOGE("Invalid nanoapp Id 0x%08" PRIx32, info->instanceId); - } else if (!mServer.CloseChannel(info->instanceId).ok()) { - LOGE("Failed to close channel for nanoapp 0x%08" PRIx32, info->instanceId); + LOGE("Invalid nanoapp instance ID %" PRIu32, info->instanceId); + } else if (pw::Status status = mServer.CloseChannel(info->instanceId); + !status.ok()) { + LOGE("Failed to close channel for nanoapp with instance ID %" + PRIu32 ": %" PRIu8, info->instanceId, + static_cast<uint8_t>(status.code())); } }
diff --git a/util/system/message_router.cc b/util/system/message_router.cc new file mode 100644 index 0000000..3582889 --- /dev/null +++ b/util/system/message_router.cc
@@ -0,0 +1,422 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <inttypes.h> +#include <cstring> +#include <optional> +#include <utility> + +#include "chre/platform/log.h" +#include "chre/util/dynamic_vector.h" +#include "chre/util/lock_guard.h" +#include "chre/util/system/message_common.h" +#include "chre/util/system/message_router.h" + +namespace chre::message { + +MessageRouter::MessageHub::MessageHub() + : mRouter(nullptr), mHubId(MESSAGE_HUB_ID_INVALID) {} + +MessageRouter::MessageHub::MessageHub(MessageRouter &router, MessageHubId id) + : mRouter(&router), mHubId(id) {} + +MessageRouter::MessageHub::MessageHub(MessageHub &&other) + : mRouter(other.mRouter), mHubId(other.mHubId) { + other.mRouter = nullptr; + other.mHubId = MESSAGE_HUB_ID_INVALID; +} + +MessageRouter::MessageHub &MessageRouter::MessageHub::operator=( + MessageHub &&other) { + mRouter = other.mRouter; + mHubId = other.mHubId; + other.mRouter = nullptr; + other.mHubId = MESSAGE_HUB_ID_INVALID; + return *this; +} + +SessionId MessageRouter::MessageHub::openSession(EndpointId fromEndpointId, + MessageHubId toMessageHubId, + EndpointId toEndpointId) { + return mRouter == nullptr + ? SESSION_ID_INVALID + : mRouter->openSession(mHubId, fromEndpointId, toMessageHubId, + toEndpointId); +} + +bool MessageRouter::MessageHub::closeSession(SessionId sessionId) { + return mRouter == nullptr ? false : mRouter->closeSession(mHubId, sessionId); +} + +std::optional<Session> MessageRouter::MessageHub::getSessionWithId( + SessionId sessionId) { + return mRouter == nullptr ? std::nullopt + : mRouter->getSessionWithId(mHubId, sessionId); +} + +bool MessageRouter::MessageHub::sendMessage(pw::UniquePtr<std::byte[]> &&data, + size_t length, uint32_t messageType, + uint32_t messagePermissions, + SessionId sessionId) { + return mRouter == nullptr + ? false + : mRouter->sendMessage(std::move(data), length, messageType, + messagePermissions, sessionId, mHubId); +} + +MessageHubId MessageRouter::MessageHub::getId() { + return mHubId; +} + +std::optional<typename MessageRouter::MessageHub> +MessageRouter::registerMessageHub( + const char *name, MessageHubId id, + MessageRouter::MessageRouter::MessageHubCallback &callback) { + LockGuard<Mutex> lock(mMutex); + if (mMessageHubs.full()) { + LOGE( + "Message hub '%s' not registered: maximum number of message hubs " + "reached", + name); + return std::nullopt; + } + + for (MessageHubRecord &messageHub : mMessageHubs) { + if (std::strcmp(messageHub.info.name, name) == 0 || + messageHub.info.id == id) { + LOGE( + "Message hub '%s' not registered: hub with same name or ID already " + "exists", + name); + return std::nullopt; + } + } + + MessageHubRecord messageHubRecord = { + .info = {.id = id, .name = name}, + .callback = &callback, + }; + mMessageHubs.push_back(std::move(messageHubRecord)); + return MessageHub(*this, id); +} + +bool MessageRouter::forEachEndpointOfHub( + MessageHubId messageHubId, + const pw::Function<bool(const EndpointInfo &)> &function) { + MessageRouter::MessageHubCallback *callback = + getCallbackFromMessageHubId(messageHubId); + if (callback == nullptr) { + LOGE("Failed to find message hub with ID %" PRIu64, messageHubId); + return false; + } + + callback->forEachEndpoint(function); + return true; +} + +void MessageRouter::forEachEndpoint( + const pw::Function<void(const MessageHubInfo &, const EndpointInfo &)> + &function) { + LockGuard<Mutex> lock(mMutex); + + struct Context { + decltype(function) function; + MessageHubInfo &messageHubInfo; + }; + for (MessageHubRecord &messageHubRecord : mMessageHubs) { + Context context = { + .function = function, + .messageHubInfo = messageHubRecord.info, + }; + + messageHubRecord.callback->forEachEndpoint( + [&context](const EndpointInfo &endpointInfo) { + context.function(context.messageHubInfo, endpointInfo); + return false; + }); + } +} + +std::optional<EndpointInfo> MessageRouter::getEndpointInfo( + MessageHubId messageHubId, EndpointId endpointId) { + MessageRouter::MessageHubCallback *callback = + getCallbackFromMessageHubId(messageHubId); + if (callback == nullptr) { + LOGE("Failed to get endpoint info for message hub with ID %" PRIu64 + " and endpoint ID %" PRIu64 ": hub not found", + messageHubId, endpointId); + return std::nullopt; + } + + return callback->getEndpointInfo(endpointId); +} + +void MessageRouter::forEachMessageHub( + const pw::Function<bool(const MessageHubInfo &)> &function) { + LockGuard<Mutex> lock(mMutex); + for (MessageHubRecord &messageHubRecord : mMessageHubs) { + function(messageHubRecord.info); + } +} + +bool MessageRouter::unregisterMessageHub(MessageHubId fromMessageHubId) { + DynamicVector<std::pair<MessageHubCallback *, Session>> sessionsToDestroy; + + { + LockGuard<Mutex> lock(mMutex); + + bool success = false; + for (MessageHubRecord &messageHubRecord : mMessageHubs) { + if (messageHubRecord.info.id == fromMessageHubId) { + mMessageHubs.erase(&messageHubRecord); + success = true; + break; + } + } + if (!success) { + return false; + } + + for (size_t i = 0; i < mSessions.size();) { + Session &session = mSessions[i]; + bool initiatorIsFromHub = + session.initiator.messageHubId == fromMessageHubId; + bool peerIsFromHub = session.peer.messageHubId == fromMessageHubId; + + if (initiatorIsFromHub || peerIsFromHub) { + MessageHubCallback *callback = getCallbackFromMessageHubIdLocked( + initiatorIsFromHub ? session.peer.messageHubId + : session.initiator.messageHubId); + sessionsToDestroy.push_back(std::make_pair(callback, session)); + mSessions.erase(&mSessions[i]); + } else { + ++i; + } + } + } + + for (auto [callback, session] : sessionsToDestroy) { + if (callback != nullptr) { + callback->onSessionClosed(session); + } + } + return true; +} + +SessionId MessageRouter::openSession(MessageHubId fromMessageHubId, + EndpointId fromEndpointId, + MessageHubId toMessageHubId, + EndpointId toEndpointId) { + if (fromMessageHubId == toMessageHubId) { + LOGE( + "Failed to open session: initiator and peer message hubs are the " + "same"); + return SESSION_ID_INVALID; + } + + MessageRouter::MessageHubCallback *initiatorCallback = + getCallbackFromMessageHubId(fromMessageHubId); + MessageRouter::MessageHubCallback *peerCallback = + getCallbackFromMessageHubId(toMessageHubId); + if (initiatorCallback == nullptr || peerCallback == nullptr) { + LOGE("Failed to open session: initiator or peer message hub not found"); + return SESSION_ID_INVALID; + } + + if (!checkIfEndpointExists(initiatorCallback, fromEndpointId)) { + LOGE("Failed to open session: endpoint with ID %" PRIu64 + " not found in message hub with ID %" PRIu64, + fromEndpointId, fromMessageHubId); + return SESSION_ID_INVALID; + } + + if (!checkIfEndpointExists(peerCallback, toEndpointId)) { + LOGE("Failed to open session: endpoint with ID %" PRIu64 + " not found in message hub with ID %" PRIu64, + toEndpointId, toMessageHubId); + return SESSION_ID_INVALID; + } + + { + LockGuard<Mutex> lock(mMutex); + if (mSessions.full()) { + LOGE("Failed to open session: maximum number of sessions reached"); + return SESSION_ID_INVALID; + } + + Session insertSession = { + .sessionId = mNextSessionId, + .initiator = {.messageHubId = fromMessageHubId, + .endpointId = fromEndpointId}, + .peer = {.messageHubId = toMessageHubId, .endpointId = toEndpointId}, + }; + + for (Session &session : mSessions) { + if (session.isEquivalent(insertSession)) { + LOGD("Session with ID %" PRIu16 " already exists", session.sessionId); + return session.sessionId; + } + } + + mSessions.push_back(std::move(insertSession)); + return mNextSessionId++; + } +} + +bool MessageRouter::closeSession(MessageHubId fromMessageHubId, + SessionId sessionId) { + Session session; + MessageRouter::MessageHubCallback *initiatorCallback = nullptr; + MessageRouter::MessageHubCallback *peerCallback = nullptr; + { + LockGuard<Mutex> lock(mMutex); + + std::optional<size_t> index = + findSessionIndexLocked(fromMessageHubId, sessionId); + if (!index.has_value()) { + LOGE("Failed to close session with ID %" PRIu16 ": session not found", + sessionId); + return false; + } + + session = mSessions[*index]; + initiatorCallback = + getCallbackFromMessageHubIdLocked(session.initiator.messageHubId); + peerCallback = getCallbackFromMessageHubIdLocked(session.peer.messageHubId); + mSessions.erase(&mSessions[*index]); + } + + if (initiatorCallback != nullptr) { + initiatorCallback->onSessionClosed(session); + } + if (peerCallback != nullptr) { + peerCallback->onSessionClosed(session); + } + return true; +} + +std::optional<Session> MessageRouter::getSessionWithId( + MessageHubId fromMessageHubId, SessionId sessionId) { + LockGuard<Mutex> lock(mMutex); + + std::optional<size_t> index = + findSessionIndexLocked(fromMessageHubId, sessionId); + return index.has_value() ? std::optional<Session>(mSessions[*index]) + : std::nullopt; +} + +bool MessageRouter::sendMessage(pw::UniquePtr<std::byte[]> &&data, + size_t length, uint32_t messageType, + uint32_t messagePermissions, + SessionId sessionId, + MessageHubId fromMessageHubId) { + MessageRouter::MessageHubCallback *receiverCallback = nullptr; + Session session; + { + LockGuard<Mutex> lock(mMutex); + + std::optional<size_t> index = + findSessionIndexLocked(fromMessageHubId, sessionId); + if (!index.has_value()) { + LOGE("Failed to send message: session with ID %" PRIu16 " not found", + sessionId); + return false; + } + + session = mSessions[*index]; + receiverCallback = getCallbackFromMessageHubIdLocked( + session.initiator.messageHubId == fromMessageHubId + ? session.peer.messageHubId + : session.initiator.messageHubId); + } + + bool success = false; + if (receiverCallback != nullptr) { + success = receiverCallback->onMessageReceived( + std::move(data), length, messageType, messagePermissions, session, + session.initiator.messageHubId == fromMessageHubId); + } + + if (!success) { + closeSession(fromMessageHubId, sessionId); + } + return success; +} + +const MessageRouter::MessageHubRecord *MessageRouter::getMessageHubRecordLocked( + MessageHubId messageHubId) { + for (MessageHubRecord &messageHubRecord : mMessageHubs) { + if (messageHubRecord.info.id == messageHubId) { + return &messageHubRecord; + } + } + return nullptr; +} + +std::optional<size_t> MessageRouter::findSessionIndexLocked( + MessageHubId fromMessageHubId, SessionId sessionId) { + for (size_t i = 0; i < mSessions.size(); ++i) { + if (mSessions[i].sessionId == sessionId) { + if (mSessions[i].initiator.messageHubId == fromMessageHubId || + mSessions[i].peer.messageHubId == fromMessageHubId) { + return i; + } + + LOGE("Hub mismatch for session with ID %" PRIu16 + ": requesting hub ID %" PRIu64 + " but session is between hubs %" PRIu64 " and %" PRIu64, + sessionId, fromMessageHubId, mSessions[i].initiator.messageHubId, + mSessions[i].peer.messageHubId); + break; + } + } + return std::nullopt; +} + +MessageRouter::MessageHubCallback *MessageRouter::getCallbackFromMessageHubId( + MessageHubId messageHubId) { + LockGuard<Mutex> lock(mMutex); + return getCallbackFromMessageHubIdLocked(messageHubId); +} + +MessageRouter::MessageHubCallback * +MessageRouter::getCallbackFromMessageHubIdLocked(MessageHubId messageHubId) { + const MessageHubRecord *messageHubRecord = + getMessageHubRecordLocked(messageHubId); + return messageHubRecord == nullptr ? nullptr : messageHubRecord->callback; +} + +bool MessageRouter::checkIfEndpointExists( + MessageRouter::MessageHubCallback *callback, EndpointId endpointId) { + struct EndpointContext { + EndpointId endpointId; + bool foundEndpoint = false; + }; + EndpointContext context = { + .endpointId = endpointId, + }; + + callback->forEachEndpoint([&context](const EndpointInfo &endpointInfo) { + if (context.endpointId == endpointInfo.id) { + context.foundEndpoint = true; + return true; + } + return false; + }); + return context.foundEndpoint; +} + +} // namespace chre::message
diff --git a/util/tests/array_queue_test.cc b/util/tests/array_queue_test.cc index bc55d19..ed8e2c6 100644 --- a/util/tests/array_queue_test.cc +++ b/util/tests/array_queue_test.cc
@@ -36,17 +36,20 @@ public: FakeElement() { constructor_count++; - }; + } + FakeElement(int i) { val_ = i; constructor_count++; - }; + } + ~FakeElement() { total_destructor_count++; if (val_ >= 0 && val_ < kMaxTestCapacity) { destructor_count[val_]++; } - }; + } + void setValue(int i) { val_ = i; }
diff --git a/util/tests/atomic_spsc_queue_test.cc b/util/tests/atomic_spsc_queue_test.cc index 2915af2..8ebb27a 100644 --- a/util/tests/atomic_spsc_queue_test.cc +++ b/util/tests/atomic_spsc_queue_test.cc
@@ -37,17 +37,20 @@ public: FakeElement() { constructor_count++; - }; + } + FakeElement(int i) { val_ = i; constructor_count++; - }; + } + ~FakeElement() { total_destructor_count++; if (val_ >= 0 && val_ < kMaxTestCapacity) { destructor_count[val_]++; } - }; + } + void setValue(int i) { val_ = i; }
diff --git a/util/tests/blocking_queue_test.cc b/util/tests/blocking_queue_test.cc index a05f657..461a7bc 100644 --- a/util/tests/blocking_queue_test.cc +++ b/util/tests/blocking_queue_test.cc
@@ -17,7 +17,7 @@ #include "gtest/gtest.h" #include "chre/util/blocking_segmented_queue.h" -#include "chre/util/fixed_size_blocking_queue.h" +#include "chre/util/system/fixed_size_blocking_queue.h" #include "chre/util/unique_ptr.h" using chre::BlockingSegmentedQueue;
diff --git a/util/tests/dynamic_vector_test.cc b/util/tests/dynamic_vector_test.cc index e69bd4c..80befe1 100644 --- a/util/tests/dynamic_vector_test.cc +++ b/util/tests/dynamic_vector_test.cc
@@ -38,7 +38,8 @@ if (mValue >= 0) { gDestructorCount[mValue]++; } - }; + } + void setValue(int value) { mValue = value; }
diff --git a/util/tests/fixed_size_vector_test.cc b/util/tests/fixed_size_vector_test.cc index 6bdffc2..4145658 100644 --- a/util/tests/fixed_size_vector_test.cc +++ b/util/tests/fixed_size_vector_test.cc
@@ -30,7 +30,8 @@ if (mValue >= 0) { destructor_count[mValue]++; } - }; + } + void setValue(int value) { mValue = value; }
diff --git a/util/tests/message_router_test.cc b/util/tests/message_router_test.cc new file mode 100644 index 0000000..8c6f875 --- /dev/null +++ b/util/tests/message_router_test.cc
@@ -0,0 +1,1175 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <pw_allocator/allocator.h> +#include <pw_allocator/capability.h> +#include <pw_allocator/unique_ptr.h> +#include <cstddef> +#include <cstdint> +#include <optional> +#include <utility> + +#include "chre/util/dynamic_vector.h" +#include "chre/util/system/message_common.h" +#include "chre/util/system/message_router.h" +#include "chre/util/system/message_router_callback_allocator.h" +#include "chre_api/chre.h" +#include "gtest/gtest.h" + +namespace chre::message { +namespace { + +constexpr size_t kMaxMessageHubs = 3; +constexpr size_t kMaxSessions = 10; +constexpr size_t kMaxFreeCallbackRecords = kMaxSessions * 2; +constexpr size_t kNumEndpoints = 3; + +const EndpointInfo kEndpointInfos[kNumEndpoints] = { + EndpointInfo(/* id= */ 1, /* name= */ "endpoint1", /* version= */ 1, + EndpointType::NANOAPP, CHRE_MESSAGE_PERMISSION_NONE), + EndpointInfo(/* id= */ 2, /* name= */ "endpoint2", /* version= */ 10, + EndpointType::HOST_NATIVE, CHRE_MESSAGE_PERMISSION_BLE), + EndpointInfo(/* id= */ 3, /* name= */ "endpoint3", /* version= */ 100, + EndpointType::GENERIC, CHRE_MESSAGE_PERMISSION_AUDIO)}; + +class TestAllocator : public pw::Allocator { + public: + static constexpr Capabilities kCapabilities = 0; + + TestAllocator() : pw::Allocator(kCapabilities) {} + + virtual void *DoAllocate(Layout layout) override { + if (layout.alignment() > alignof(std::max_align_t)) { + void *ptr; + return posix_memalign(&ptr, layout.alignment(), layout.size()) == 0 + ? ptr + : nullptr; + } else { + return malloc(layout.size()); + } + } + + virtual void DoDeallocate(void *ptr) override { + free(ptr); + } +}; + +class MessageRouterTest : public ::testing::Test { + protected: + void SetUp() override {} + + TestAllocator mAllocator; +}; + +//! Base class for MessageHubCallbacks used in tests +class MessageHubCallbackBase : public MessageRouter::MessageHubCallback { + public: + void forEachEndpoint( + const pw::Function<bool(const EndpointInfo &)> &function) override { + for (const EndpointInfo &endpointInfo : kEndpointInfos) { + if (function(endpointInfo)) { + return; + } + } + } + + std::optional<EndpointInfo> getEndpointInfo(EndpointId endpointId) override { + for (const EndpointInfo &endpointInfo : kEndpointInfos) { + if (endpointInfo.id == endpointId) { + return endpointInfo; + } + } + return std::nullopt; + } +}; + +//! MessageHubCallback that stores the data passed to onMessageReceived and +//! onSessionClosed +class MessageHubCallbackStoreData : public MessageHubCallbackBase { + public: + MessageHubCallbackStoreData(Message *message, Session *session) + : mMessage(message), mSession(session) {} + + bool onMessageReceived(pw::UniquePtr<std::byte[]> &&data, size_t length, + uint32_t messageType, uint32_t messagePermissions, + const Session &session, + bool sentBySessionInitiator) override { + if (mMessage != nullptr) { + mMessage->sender = sentBySessionInitiator ? session.initiator + : session.peer; + mMessage->recipient = + sentBySessionInitiator ? session.peer : session.initiator; + mMessage->sessionId = session.sessionId; + mMessage->data = std::move(data); + mMessage->length = length; + mMessage->messageType = messageType; + mMessage->messagePermissions = messagePermissions; + } + return true; + } + + void onSessionClosed(const Session &session) override { + if (mSession != nullptr) { + *mSession = session; + } + } + + private: + Message *mMessage; + Session *mSession; +}; + +//! MessageHubCallback that always fails to process messages +class MessageHubCallbackAlwaysFails : public MessageHubCallbackBase { + public: + MessageHubCallbackAlwaysFails(bool *wasMessageReceivedCalled, + bool *wasSessionClosedCalled) + : mWasMessageReceivedCalled(wasMessageReceivedCalled), + mWasSessionClosedCalled(wasSessionClosedCalled) {} + + bool onMessageReceived(pw::UniquePtr<std::byte[]> && /* data */, + size_t /* length */, uint32_t /* messageType */, + uint32_t /* messagePermissions */, + const Session & /* session */, + bool /* sentBySessionInitiator */) override { + if (mWasMessageReceivedCalled != nullptr) { + *mWasMessageReceivedCalled = true; + } + return false; + } + + void onSessionClosed(const Session & /* session */) override { + if (mWasSessionClosedCalled != nullptr) { + *mWasSessionClosedCalled = true; + } + } + + private: + bool *mWasMessageReceivedCalled; + bool *mWasSessionClosedCalled; +}; + +//! MessageHubCallback that calls MessageHub APIs during callbacks +class MessageHubCallbackCallsMessageHubApisDuringCallback + : public MessageHubCallbackBase { + public: + bool onMessageReceived(pw::UniquePtr<std::byte[]> && /* data */, + size_t /* length */, uint32_t /* messageType */, + uint32_t /* messagePermissions */, + const Session & /* session */, + bool /* sentBySessionInitiator */) override { + if (mMessageHub != nullptr) { + // Call a function that locks the MessageRouter mutex + mMessageHub->openSession(kEndpointInfos[0].id, mMessageHub->getId(), + kEndpointInfos[1].id); + } + return true; + } + + void onSessionClosed(const Session & /* session */) override { + if (mMessageHub != nullptr) { + // Call a function that locks the MessageRouter mutex + mMessageHub->openSession(kEndpointInfos[0].id, mMessageHub->getId(), + kEndpointInfos[1].id); + } + } + + void setMessageHub(MessageRouter::MessageHub *messageHub) { + mMessageHub = messageHub; + } + + private: + MessageRouter::MessageHub *mMessageHub = nullptr; +}; + +TEST_F(MessageRouterTest, RegisterMessageHubNameIsUnique) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + + MessageHubCallbackStoreData callback(/* message= */ nullptr, + /* session= */ nullptr); + std::optional<MessageRouter::MessageHub> messageHub1 = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub1.has_value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback); + EXPECT_TRUE(messageHub2.has_value()); + + std::optional<MessageRouter::MessageHub> messageHub3 = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_FALSE(messageHub3.has_value()); +} + +TEST_F(MessageRouterTest, RegisterMessageHubIdIsUnique) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + + MessageHubCallbackStoreData callback(/* message= */ nullptr, + /* session= */ nullptr); + std::optional<MessageRouter::MessageHub> messageHub1 = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub1.has_value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback); + EXPECT_TRUE(messageHub2.has_value()); + + std::optional<MessageRouter::MessageHub> messageHub3 = + router.registerMessageHub("hub3", /* id= */ 1, callback); + EXPECT_FALSE(messageHub3.has_value()); +} + +TEST_F(MessageRouterTest, RegisterMessageHubGetListOfHubs) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + + MessageHubCallbackStoreData callback(/* message= */ nullptr, + /* session= */ nullptr); + std::optional<MessageRouter::MessageHub> messageHub1 = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub1.has_value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback); + EXPECT_TRUE(messageHub2.has_value()); + std::optional<MessageRouter::MessageHub> messageHub3 = + router.registerMessageHub("hub3", /* id= */ 3, callback); + EXPECT_TRUE(messageHub3.has_value()); + + DynamicVector<MessageHubInfo> messageHubs; + router.forEachMessageHub( + [&messageHubs](const MessageHubInfo &messageHubInfo) { + messageHubs.push_back(messageHubInfo); + return false; + }); + EXPECT_EQ(messageHubs.size(), 3); + EXPECT_EQ(messageHubs[0].name, "hub1"); + EXPECT_EQ(messageHubs[1].name, "hub2"); + EXPECT_EQ(messageHubs[2].name, "hub3"); + EXPECT_EQ(messageHubs[0].id, 1); + EXPECT_EQ(messageHubs[1].id, 2); + EXPECT_EQ(messageHubs[2].id, 3); + EXPECT_EQ(messageHubs[0].id, messageHub1->getId()); + EXPECT_EQ(messageHubs[1].id, messageHub2->getId()); + EXPECT_EQ(messageHubs[2].id, messageHub3->getId()); +} + +TEST_F(MessageRouterTest, RegisterMessageHubGetListOfHubsWithUnregister) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + + MessageHubCallbackStoreData callback(/* message= */ nullptr, + /* session= */ nullptr); + std::optional<MessageRouter::MessageHub> messageHub1 = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub1.has_value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback); + EXPECT_TRUE(messageHub2.has_value()); + std::optional<MessageRouter::MessageHub> messageHub3 = + router.registerMessageHub("hub3", /* id= */ 3, callback); + EXPECT_TRUE(messageHub3.has_value()); + + DynamicVector<MessageHubInfo> messageHubs; + router.forEachMessageHub( + [&messageHubs](const MessageHubInfo &messageHubInfo) { + messageHubs.push_back(messageHubInfo); + return false; + }); + EXPECT_EQ(messageHubs.size(), 3); + EXPECT_EQ(messageHubs[0].name, "hub1"); + EXPECT_EQ(messageHubs[1].name, "hub2"); + EXPECT_EQ(messageHubs[2].name, "hub3"); + EXPECT_EQ(messageHubs[0].id, 1); + EXPECT_EQ(messageHubs[1].id, 2); + EXPECT_EQ(messageHubs[2].id, 3); + EXPECT_EQ(messageHubs[0].id, messageHub1->getId()); + EXPECT_EQ(messageHubs[1].id, messageHub2->getId()); + EXPECT_EQ(messageHubs[2].id, messageHub3->getId()); + + // Clear messageHubs and reset messageHub2 + messageHubs.clear(); + messageHub2.reset(); + + router.forEachMessageHub( + [&messageHubs](const MessageHubInfo &messageHubInfo) { + messageHubs.push_back(messageHubInfo); + return false; + }); + EXPECT_EQ(messageHubs.size(), 2); + EXPECT_EQ(messageHubs[0].name, "hub1"); + EXPECT_EQ(messageHubs[1].name, "hub3"); + EXPECT_EQ(messageHubs[0].id, 1); + EXPECT_EQ(messageHubs[1].id, 3); + EXPECT_EQ(messageHubs[0].id, messageHub1->getId()); + EXPECT_EQ(messageHubs[1].id, messageHub3->getId()); +} + +TEST_F(MessageRouterTest, RegisterMessageHubTooManyFails) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + static_assert(kMaxMessageHubs == 3); + constexpr const char *kNames[3] = {"hub1", "hub2", "hub3"}; + + MessageHubCallbackStoreData callback(/* message= */ nullptr, + /* session= */ nullptr); + MessageRouter::MessageHub messageHubs[kMaxMessageHubs]; + for (size_t i = 0; i < kMaxMessageHubs; ++i) { + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub(kNames[i], /* id= */ i, callback); + EXPECT_TRUE(messageHub.has_value()); + messageHubs[i] = std::move(*messageHub); + } + + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub("shouldfail", /* id= */ kMaxMessageHubs * 2, + callback); + EXPECT_FALSE(messageHub.has_value()); +} + +TEST_F(MessageRouterTest, GetEndpointInfo) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + + MessageHubCallbackStoreData callback(/* message= */ nullptr, + /* session= */ nullptr); + std::optional<MessageRouter::MessageHub> messageHub1 = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub1.has_value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback); + EXPECT_TRUE(messageHub2.has_value()); + std::optional<MessageRouter::MessageHub> messageHub3 = + router.registerMessageHub("hub3", /* id= */ 3, callback); + EXPECT_TRUE(messageHub3.has_value()); + + for (size_t i = 0; i < kNumEndpoints; ++i) { + EXPECT_EQ( + router.getEndpointInfo(messageHub1->getId(), kEndpointInfos[i].id), + kEndpointInfos[i]); + EXPECT_EQ( + router.getEndpointInfo(messageHub2->getId(), kEndpointInfos[i].id), + kEndpointInfos[i]); + EXPECT_EQ( + router.getEndpointInfo(messageHub3->getId(), kEndpointInfos[i].id), + kEndpointInfos[i]); + } +} + +TEST_F(MessageRouterTest, RegisterSessionTwoDifferentMessageHubs) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + Session sessionFromCallback1; + Session sessionFromCallback2; + MessageHubCallbackStoreData callback(/* message= */ nullptr, + &sessionFromCallback1); + MessageHubCallbackStoreData callback2(/* message= */ nullptr, + &sessionFromCallback2); + + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub.has_value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback2); + EXPECT_TRUE(messageHub2.has_value()); + + // Open session from messageHub:1 to messageHub2:2 + SessionId sessionId = messageHub->openSession( + kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Get session from messageHub and compare it with messageHub2 + std::optional<Session> sessionAfterRegistering = + messageHub->getSessionWithId(sessionId); + EXPECT_TRUE(sessionAfterRegistering.has_value()); + EXPECT_EQ(sessionAfterRegistering->sessionId, sessionId); + EXPECT_EQ(sessionAfterRegistering->initiator.messageHubId, + messageHub->getId()); + EXPECT_EQ(sessionAfterRegistering->initiator.endpointId, + kEndpointInfos[0].id); + EXPECT_EQ(sessionAfterRegistering->peer.messageHubId, messageHub2->getId()); + EXPECT_EQ(sessionAfterRegistering->peer.endpointId, kEndpointInfos[1].id); + std::optional<Session> sessionAfterRegistering2 = + messageHub2->getSessionWithId(sessionId); + EXPECT_TRUE(sessionAfterRegistering2.has_value()); + EXPECT_EQ(*sessionAfterRegistering, *sessionAfterRegistering2); + + // Close the session and verify it is closed on both message hubs + EXPECT_NE(*sessionAfterRegistering, sessionFromCallback1); + EXPECT_NE(*sessionAfterRegistering, sessionFromCallback2); + EXPECT_TRUE(messageHub->closeSession(sessionId)); + EXPECT_EQ(*sessionAfterRegistering, sessionFromCallback1); + EXPECT_EQ(*sessionAfterRegistering, sessionFromCallback2); + EXPECT_FALSE(messageHub->getSessionWithId(sessionId).has_value()); + EXPECT_FALSE(messageHub2->getSessionWithId(sessionId).has_value()); +} + +TEST_F(MessageRouterTest, UnregisterMessageHubCausesSessionClosed) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + Session sessionFromCallback1; + Session sessionFromCallback2; + MessageHubCallbackStoreData callback(/* message= */ nullptr, + &sessionFromCallback1); + MessageHubCallbackStoreData callback2(/* message= */ nullptr, + &sessionFromCallback2); + + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub.has_value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback2); + EXPECT_TRUE(messageHub2.has_value()); + + // Open session from messageHub:1 to messageHub2:2 + SessionId sessionId = messageHub->openSession( + kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Get session from messageHub and compare it with messageHub2 + std::optional<Session> sessionAfterRegistering = + messageHub->getSessionWithId(sessionId); + EXPECT_TRUE(sessionAfterRegistering.has_value()); + EXPECT_EQ(sessionAfterRegistering->sessionId, sessionId); + EXPECT_EQ(sessionAfterRegistering->initiator.messageHubId, + messageHub->getId()); + EXPECT_EQ(sessionAfterRegistering->initiator.endpointId, + kEndpointInfos[0].id); + EXPECT_EQ(sessionAfterRegistering->peer.messageHubId, messageHub2->getId()); + EXPECT_EQ(sessionAfterRegistering->peer.endpointId, kEndpointInfos[1].id); + std::optional<Session> sessionAfterRegistering2 = + messageHub2->getSessionWithId(sessionId); + EXPECT_TRUE(sessionAfterRegistering2.has_value()); + EXPECT_EQ(*sessionAfterRegistering, *sessionAfterRegistering2); + + // Close the session and verify it is closed on the other hub + EXPECT_NE(*sessionAfterRegistering, sessionFromCallback1); + messageHub2.reset(); + EXPECT_EQ(*sessionAfterRegistering, sessionFromCallback1); + EXPECT_FALSE(messageHub->getSessionWithId(sessionId).has_value()); +} + +TEST_F(MessageRouterTest, RegisterSessionSameMessageHubInvalid) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + Session sessionFromCallback1; + Session sessionFromCallback2; + MessageHubCallbackStoreData callback(/* message= */ nullptr, + &sessionFromCallback1); + MessageHubCallbackStoreData callback2(/* message= */ nullptr, + &sessionFromCallback2); + + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub.has_value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback2); + EXPECT_TRUE(messageHub2.has_value()); + + // Open session from messageHub:2 to messageHub:2 + SessionId sessionId = messageHub->openSession( + kEndpointInfos[1].id, messageHub->getId(), kEndpointInfos[1].id); + EXPECT_EQ(sessionId, SESSION_ID_INVALID); + + // Open session from messageHub:1 to messageHub:3 + sessionId = messageHub->openSession(kEndpointInfos[0].id, messageHub->getId(), + kEndpointInfos[2].id); + EXPECT_EQ(sessionId, SESSION_ID_INVALID); +} + +TEST_F(MessageRouterTest, RegisterSessionDifferentMessageHubsSameEndpoints) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + Session sessionFromCallback1; + Session sessionFromCallback2; + MessageHubCallbackStoreData callback(/* message= */ nullptr, + &sessionFromCallback1); + MessageHubCallbackStoreData callback2(/* message= */ nullptr, + &sessionFromCallback2); + + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub.has_value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback2); + EXPECT_TRUE(messageHub2.has_value()); + + // Open session from messageHub:1 to messageHub:2 + SessionId sessionId = messageHub->openSession( + kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[0].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); +} + +TEST_F(MessageRouterTest, + RegisterSessionTwoDifferentMessageHubsInvalidEndpoint) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + MessageHubCallbackStoreData callback(/* message= */ nullptr, + /* session= */ nullptr); + MessageHubCallbackStoreData callback2(/* message= */ nullptr, + /* session= */ nullptr); + + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub.has_value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback2); + EXPECT_TRUE(messageHub2.has_value()); + + // Open session from messageHub with other non-registered endpoint - not + // valid + SessionId sessionId = messageHub->openSession( + kEndpointInfos[0].id, messageHub2->getId(), /* toEndpointId= */ 10); + EXPECT_EQ(sessionId, SESSION_ID_INVALID); +} + +TEST_F(MessageRouterTest, ThirdMessageHubTriesToFindOthersSession) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + Session sessionFromCallback1; + Session sessionFromCallback2; + Session sessionFromCallback3; + MessageHubCallbackStoreData callback(/* message= */ nullptr, + &sessionFromCallback1); + MessageHubCallbackStoreData callback2(/* message= */ nullptr, + &sessionFromCallback2); + MessageHubCallbackStoreData callback3(/* message= */ nullptr, + &sessionFromCallback3); + + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub.has_value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback2); + EXPECT_TRUE(messageHub2.has_value()); + std::optional<MessageRouter::MessageHub> messageHub3 = + router.registerMessageHub("hub3", /* id= */ 3, callback3); + EXPECT_TRUE(messageHub3.has_value()); + + // Open session from messageHub:1 to messageHub2:2 + SessionId sessionId = messageHub->openSession( + kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Get session from messageHub and compare it with messageHub2 + std::optional<Session> sessionAfterRegistering = + messageHub->getSessionWithId(sessionId); + EXPECT_TRUE(sessionAfterRegistering.has_value()); + EXPECT_EQ(sessionAfterRegistering->sessionId, sessionId); + EXPECT_EQ(sessionAfterRegistering->initiator.messageHubId, + messageHub->getId()); + EXPECT_EQ(sessionAfterRegistering->initiator.endpointId, + kEndpointInfos[0].id); + EXPECT_EQ(sessionAfterRegistering->peer.messageHubId, messageHub2->getId()); + EXPECT_EQ(sessionAfterRegistering->peer.endpointId, kEndpointInfos[1].id); + std::optional<Session> sessionAfterRegistering2 = + messageHub2->getSessionWithId(sessionId); + EXPECT_TRUE(sessionAfterRegistering2.has_value()); + EXPECT_EQ(*sessionAfterRegistering, *sessionAfterRegistering2); + + // Third message hub tries to find the session - not found + EXPECT_FALSE(messageHub3->getSessionWithId(sessionId).has_value()); + // Third message hub tries to close the session - not found + EXPECT_FALSE(messageHub3->closeSession(sessionId)); + + // Get session from messageHub and compare it with messageHub2 again + sessionAfterRegistering = messageHub->getSessionWithId(sessionId); + EXPECT_TRUE(sessionAfterRegistering.has_value()); + EXPECT_EQ(sessionAfterRegistering->sessionId, sessionId); + EXPECT_EQ(sessionAfterRegistering->initiator.messageHubId, + messageHub->getId()); + EXPECT_EQ(sessionAfterRegistering->initiator.endpointId, + kEndpointInfos[0].id); + EXPECT_EQ(sessionAfterRegistering->peer.messageHubId, messageHub2->getId()); + EXPECT_EQ(sessionAfterRegistering->peer.endpointId, kEndpointInfos[1].id); + sessionAfterRegistering2 = messageHub2->getSessionWithId(sessionId); + EXPECT_TRUE(sessionAfterRegistering2.has_value()); + EXPECT_EQ(*sessionAfterRegistering, *sessionAfterRegistering2); + + // Close the session and verify it is closed on both message hubs + EXPECT_NE(*sessionAfterRegistering, sessionFromCallback1); + EXPECT_NE(*sessionAfterRegistering, sessionFromCallback2); + EXPECT_TRUE(messageHub->closeSession(sessionId)); + EXPECT_EQ(*sessionAfterRegistering, sessionFromCallback1); + EXPECT_EQ(*sessionAfterRegistering, sessionFromCallback2); + EXPECT_NE(*sessionAfterRegistering, sessionFromCallback3); + EXPECT_FALSE(messageHub->getSessionWithId(sessionId).has_value()); + EXPECT_FALSE(messageHub2->getSessionWithId(sessionId).has_value()); +} + +TEST_F(MessageRouterTest, ThreeMessageHubsAndThreeSessions) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + MessageHubCallbackStoreData callback(/* message= */ nullptr, + /* session= */ nullptr); + MessageHubCallbackStoreData callback2(/* message= */ nullptr, + /* session= */ nullptr); + MessageHubCallbackStoreData callback3(/* message= */ nullptr, + /* session= */ nullptr); + + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub.has_value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback2); + EXPECT_TRUE(messageHub2.has_value()); + std::optional<MessageRouter::MessageHub> messageHub3 = + router.registerMessageHub("hub3", /* id= */ 3, callback3); + EXPECT_TRUE(messageHub3.has_value()); + + // Open session from messageHub:1 to messageHub2:2 + SessionId sessionId = messageHub->openSession( + kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Open session from messageHub2:2 to messageHub3:3 + SessionId sessionId2 = messageHub2->openSession( + kEndpointInfos[1].id, messageHub3->getId(), kEndpointInfos[2].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Open session from messageHub3:3 to messageHub1:1 + SessionId sessionId3 = messageHub3->openSession( + kEndpointInfos[2].id, messageHub->getId(), kEndpointInfos[0].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Get sessions and compare + // Find session: MessageHub1:1 -> MessageHub2:2 + std::optional<Session> sessionAfterRegistering = + messageHub->getSessionWithId(sessionId); + EXPECT_TRUE(sessionAfterRegistering.has_value()); + std::optional<Session> sessionAfterRegistering2 = + messageHub2->getSessionWithId(sessionId); + EXPECT_TRUE(sessionAfterRegistering2.has_value()); + EXPECT_FALSE(messageHub3->getSessionWithId(sessionId).has_value()); + EXPECT_EQ(*sessionAfterRegistering, *sessionAfterRegistering2); + + // Find session: MessageHub2:2 -> MessageHub3:3 + sessionAfterRegistering = messageHub2->getSessionWithId(sessionId2); + EXPECT_TRUE(sessionAfterRegistering.has_value()); + sessionAfterRegistering2 = messageHub3->getSessionWithId(sessionId2); + EXPECT_TRUE(sessionAfterRegistering2.has_value()); + EXPECT_FALSE(messageHub->getSessionWithId(sessionId2).has_value()); + EXPECT_EQ(*sessionAfterRegistering, *sessionAfterRegistering2); + + // Find session: MessageHub3:3 -> MessageHub1:1 + sessionAfterRegistering = messageHub3->getSessionWithId(sessionId3); + EXPECT_TRUE(sessionAfterRegistering.has_value()); + sessionAfterRegistering2 = messageHub->getSessionWithId(sessionId3); + EXPECT_TRUE(sessionAfterRegistering2.has_value()); + EXPECT_FALSE(messageHub2->getSessionWithId(sessionId3).has_value()); + EXPECT_EQ(*sessionAfterRegistering, *sessionAfterRegistering2); + + // Close sessions from receivers and verify they are closed on all hubs + EXPECT_TRUE(messageHub2->closeSession(sessionId)); + EXPECT_TRUE(messageHub3->closeSession(sessionId2)); + EXPECT_TRUE(messageHub->closeSession(sessionId3)); + for (SessionId id : {sessionId, sessionId2, sessionId3}) { + EXPECT_FALSE(messageHub->getSessionWithId(id).has_value()); + EXPECT_FALSE(messageHub2->getSessionWithId(id).has_value()); + EXPECT_FALSE(messageHub3->getSessionWithId(id).has_value()); + } +} + +TEST_F(MessageRouterTest, SendMessageToSession) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + constexpr size_t kMessageSize = 5; + pw::UniquePtr<std::byte[]> messageData = + mAllocator.MakeUniqueArray<std::byte>(kMessageSize); + for (size_t i = 0; i < 5; ++i) { + messageData[i] = static_cast<std::byte>(i + 1); + } + + Message messageFromCallback1; + Message messageFromCallback2; + Message messageFromCallback3; + Session sessionFromCallback1; + Session sessionFromCallback2; + Session sessionFromCallback3; + MessageHubCallbackStoreData callback(&messageFromCallback1, + &sessionFromCallback1); + MessageHubCallbackStoreData callback2(&messageFromCallback2, + &sessionFromCallback2); + MessageHubCallbackStoreData callback3(&messageFromCallback3, + &sessionFromCallback3); + + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub.has_value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback2); + EXPECT_TRUE(messageHub2.has_value()); + std::optional<MessageRouter::MessageHub> messageHub3 = + router.registerMessageHub("hub3", /* id= */ 3, callback3); + EXPECT_TRUE(messageHub3.has_value()); + + // Open session from messageHub:1 to messageHub2:2 + SessionId sessionId = messageHub->openSession( + kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Open session from messageHub2:2 to messageHub3:3 + SessionId sessionId2 = messageHub2->openSession( + kEndpointInfos[1].id, messageHub3->getId(), kEndpointInfos[2].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Open session from messageHub3:3 to messageHub1:1 + SessionId sessionId3 = messageHub3->openSession( + kEndpointInfos[2].id, messageHub->getId(), kEndpointInfos[0].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Send message from messageHub:1 to messageHub2:2 + ASSERT_TRUE(messageHub->sendMessage(std::move(messageData), kMessageSize, + /* messageType= */ 1, + /* messagePermissions= */ 0, sessionId)); + EXPECT_EQ(messageFromCallback2.sessionId, sessionId); + EXPECT_EQ(messageFromCallback2.sender.messageHubId, messageHub->getId()); + EXPECT_EQ(messageFromCallback2.sender.endpointId, kEndpointInfos[0].id); + EXPECT_EQ(messageFromCallback2.recipient.messageHubId, messageHub2->getId()); + EXPECT_EQ(messageFromCallback2.recipient.endpointId, kEndpointInfos[1].id); + EXPECT_EQ(messageFromCallback2.messageType, 1); + EXPECT_EQ(messageFromCallback2.messagePermissions, 0); + EXPECT_EQ(messageFromCallback2.length, kMessageSize); + for (size_t i = 0; i < kMessageSize; ++i) { + EXPECT_EQ(messageFromCallback2.data[i], static_cast<std::byte>(i + 1)); + } + + messageData = mAllocator.MakeUniqueArray<std::byte>(kMessageSize); + for (size_t i = 0; i < 5; ++i) { + messageData[i] = static_cast<std::byte>(i + 1); + } + + // Send message from messageHub2:2 to messageHub:1 + ASSERT_TRUE(messageHub2->sendMessage(std::move(messageData), kMessageSize, + /* messageType= */ 2, + /* messagePermissions= */ 3, sessionId)); + EXPECT_EQ(messageFromCallback1.sessionId, sessionId); + EXPECT_EQ(messageFromCallback1.sender.messageHubId, messageHub2->getId()); + EXPECT_EQ(messageFromCallback1.sender.endpointId, kEndpointInfos[1].id); + EXPECT_EQ(messageFromCallback1.recipient.messageHubId, messageHub->getId()); + EXPECT_EQ(messageFromCallback1.recipient.endpointId, kEndpointInfos[0].id); + EXPECT_EQ(messageFromCallback1.messageType, 2); + EXPECT_EQ(messageFromCallback1.messagePermissions, 3); + EXPECT_EQ(messageFromCallback1.length, kMessageSize); + for (size_t i = 0; i < kMessageSize; ++i) { + EXPECT_EQ(messageFromCallback1.data[i], static_cast<std::byte>(i + 1)); + } +} + +TEST_F(MessageRouterTest, SendMessageToSessionUsingPointerAndFreeCallback) { + struct FreeCallbackContext { + bool *freeCallbackCalled; + std::byte *message; + size_t length; + }; + + pw::Vector< + MessageRouterCallbackAllocator<FreeCallbackContext>::FreeCallbackRecord, + 10> + freeCallbackRecords; + MessageRouterCallbackAllocator<FreeCallbackContext> allocator( + [](std::byte *message, size_t length, + const FreeCallbackContext &context) { + *context.freeCallbackCalled = + message == context.message && length == context.length; + }, + freeCallbackRecords); + + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + constexpr size_t kMessageSize = 5; + std::byte messageData[kMessageSize]; + for (size_t i = 0; i < 5; ++i) { + messageData[i] = static_cast<std::byte>(i + 1); + } + + Message messageFromCallback1; + Message messageFromCallback2; + Message messageFromCallback3; + Session sessionFromCallback1; + Session sessionFromCallback2; + Session sessionFromCallback3; + MessageHubCallbackStoreData callback(&messageFromCallback1, + &sessionFromCallback1); + MessageHubCallbackStoreData callback2(&messageFromCallback2, + &sessionFromCallback2); + MessageHubCallbackStoreData callback3(&messageFromCallback3, + &sessionFromCallback3); + + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub.has_value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback2); + EXPECT_TRUE(messageHub2.has_value()); + std::optional<MessageRouter::MessageHub> messageHub3 = + router.registerMessageHub("hub3", /* id= */ 3, callback3); + EXPECT_TRUE(messageHub3.has_value()); + + // Open session from messageHub:1 to messageHub2:2 + SessionId sessionId = messageHub->openSession( + kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Open session from messageHub2:2 to messageHub3:3 + SessionId sessionId2 = messageHub2->openSession( + kEndpointInfos[1].id, messageHub3->getId(), kEndpointInfos[2].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Open session from messageHub3:3 to messageHub1:1 + SessionId sessionId3 = messageHub3->openSession( + kEndpointInfos[2].id, messageHub->getId(), kEndpointInfos[0].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Send message from messageHub:1 to messageHub2:2 + bool freeCallbackCalled = false; + FreeCallbackContext freeCallbackContext = { + .freeCallbackCalled = &freeCallbackCalled, + .message = messageData, + .length = kMessageSize, + }; + pw::UniquePtr<std::byte[]> data = allocator.MakeUniqueArrayWithCallback( + messageData, kMessageSize, std::move(freeCallbackContext)); + ASSERT_NE(data.get(), nullptr); + + ASSERT_TRUE(messageHub->sendMessage(std::move(data), kMessageSize, + /* messageType= */ 1, + /* messagePermissions= */ 0, sessionId)); + EXPECT_EQ(messageFromCallback2.sessionId, sessionId); + EXPECT_EQ(messageFromCallback2.sender.messageHubId, messageHub->getId()); + EXPECT_EQ(messageFromCallback2.sender.endpointId, kEndpointInfos[0].id); + EXPECT_EQ(messageFromCallback2.recipient.messageHubId, messageHub2->getId()); + EXPECT_EQ(messageFromCallback2.recipient.endpointId, kEndpointInfos[1].id); + EXPECT_EQ(messageFromCallback2.messageType, 1); + EXPECT_EQ(messageFromCallback2.messagePermissions, 0); + EXPECT_EQ(messageFromCallback2.length, kMessageSize); + for (size_t i = 0; i < kMessageSize; ++i) { + EXPECT_EQ(messageFromCallback2.data[i], static_cast<std::byte>(i + 1)); + } + + // Check if free callback was called + EXPECT_FALSE(freeCallbackCalled); + EXPECT_EQ(messageFromCallback2.data.get(), messageData); + messageFromCallback2.data.Reset(); + EXPECT_TRUE(freeCallbackCalled); + + // Send message from messageHub2:2 to messageHub:1 + freeCallbackCalled = false; + FreeCallbackContext freeCallbackContext2 = { + .freeCallbackCalled = &freeCallbackCalled, + .message = messageData, + .length = kMessageSize, + }; + data = allocator.MakeUniqueArrayWithCallback(messageData, kMessageSize, + std::move(freeCallbackContext2)); + ASSERT_NE(data.get(), nullptr); + + ASSERT_TRUE(messageHub2->sendMessage(std::move(data), kMessageSize, + /* messageType= */ 2, + /* messagePermissions= */ 3, sessionId)); + EXPECT_EQ(messageFromCallback1.sessionId, sessionId); + EXPECT_EQ(messageFromCallback1.sender.messageHubId, messageHub2->getId()); + EXPECT_EQ(messageFromCallback1.sender.endpointId, kEndpointInfos[1].id); + EXPECT_EQ(messageFromCallback1.recipient.messageHubId, messageHub->getId()); + EXPECT_EQ(messageFromCallback1.recipient.endpointId, kEndpointInfos[0].id); + EXPECT_EQ(messageFromCallback1.messageType, 2); + EXPECT_EQ(messageFromCallback1.messagePermissions, 3); + EXPECT_EQ(messageFromCallback1.length, kMessageSize); + for (size_t i = 0; i < kMessageSize; ++i) { + EXPECT_EQ(messageFromCallback1.data[i], static_cast<std::byte>(i + 1)); + } + + // Check if free callback was called + EXPECT_FALSE(freeCallbackCalled); + EXPECT_EQ(messageFromCallback1.data.get(), messageData); + messageFromCallback1.data.Reset(); + EXPECT_TRUE(freeCallbackCalled); +} + +TEST_F(MessageRouterTest, SendMessageToSessionInvalidHubAndSession) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + constexpr size_t kMessageSize = 5; + pw::UniquePtr<std::byte[]> messageData = + mAllocator.MakeUniqueArray<std::byte>(kMessageSize); + for (size_t i = 0; i < 5; ++i) { + messageData[i] = static_cast<std::byte>(i + 1); + } + + Message messageFromCallback1; + Message messageFromCallback2; + Message messageFromCallback3; + Session sessionFromCallback1; + Session sessionFromCallback2; + Session sessionFromCallback3; + MessageHubCallbackStoreData callback(&messageFromCallback1, + &sessionFromCallback1); + MessageHubCallbackStoreData callback2(&messageFromCallback2, + &sessionFromCallback2); + MessageHubCallbackStoreData callback3(&messageFromCallback3, + &sessionFromCallback3); + + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub.has_value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback2); + EXPECT_TRUE(messageHub2.has_value()); + std::optional<MessageRouter::MessageHub> messageHub3 = + router.registerMessageHub("hub3", /* id= */ 3, callback3); + EXPECT_TRUE(messageHub3.has_value()); + + // Open session from messageHub:1 to messageHub2:2 + SessionId sessionId = messageHub->openSession( + kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Open session from messageHub2:2 to messageHub3:3 + SessionId sessionId2 = messageHub2->openSession( + kEndpointInfos[1].id, messageHub3->getId(), kEndpointInfos[2].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Open session from messageHub3:3 to messageHub1:1 + SessionId sessionId3 = messageHub3->openSession( + kEndpointInfos[2].id, messageHub->getId(), kEndpointInfos[0].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Send message from messageHub:1 to messageHub2:2 + EXPECT_FALSE(messageHub->sendMessage(std::move(messageData), kMessageSize, + /* messageType= */ 1, + /* messagePermissions= */ 0, + sessionId2)); + EXPECT_FALSE(messageHub2->sendMessage(std::move(messageData), kMessageSize, + /* messageType= */ 2, + /* messagePermissions= */ 3, + sessionId3)); + EXPECT_FALSE(messageHub3->sendMessage(std::move(messageData), kMessageSize, + /* messageType= */ 2, + /* messagePermissions= */ 3, + sessionId)); +} + +TEST_F(MessageRouterTest, SendMessageToSessionCallbackFailureClosesSession) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + constexpr size_t kMessageSize = 5; + pw::UniquePtr<std::byte[]> messageData = + mAllocator.MakeUniqueArray<std::byte>(kMessageSize); + for (size_t i = 0; i < 5; ++i) { + messageData[i] = static_cast<std::byte>(i + 1); + } + + bool wasMessageReceivedCalled1 = false; + bool wasMessageReceivedCalled2 = false; + bool wasMessageReceivedCalled3 = false; + MessageHubCallbackAlwaysFails callback1( + &wasMessageReceivedCalled1, + /* wasSessionClosedCalled= */ nullptr); + MessageHubCallbackAlwaysFails callback2( + &wasMessageReceivedCalled2, + /* wasSessionClosedCalled= */ nullptr); + MessageHubCallbackAlwaysFails callback3( + &wasMessageReceivedCalled3, + /* wasSessionClosedCalled= */ nullptr); + + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub("hub1", /* id= */ 1, callback1); + EXPECT_TRUE(messageHub.has_value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback2); + EXPECT_TRUE(messageHub2.has_value()); + std::optional<MessageRouter::MessageHub> messageHub3 = + router.registerMessageHub("hub3", /* id= */ 3, callback3); + EXPECT_TRUE(messageHub3.has_value()); + + // Open session from messageHub:1 to messageHub2:2 + SessionId sessionId = messageHub->openSession( + kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Open session from messageHub2:2 to messageHub3:3 + SessionId sessionId2 = messageHub2->openSession( + kEndpointInfos[1].id, messageHub3->getId(), kEndpointInfos[2].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Open session from messageHub3:3 to messageHub1:1 + SessionId sessionId3 = messageHub3->openSession( + kEndpointInfos[2].id, messageHub->getId(), kEndpointInfos[0].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Send message from messageHub2:2 to messageHub3:3 + EXPECT_FALSE(wasMessageReceivedCalled1); + EXPECT_FALSE(wasMessageReceivedCalled2); + EXPECT_FALSE(wasMessageReceivedCalled3); + EXPECT_FALSE(messageHub->getSessionWithId(sessionId2).has_value()); + EXPECT_TRUE(messageHub2->getSessionWithId(sessionId2).has_value()); + EXPECT_TRUE(messageHub3->getSessionWithId(sessionId2).has_value()); + + EXPECT_FALSE(messageHub2->sendMessage(std::move(messageData), kMessageSize, + /* messageType= */ 1, + /* messagePermissions= */ 0, + sessionId2)); + EXPECT_FALSE(wasMessageReceivedCalled1); + EXPECT_FALSE(wasMessageReceivedCalled2); + EXPECT_TRUE(wasMessageReceivedCalled3); + EXPECT_FALSE(messageHub->getSessionWithId(sessionId2).has_value()); + EXPECT_FALSE(messageHub2->getSessionWithId(sessionId2).has_value()); + EXPECT_FALSE(messageHub3->getSessionWithId(sessionId2).has_value()); + + // Try to send a message on the same session - should fail + wasMessageReceivedCalled1 = false; + wasMessageReceivedCalled2 = false; + wasMessageReceivedCalled3 = false; + messageData = mAllocator.MakeUniqueArray<std::byte>(kMessageSize); + for (size_t i = 0; i < 5; ++i) { + messageData[i] = static_cast<std::byte>(i + 1); + } + EXPECT_FALSE(messageHub2->sendMessage(std::move(messageData), kMessageSize, + /* messageType= */ 1, + /* messagePermissions= */ 0, + sessionId2)); + messageData = mAllocator.MakeUniqueArray<std::byte>(kMessageSize); + for (size_t i = 0; i < 5; ++i) { + messageData[i] = static_cast<std::byte>(i + 1); + } + EXPECT_FALSE(messageHub3->sendMessage(std::move(messageData), kMessageSize, + /* messageType= */ 1, + /* messagePermissions= */ 0, + sessionId2)); + EXPECT_FALSE(wasMessageReceivedCalled1); + EXPECT_FALSE(wasMessageReceivedCalled2); + EXPECT_FALSE(wasMessageReceivedCalled3); +} + +TEST_F(MessageRouterTest, MessageHubCallbackCanCallOtherMessageHubAPIs) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + constexpr size_t kMessageSize = 5; + pw::UniquePtr<std::byte[]> messageData = + mAllocator.MakeUniqueArray<std::byte>(kMessageSize); + for (size_t i = 0; i < 5; ++i) { + messageData[i] = static_cast<std::byte>(i + 1); + } + + MessageHubCallbackCallsMessageHubApisDuringCallback callback; + MessageHubCallbackCallsMessageHubApisDuringCallback callback2; + MessageHubCallbackCallsMessageHubApisDuringCallback callback3; + + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub.has_value()); + callback.setMessageHub(&messageHub.value()); + std::optional<MessageRouter::MessageHub> messageHub2 = + router.registerMessageHub("hub2", /* id= */ 2, callback2); + EXPECT_TRUE(messageHub2.has_value()); + callback2.setMessageHub(&messageHub2.value()); + std::optional<MessageRouter::MessageHub> messageHub3 = + router.registerMessageHub("hub3", /* id= */ 3, callback3); + EXPECT_TRUE(messageHub3.has_value()); + callback3.setMessageHub(&messageHub3.value()); + + // Open session from messageHub:1 to messageHub2:2 + SessionId sessionId = messageHub->openSession( + kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Open session from messageHub2:2 to messageHub3:3 + SessionId sessionId2 = messageHub2->openSession( + kEndpointInfos[1].id, messageHub3->getId(), kEndpointInfos[2].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Open session from messageHub3:3 to messageHub1:1 + SessionId sessionId3 = messageHub3->openSession( + kEndpointInfos[2].id, messageHub->getId(), kEndpointInfos[0].id); + EXPECT_NE(sessionId, SESSION_ID_INVALID); + + // Send message from messageHub:1 to messageHub2:2 + EXPECT_TRUE(messageHub->sendMessage(std::move(messageData), kMessageSize, + /* messageType= */ 1, + /* messagePermissions= */ 0, sessionId)); + + // Send message from messageHub2:2 to messageHub:1 + messageData = mAllocator.MakeUniqueArray<std::byte>(kMessageSize); + for (size_t i = 0; i < 5; ++i) { + messageData[i] = static_cast<std::byte>(i + 1); + } + EXPECT_TRUE(messageHub2->sendMessage(std::move(messageData), kMessageSize, + /* messageType= */ 2, + /* messagePermissions= */ 3, sessionId)); + + // Close all sessions + EXPECT_TRUE(messageHub->closeSession(sessionId)); + EXPECT_TRUE(messageHub2->closeSession(sessionId2)); + EXPECT_TRUE(messageHub3->closeSession(sessionId3)); + + // If we finish the test, both callbacks should have been called + // If the router holds the lock during the callback, this test will timeout +} + +TEST_F(MessageRouterTest, ForEachEndpointOfHub) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + MessageHubCallbackStoreData callback(/* message= */ nullptr, + /* session= */ nullptr); + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub.has_value()); + + DynamicVector<EndpointInfo> endpoints; + EXPECT_TRUE(router.forEachEndpointOfHub( + /* messageHubId= */ 1, [&endpoints](const EndpointInfo &info) { + endpoints.push_back(info); + return false; + })); + EXPECT_EQ(endpoints.size(), kNumEndpoints); + for (size_t i = 0; i < endpoints.size(); ++i) { + EXPECT_EQ(endpoints[i].id, kEndpointInfos[i].id); + EXPECT_STREQ(endpoints[i].name, kEndpointInfos[i].name); + EXPECT_EQ(endpoints[i].version, kEndpointInfos[i].version); + EXPECT_EQ(endpoints[i].type, kEndpointInfos[i].type); + EXPECT_EQ(endpoints[i].requiredPermissions, + kEndpointInfos[i].requiredPermissions); + } +} + +TEST_F(MessageRouterTest, ForEachEndpoint) { + const char *kHubName = "hub1"; + constexpr MessageHubId kHubId = 1; + + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + MessageHubCallbackStoreData callback(/* message= */ nullptr, + /* session= */ nullptr); + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub(kHubName, kHubId, callback); + EXPECT_TRUE(messageHub.has_value()); + + DynamicVector<std::pair<MessageHubInfo, EndpointInfo>> endpoints; + router.forEachEndpoint( + [&endpoints](const MessageHubInfo &hubInfo, const EndpointInfo &info) { + endpoints.push_back(std::make_pair(hubInfo, info)); + }); + EXPECT_EQ(endpoints.size(), kNumEndpoints); + for (size_t i = 0; i < endpoints.size(); ++i) { + EXPECT_EQ(endpoints[i].first.id, kHubId); + EXPECT_STREQ(endpoints[i].first.name, kHubName); + + EXPECT_EQ(endpoints[i].second.id, kEndpointInfos[i].id); + EXPECT_STREQ(endpoints[i].second.name, kEndpointInfos[i].name); + EXPECT_EQ(endpoints[i].second.version, kEndpointInfos[i].version); + EXPECT_EQ(endpoints[i].second.type, kEndpointInfos[i].type); + EXPECT_EQ(endpoints[i].second.requiredPermissions, + kEndpointInfos[i].requiredPermissions); + } +} + +TEST_F(MessageRouterTest, ForEachEndpointOfHubInvalidHub) { + MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router; + MessageHubCallbackStoreData callback(/* message= */ nullptr, + /* session= */ nullptr); + std::optional<MessageRouter::MessageHub> messageHub = + router.registerMessageHub("hub1", /* id= */ 1, callback); + EXPECT_TRUE(messageHub.has_value()); + + DynamicVector<EndpointInfo> endpoints; + EXPECT_FALSE(router.forEachEndpointOfHub( + /* messageHubId= */ 2, [&endpoints](const EndpointInfo &info) { + endpoints.push_back(info); + return false; + })); + EXPECT_EQ(endpoints.size(), 0); +} + +} // namespace +} // namespace chre::message
diff --git a/util/tests/priority_queue_test.cc b/util/tests/priority_queue_test.cc index f6deb66..1d9a173 100644 --- a/util/tests/priority_queue_test.cc +++ b/util/tests/priority_queue_test.cc
@@ -22,12 +22,14 @@ namespace { class FakeElement { public: - FakeElement(){}; + FakeElement() {} FakeElement(int index, int value) { mValue = value; mIndex = index; - }; - ~FakeElement(){}; + } + + ~FakeElement() {} + void setValue(int value) { mValue = value; } @@ -45,7 +47,7 @@ bool compareFunction(const FakeElement &left, const FakeElement &right) { return left.getValue() > right.getValue(); -}; +} class CompareClass { public:
diff --git a/util/tests/synchronized_expandable_memory_pool_test.cc b/util/tests/synchronized_expandable_memory_pool_test.cc index f5957a9..ee62dfb 100644 --- a/util/tests/synchronized_expandable_memory_pool_test.cc +++ b/util/tests/synchronized_expandable_memory_pool_test.cc
@@ -14,7 +14,7 @@ * limitations under the License. */ -#include "chre/util/synchronized_expandable_memory_pool.h" +#include "chre/util/system/synchronized_expandable_memory_pool.h" #include "gtest/gtest.h"
diff --git a/util/tests/synchronized_memory_pool_test.cc b/util/tests/synchronized_memory_pool_test.cc index cecff88..35127ec 100644 --- a/util/tests/synchronized_memory_pool_test.cc +++ b/util/tests/synchronized_memory_pool_test.cc
@@ -14,7 +14,7 @@ * limitations under the License. */ -#include "chre/util/synchronized_memory_pool.h" +#include "chre/util/system/synchronized_memory_pool.h" #include "gtest/gtest.h"
diff --git a/util/tests/transaction_manager_test.cc b/util/tests/transaction_manager_test.cc index 0c70b2f..7df617b 100644 --- a/util/tests/transaction_manager_test.cc +++ b/util/tests/transaction_manager_test.cc
@@ -14,7 +14,7 @@ * limitations under the License. */ -#include "chre/util/transaction_manager.h" +#include "chre/util/system/transaction_manager.h" #include <algorithm> #include <map>
diff --git a/util/util.mk b/util/util.mk index b03bd26..4e5cd1e 100644 --- a/util/util.mk +++ b/util/util.mk
@@ -2,11 +2,35 @@ # Util Makefile # +# Location of various Pigweed modules ######################################### + +PIGWEED_DIR = $(ANDROID_BUILD_TOP)/external/pigweed +PIGWEED_CHRE_DIR = $(ANDROID_BUILD_TOP)/system/chre/external/pigweed + # Common Compiler Flags ######################################################## # Include paths. COMMON_CFLAGS += -I$(CHRE_PREFIX)/util/include +# Pigweed ###################################################################### + +COMMON_CFLAGS += -I$(PIGWEED_CHRE_DIR)/pw_log_nanoapp/public_overrides +COMMON_CFLAGS += -I$(PIGWEED_CHRE_DIR)/pw_assert_nanoapp/public_overrides +COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_allocator/public +COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_assert/public +COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_containers/public +COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_function/public +COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_log/public +COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_polyfill/public +COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_preprocessor/public +COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_result/public +COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_span/public +COMMON_CFLAGS += -I$(PIGWEED_DIR)/pw_status/public +COMMON_CFLAGS += -I$(PIGWEED_DIR)/third_party/fuchsia/repo/sdk/lib/fit/include +COMMON_CFLAGS += -I$(PIGWEED_DIR)/third_party/fuchsia/repo/sdk/lib/stdcompat/include + +COMMON_SRCS += $(PIGWEED_DIR)/pw_allocator/unique_ptr.cc + # Common Source Files ########################################################## COMMON_SRCS += $(CHRE_PREFIX)/util/buffer_base.cc @@ -23,6 +47,7 @@ COMMON_SRCS += $(CHRE_PREFIX)/util/system/ble_util.cc COMMON_SRCS += $(CHRE_PREFIX)/util/system/event_callbacks.cc COMMON_SRCS += $(CHRE_PREFIX)/util/system/debug_dump.cc +COMMON_SRCS += $(CHRE_PREFIX)/util/system/message_router.cc # GoogleTest Source Files ######################################################
diff --git a/variant/CMakeLists.txt b/variant/CMakeLists.txt new file mode 100644 index 0000000..1a09fb8 --- /dev/null +++ b/variant/CMakeLists.txt
@@ -0,0 +1,13 @@ +include($ENV{PW_ROOT}/pw_build/pigweed.cmake) + +pw_add_module_config(chre_variant_CONFIG) +pw_add_library(chre.variant.config INTERFACE + HEADERS + include/chre/variant/config.h + PUBLIC_INCLUDES + include + PUBLIC_DEPS + "${chre_variant_CONFIG}" + PUBLIC_COMPILE_OPTIONS + --include=${CMAKE_CURRENT_SOURCE_DIR}/include/chre/variant/config.h +)
diff --git a/variant/include/chre/variant/config.h b/variant/include/chre/variant/config.h new file mode 100644 index 0000000..9a94d52 --- /dev/null +++ b/variant/include/chre/variant/config.h
@@ -0,0 +1,29 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +// TODO: b/376532038 - Refactor the platform layer to provide static nanoapps +// instead of having it conditionally come out of core/static_nanoapps.cc to +// ensure the build graph can properly represent chre.core. +#if defined(CHRE_INCLUDE_DEFAULT_STATIC_NANOAPPS) +// This cannot be supported due to how the build rules are set up. Ideally this +// would be part of a shared platform layer, but it's in fact part of core. +#error "CMake does not permit the built in default static nanoapps" +#endif // defined(CHRE_INCLUDE_DEFAULT_STATIC_NANOAPPS) + +// This should provide all CHRE_* configuration defines. +#include "chre/target_variant/config.h"
diff --git a/variant/tinysys/variant.mk b/variant/tinysys/variant.mk index 5849305..ccb2db5 100644 --- a/variant/tinysys/variant.mk +++ b/variant/tinysys/variant.mk
@@ -53,20 +53,21 @@ TINYSYS_CFLAGS += -I$(RISCV_TINYSYS_PREFIX)/scp/project/RV55_A/$(TINYSYS_PLATFORM)/platform/inc TINYSYS_CFLAGS += -I$(RISCV_TINYSYS_PREFIX)/scp/project/RV55_A/common/platform/inc -# Clang include paths -TINYSYS_CFLAGS += -I$(RISCV_TOOLCHAIN_PATH)/lib/clang/9.0.1/include -TINYSYS_CFLAGS += -I$(RISCV_TOOLCHAIN_PATH)/dkwlib/MRV55E03v/include - # Common Compiler Flags ######################################################## # Supply a symbol to indicate that the build variant supplies the static # nanoapp list. COMMON_CFLAGS += -DCHRE_VARIANT_SUPPLIES_STATIC_NANOAPP_LIST +# Enable nanoapp authentication by default +TINYSYS_CFLAGS += -DCHRE_NAPP_AUTHENTICATION_ENABLED + # CHRE event count ############################################################# TINYSYS_CFLAGS += -DCHRE_EVENT_PER_BLOCK=32 TINYSYS_CFLAGS += -DCHRE_MAX_EVENT_BLOCKS=4 +TINYSYS_CFLAGS += -DCHRE_UNSCHEDULED_EVENT_PER_BLOCK=32 +TINYSYS_CFLAGS += -DCHRE_MAX_UNSCHEDULED_EVENT_BLOCKS=4 # Optional Features ############################################################ @@ -74,7 +75,7 @@ CHRE_GNSS_SUPPORT_ENABLED = true CHRE_SENSORS_SUPPORT_ENABLED = true CHRE_WIFI_SUPPORT_ENABLED = true -CHRE_WWAN_SUPPORT_ENABLED = false +CHRE_WWAN_SUPPORT_ENABLED = true CHRE_BLE_SUPPORT_ENABLED = true # Common Source Files ##########################################################