diff options
author | 2024-08-02 17:09:45 +0000 | |
---|---|---|
committer | 2024-08-02 17:09:45 +0000 | |
commit | cb5774b5b057de01a6b1aad919ac272d0caa0d19 (patch) | |
tree | b42aa617071caf3a78ec2562094659f82cdd37fd | |
parent | 3556b136ad4f583f417f47339c546cc139a16814 (diff) | |
parent | 26b76ebcb79645522b5a6f01671e5be5a3500e3c (diff) |
Merge "Add Android information service to send API level" into main
-rw-r--r-- | system/btif/src/stack_manager.cc | 2 | ||||
-rw-r--r-- | system/stack/Android.bp | 5 | ||||
-rw-r--r-- | system/stack/BUILD.gn | 2 | ||||
-rw-r--r-- | system/stack/ais/ais_ble.cc | 144 | ||||
-rw-r--r-- | system/stack/fuzzers/gatt_fuzzer.cc | 3 | ||||
-rw-r--r-- | system/stack/gatt/gatt_api.cc | 7 | ||||
-rw-r--r-- | system/stack/include/ais_api.h | 43 | ||||
-rw-r--r-- | system/test/mock/mock_stack_ais_ble.cc | 20 |
8 files changed, 224 insertions, 2 deletions
diff --git a/system/btif/src/stack_manager.cc b/system/btif/src/stack_manager.cc index 3af74062d6..61099d65d8 100644 --- a/system/btif/src/stack_manager.cc +++ b/system/btif/src/stack_manager.cc @@ -63,6 +63,7 @@ #include "internal_include/stack_config.h" #include "rust/src/core/ffi/module.h" #include "stack/btm/btm_ble_int.h" +#include "stack/include/ais_api.h" #include "stack/include/smp_api.h" #ifndef BT_STACK_CLEANUP_WAIT_MS @@ -301,6 +302,7 @@ static void event_start_up_stack(bluetooth::core::CoreInterface* interface, RFCOMM_Init(); GAP_Init(); + AIS_Init(); startProfiles(); diff --git a/system/stack/Android.bp b/system/stack/Android.bp index 1d6376c90d..d6c88e0dfa 100644 --- a/system/stack/Android.bp +++ b/system/stack/Android.bp @@ -38,6 +38,7 @@ cc_library_static { name: "libbt-stack", defaults: ["fluoride_defaults"], local_include_dirs: [ + "ais", "avct", "avdt", "avrc", @@ -180,6 +181,7 @@ cc_library_static { name: "libbt-stack-core", defaults: ["fluoride_defaults"], local_include_dirs: [ + "ais", "avct", "avdt", "avrc", @@ -213,6 +215,7 @@ cc_library_static { "acl/ble_acl.cc", "acl/btm_acl.cc", "acl/btm_pm.cc", + "ais/ais_ble.cc", "arbiter/acl_arbiter.cc", "btm/ble_scanner_hci_interface.cc", "btm/btm_ble.cc", @@ -517,6 +520,7 @@ cc_fuzz { ":TestMockStackL2cap", ":TestMockStackMetrics", ":TestMockStackSdp", + "ais/*.cc", "eatt/*.cc", "fuzzers/gatt_fuzzer.cc", "gatt/*.cc", @@ -1973,6 +1977,7 @@ cc_test { ":TestMockStackL2cap", ":TestMockStackSdp", ":TestMockStackSmp", + "ais/ais_ble.cc", "arbiter/acl_arbiter.cc", "eatt/eatt.cc", "gatt/att_protocol.cc", diff --git a/system/stack/BUILD.gn b/system/stack/BUILD.gn index 2581035379..68d5136db0 100644 --- a/system/stack/BUILD.gn +++ b/system/stack/BUILD.gn @@ -53,6 +53,7 @@ source_set("nonstandard_codecs") { source_set("stack") { sources = [ + "ais/ais_ble.cc", "a2dp/a2dp_api.cc", "a2dp/a2dp_codec_config.cc", "a2dp/a2dp_ext.cc", @@ -187,6 +188,7 @@ source_set("stack") { include_dirs = [ ".", "include", + "ais", "avct", "btm", "avrc", diff --git a/system/stack/ais/ais_ble.cc b/system/stack/ais/ais_ble.cc new file mode 100644 index 0000000000..f545fc7981 --- /dev/null +++ b/system/stack/ais/ais_ble.cc @@ -0,0 +1,144 @@ +/****************************************************************************** + * + * 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. + * + ******************************************************************************/ + +#include <bluetooth/log.h> +#include <com_android_bluetooth_flags.h> +#include <string.h> + +#include <array> + +#include "os/system_properties.h" +#include "stack/include/ais_api.h" +#include "stack/include/bt_types.h" +#include "stack/include/gatt_api.h" +#include "types/bluetooth/uuid.h" + +using bluetooth::Uuid; +using bluetooth::log::error; +using bluetooth::log::warn; + +static const char kPropertyAndroidAPILevel[] = "ro.build.version.sdk"; +static const uint32_t kPropertyAndroidAPILevelDefault = 0; + +const Uuid ANDROID_INFORMATION_SERVICE_UUID = + Uuid::FromString(ANDROID_INFORMATION_SERVICE_UUID_STRING); +const Uuid GATT_UUID_AIS_API_LEVEL = Uuid::FromString(GATT_UUID_AIS_API_LEVEL_STRING); + +/* LE AIS attribute handle */ +static uint16_t attr_api_level_handle; + +static uint32_t api_level; + +void ais_request_cback(uint16_t, uint32_t, tGATTS_REQ_TYPE, tGATTS_DATA*); + +static tGATT_CBACK ais_cback = { + .p_conn_cb = nullptr, + .p_cmpl_cb = nullptr, + .p_disc_res_cb = nullptr, + .p_disc_cmpl_cb = nullptr, + .p_req_cb = ais_request_cback, + .p_enc_cmpl_cb = nullptr, + .p_congestion_cb = nullptr, + .p_phy_update_cb = nullptr, + .p_conn_update_cb = nullptr, + .p_subrate_chg_cb = nullptr, +}; + +/** AIS ATT server attribute access request callback */ +void ais_request_cback(uint16_t conn_id, uint32_t trans_id, tGATTS_REQ_TYPE type, + tGATTS_DATA* p_data) { + tGATT_STATUS status = GATT_INVALID_PDU; + tGATTS_RSP rsp_msg = {}; + uint16_t handle = p_data->read_req.handle; + tGATT_VALUE* p_value = &rsp_msg.attr_value; + uint8_t* p = p_value->value; + + if (type == GATTS_REQ_TYPE_READ_CHARACTERISTIC) { + p_value->handle = handle; + + if (handle == attr_api_level_handle) { + if (p_data->read_req.is_long) { + p_value->offset = p_data->read_req.offset; + status = GATT_NOT_LONG; + } else { + UINT32_TO_STREAM(p, api_level); + p_value->len = 4; + status = GATT_SUCCESS; + } + } else { + status = GATT_NOT_FOUND; + } + } else { + warn("Unknown/unexpected LE AIS ATT request: 0x{:02x}", type); + } + + if (GATTS_SendRsp(conn_id, trans_id, status, &rsp_msg) != GATT_SUCCESS) { + warn("Unable to send GATT server response conn_id:{}", conn_id); + } +} + +/******************************************************************************* + * + * Function ais_attr_db_init + * + * Description AIS ATT database initialization. + * + * Returns void. + * + ******************************************************************************/ +void ais_attr_db_init(void) { + if (!com::android::bluetooth::flags::android_os_identifier()) { + return; + } + api_level = bluetooth::os::GetSystemPropertyUint32(kPropertyAndroidAPILevel, + kPropertyAndroidAPILevelDefault); + // Add Android OS identifier if API level is defined. + if (api_level != kPropertyAndroidAPILevelDefault) { + std::array<uint8_t, Uuid::kNumBytes128> tmp; + tmp.fill(0xc5); // any number is fine here + Uuid app_uuid = Uuid::From128BitBE(tmp); + + tGATT_IF gatt_if = GATT_Register(app_uuid, "Ais", &ais_cback, false); + + GATT_StartIf(gatt_if); + + btgatt_db_element_t android_information_service[] = { + { + .uuid = ANDROID_INFORMATION_SERVICE_UUID, + .type = BTGATT_DB_PRIMARY_SERVICE, + }, + { + .uuid = GATT_UUID_AIS_API_LEVEL, + .type = BTGATT_DB_CHARACTERISTIC, + .properties = GATT_CHAR_PROP_BIT_READ, + .permissions = GATT_PERM_READ_IF_ENCRYPTED_OR_DISCOVERABLE, + }}; + if (GATTS_AddService(gatt_if, android_information_service, + sizeof(android_information_service) / sizeof(btgatt_db_element_t)) != + GATT_SERVICE_STARTED) { + error("Unable to add Android Information Server gatt_if:{}", gatt_if); + } + + attr_api_level_handle = android_information_service[1].attribute_handle; + } +} + +/* + * This routine should not be called except once per stack invocation. + */ +void AIS_Init(void) { ais_attr_db_init(); } diff --git a/system/stack/fuzzers/gatt_fuzzer.cc b/system/stack/fuzzers/gatt_fuzzer.cc index a98f674e72..409e62c1da 100644 --- a/system/stack/fuzzers/gatt_fuzzer.cc +++ b/system/stack/fuzzers/gatt_fuzzer.cc @@ -49,6 +49,9 @@ namespace os { bool GetSystemPropertyBool(const std::string& property, bool default_value) { return default_value; } +uint32_t GetSystemPropertyUint32(const std::string& property, uint32_t default_value) { + return default_value; +} } // namespace os } // namespace bluetooth diff --git a/system/stack/gatt/gatt_api.cc b/system/stack/gatt/gatt_api.cc index c6ea0cf5b0..dff5e42974 100644 --- a/system/stack/gatt/gatt_api.cc +++ b/system/stack/gatt/gatt_api.cc @@ -41,6 +41,7 @@ #include "stack/btm/btm_dev.h" #include "stack/gatt/connection_manager.h" #include "stack/gatt/gatt_int.h" +#include "stack/include/ais_api.h" #include "stack/include/bt_hdr.h" #include "stack/include/bt_uuid16.h" #include "stack/include/l2cap_acl_interface.h" @@ -323,8 +324,10 @@ tGATT_STATUS GATTS_AddService(tGATT_IF gatt_if, btgatt_db_element_t* service, in Uuid* p_uuid = gatts_get_service_uuid(elem.p_db); if (*p_uuid != Uuid::From16Bit(UUID_SERVCLASS_GMCS_SERVER) && *p_uuid != Uuid::From16Bit(UUID_SERVCLASS_GTBS_SERVER)) { - if (com::android::bluetooth::flags::channel_sounding_in_stack() && - *p_uuid == Uuid::From16Bit(UUID_SERVCLASS_RAS)) { + if ((com::android::bluetooth::flags::channel_sounding_in_stack() && + *p_uuid == Uuid::From16Bit(UUID_SERVCLASS_RAS)) || + (com::android::bluetooth::flags::android_os_identifier() && + *p_uuid == ANDROID_INFORMATION_SERVICE_UUID)) { elem.sdp_handle = 0; } else { elem.sdp_handle = gatt_add_sdp_record(*p_uuid, elem.s_hdl, elem.e_hdl); diff --git a/system/stack/include/ais_api.h b/system/stack/include/ais_api.h new file mode 100644 index 0000000000..41dad8242b --- /dev/null +++ b/system/stack/include/ais_api.h @@ -0,0 +1,43 @@ +/****************************************************************************** + * + * 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. + * + ******************************************************************************/ +#ifndef SYSTEM_STACK_INCLUDE_AIS_API_H_ +#define SYSTEM_STACK_INCLUDE_AIS_API_H_ + +#include "types/bluetooth/uuid.h" + +#define ANDROID_INFORMATION_SERVICE_UUID_STRING "e73e0001-ef1b-4e74-8291-2e4f3164f3b5" +/* Android Information Service characteristic */ +#define GATT_UUID_AIS_API_LEVEL_STRING "e73e0002-ef1b-4e74-8291-2e4f3164f3b5" + +extern const bluetooth::Uuid ANDROID_INFORMATION_SERVICE_UUID; +extern const bluetooth::Uuid GATT_UUID_AIS_API_LEVEL; + +/******************************************************************************* + * + * Function AIS_Init + * + * Description Initializes the control blocks used by AIS. + * This routine should not be called except once per + * stack invocation. + * + * Returns Nothing + * + ******************************************************************************/ +void AIS_Init(void); + +#endif // SYSTEM_STACK_INCLUDE_AIS_API_H_ diff --git a/system/test/mock/mock_stack_ais_ble.cc b/system/test/mock/mock_stack_ais_ble.cc new file mode 100644 index 0000000000..29630207b4 --- /dev/null +++ b/system/test/mock/mock_stack_ais_ble.cc @@ -0,0 +1,20 @@ +/* + * 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. + */ + +#include "stack/include/ais_api.h" +#include "test/common/mock_functions.h" + +void AIS_Init(void) { inc_func_call_count(__func__); } |