Remove ToT system/bt code as it has been migrated.
New code location is platform/packages/modules/Bluetooth, removing
ToT in aosp/master to ensure folks do not continue to upload
patches in this project.
BUG: 196026708
Test: TH
Change-Id: I0fe927c913d61f85ca458af0f5620205152dc4db
diff --git a/.clang-format b/.clang-format
deleted file mode 100644
index 0b4b45a..0000000
--- a/.clang-format
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Copyright 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.
-#
-
-#
-# Below are some minor deviations from the default Google style to
-# accommodate for handling of the large legacy code base.
-#
-
-BasedOnStyle: Google
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index d26e74c..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,9 +0,0 @@
-buildtools
-out
-third_party/
-target/
-Cargo.lock
-tags
-cscope.out
-cscope.files
-*.sw?
diff --git a/.style.yapf b/.style.yapf
deleted file mode 100644
index 2b11922..0000000
--- a/.style.yapf
+++ /dev/null
@@ -1,5 +0,0 @@
-[style]
-# http://google.github.io/styleguide/pyguide.html
-based_on_style: google
-indent_width: 4
-column_limit: 120
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index 2b49380..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,68 +0,0 @@
-package {
- default_applicable_licenses: ["system_bt_license"],
-}
-
-// Added automatically by a large-scale-change that took the approach of
-// 'apply every license found to every target'. While this makes sure we respect
-// every license restriction, it may not be entirely correct.
-//
-// e.g. GPL in an MIT project might only apply to the contrib/ directory.
-//
-// Please consider splitting the single license below into multiple licenses,
-// taking care not to lose any license_kind information, and overriding the
-// default license using the 'licenses: [...]' property on targets as needed.
-//
-// For unused files, consider creating a 'fileGroup' with "//visibility:private"
-// to attach the license to, and including a comment whether the files may be
-// used in the current project.
-// See: http://go/android-license-faq
-license {
- name: "system_bt_license",
- visibility: [":__subpackages__"],
- license_kinds: [
- "SPDX-license-identifier-Apache-2.0",
- "SPDX-license-identifier-BSD",
- "SPDX-license-identifier-MIT",
- "legacy_unencumbered",
- ],
- license_text: [
- "NOTICE",
- ],
-}
-
-subdirs = [
- "apex",
- "binder",
- "build",
- "btif",
- "btcore",
- "common",
- "audio_a2dp_hw",
- "audio_bluetooth_hw",
- "audio_hal_interface",
- "audio_hearing_aid_hw",
- "gd",
- "hci",
- "utils",
- "device",
- "stack",
- "osi",
- "embdrv",
- "service",
- "include",
- "main",
- "bta",
- "vendor_libs",
- "test",
- "types",
- "udrv",
- "tools",
- "proto",
-]
-
-filegroup {
- name: "BluetoothTestConfigTemplate",
- srcs: [
- "AndroidTestTemplate.xml",
- ],
-}
diff --git a/AndroidTestTemplate.xml b/AndroidTestTemplate.xml
deleted file mode 100644
index 601be93..0000000
--- a/AndroidTestTemplate.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 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.
--->
-<configuration description="Runs {MODULE}.">
- <option name="test-suite-tag" value="apct" />
- <option name="test-suite-tag" value="apct-native" />
- <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
- <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
- <option name="cleanup" value="true" />
- <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" />
- </target_preparer>
- <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
- <option name="run-command" value="settings put global ble_scan_always_enabled 0" />
- <option name="run-command" value="svc bluetooth disable" />
- </target_preparer>
- <target_preparer class="com.android.tradefed.targetprep.FolderSaver">
- <option name="device-path" value="/data/vendor/ssrdump" />
- </target_preparer>
- <test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp" />
- <option name="module-name" value="{MODULE}" />
- <option name="run-test-as" value="0" />
- </test>
-</configuration>
diff --git a/BUILD.gn b/BUILD.gn
deleted file mode 100644
index ecbfa07..0000000
--- a/BUILD.gn
+++ /dev/null
@@ -1,231 +0,0 @@
-#
-# Copyright 2015 Google, Inc.
-#
-# 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.
-#
-
-# This is the root build file for GN. GN will start processing by loading this
-# file, and recursively load all dependencies until all dependencies are either
-# resolved or known not to exist (which will cause the build to fail). So if
-# you add a new build file, there must be some path of dependencies from this
-# file to your new one or GN won't know about it.
-
-group("all") {
- deps = [ ":bluetooth" ]
-
- #if (use.test) {
- #deps += [ ":bluetooth_tests" ]
- #}
-}
-
-# This pulls in main/BUILD.gn and all of its dependencies.
-group("bluetooth") {
- deps = [
- "//bt/main:bluetooth",
- "//bt/main:bluetooth-static",
- #"//bt/service:bluetoothtbd",
- ]
-}
-
-# TODO(b/190750167) - Re-enable once we're fully Bazel build
-#if (use.test) {
- #group("bluetooth_tests") {
- #deps = [
- #"//bt/btcore:net_test_btcore",
- #"//bt/common:bluetooth_test_common",
- #"//bt/profile/avrcp:net_test_avrcp",
- #"//bt/service:bluetoothtbd_test",
- #"//bt/stack:net_test_btm_iso",
- #"//bt/types:net_test_types",
-
- ##"//bt/packet:net_test_btpackets",
- #]
- #}
-#}
-
-if (host_cpu == target_cpu && host_os == target_os) {
- group("tools") {
- deps = [
- "//bt/gd/dumpsys/bundler:bluetooth_flatbuffer_bundler",
- "//bt/gd/packet/parser:bluetooth_packetgen",
- ]
- }
-}
-
-if (defined(use.android) && use.android) {
- group("android_bluetooth_tests") {
- deps = [
- "//bt/device:net_test_device",
- "//bt/hci:net_test_hci",
- "//bt/osi:net_test_osi",
- "//bt/test/suite:net_test_bluetooth",
- ]
- }
-}
-
-config("target_defaults") {
- include_dirs = [
- "//bt",
- "//bt/linux_include",
- "//bt/types",
- "//bt/include",
-
- # For flatbuffer generated headers
- "${root_gen_dir}/bt/gd/",
- "${root_gen_dir}/bt/gd/dumpsys/bundler",
- ]
-
- cflags = [
- "-fPIC",
- "-Wno-non-c-typedef-for-linkage",
- "-Wno-unreachable-code-return",
- "-Wno-defaulted-function-deleted",
- "-Wno-gnu-variable-sized-type-not-at-end",
- "-Wno-format-nonliteral",
- "-Wno-inconsistent-missing-override",
- "-Wno-unreachable-code",
- "-Wno-range-loop-construct",
- "-Wno-reorder-init-list",
- "-Wno-unused-function",
- "-Wno-unused-result",
- "-Wno-unused-variable",
- "-Wno-unused-const-variable",
- "-Wno-format",
- "-Wno-pessimizing-move",
- "-Wno-unknown-warning-option",
- "-Wno-final-dtor-non-final-class",
- ]
-
- cflags_cc = [
- "-std=c++17",
- ]
-
- defines = [
- "HAS_NO_BDROID_BUILDCFG",
- "OS_GENERIC",
- "OS_LINUX_GENERIC",
- "TARGET_FLOSS",
- "EXPORT_SYMBOL=__attribute__((visibility(\"default\")))",
- "FALLTHROUGH_INTENDED=[[clang::fallthrough]]",
- ]
-
- # If not configured as a dynamic library, default to static library
- if (!(defined(use.bt_dynlib) && use.bt_dynlib)) {
- defines += [
- "STATIC_LIBBLUETOOTH",
- ]
- }
-
- if (!(defined(use.bt_nonstandard_codecs) && use.bt_nonstandard_codecs)) {
- defines += [ "EXCLUDE_NONSTANDARD_CODECS" ]
- }
-
- configs = [ ":external_libchrome" ]
-}
-
-group("libbt-platform-protos-lite") {
- deps = [
- "//external/proto_logging/stats/enums/bluetooth:libbt-platform-protos-lite",
- ]
-}
-
-# Configurations to use as dependencies for GN build
-config("external_gtest") {
- configs = [
- ":pkg_gtest",
- ":pkg_gmock",
- ]
-}
-
-config("external_gtest_main") {
- configs = [ ":pkg_gtest_main" ]
-}
-
-config("external_gmock_main") {
- configs = [ ":pkg_gmock_main" ]
-}
-
-config("external_libchrome") {
- configs = [ ":pkg_libchrome" ]
-}
-
-config("external_modp_b64") {
- configs = [ ":pkg_modp_b64" ]
-}
-
-config("external_tinyxml2") {
- configs = [ ":pkg_tinyxml2" ]
-}
-
-config("external_flatbuffers") {
- lib_dirs = [ "${libdir}" ]
-
- libs = [ "flatbuffers" ]
-}
-
-# Package configurations to extract dependencies from env
-pkg_config("pkg_gtest") {
- pkg_deps = [ "gtest" ]
-}
-
-pkg_config("pkg_gtest_main") {
- pkg_deps = [ "gtest_main" ]
-}
-
-pkg_config("pkg_gmock") {
- pkg_deps = [ "gmock" ]
-}
-
-pkg_config("pkg_gmock_main") {
- pkg_deps = [ "gmock_main" ]
-}
-
-pkg_config("pkg_libchrome") {
- pkg_deps = [ "libchrome" ]
-}
-
-pkg_config("pkg_modp_b64") {
- pkg_deps = [ "libmodp_b64" ]
-}
-
-pkg_config("pkg_tinyxml2") {
- pkg_deps = [ "tinyxml2" ]
-}
-
-# To use non-standard codecs (i.e. ldac, aac, aptx), set this use flag when
-# building. These codecs may have licensing issues that need to be resolved
-# first.
-if (defined(use.bt_nonstandard_codecs) && use.bt_nonstandard_codecs) {
- config("external_aac") {
- configs = [ ":pkg_aac" ]
- }
-
- pkg_config("pkg_aac") {
- pkg_deps = [ "fdk-aac" ]
- }
-
- config("external_libldac") {
- configs = [
- ":pkg_libldacBT_enc",
- ":pkg_libldacBT_abr",
- ]
- }
-
- pkg_config("pkg_libldacBT_enc") {
- pkg_deps = [ "ldacBT-enc" ]
- }
-
- pkg_config("pkg_libldacBT_abr") {
- pkg_deps = [ "ldacBT-abr" ]
- }
-}
diff --git a/Cargo.toml b/Cargo.toml
deleted file mode 100644
index 134dd9f..0000000
--- a/Cargo.toml
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Copyright 2021 Google, Inc.
-#
-# 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.
-
-[workspace]
-
-members = [
- "gd/rust/shim",
- "gd/rust/topshim",
- "gd/rust/linux/mgmt",
- "gd/rust/linux/service",
- "gd/rust/linux/client",
-]
diff --git a/CleanSpec.mk b/CleanSpec.mk
deleted file mode 100644
index 8be8c0a..0000000
--- a/CleanSpec.mk
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2007 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.
-#
-
-# If you don't need to do a full clean build but would like to touch
-# a file or delete some intermediate files, add a clean step to the end
-# of the list. These steps will only be run once, if they haven't been
-# run before.
-#
-# E.g.:
-# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
-# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
-#
-# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
-# files that are missing or have been moved.
-#
-# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
-# Use $(OUT_DIR) to refer to the "out" directory.
-#
-# If you need to re-do something that's already mentioned, just copy
-# the command and add it to the bottom of the list. E.g., if a change
-# that you made last week required touching a file and a change you
-# made today requires touching the same file, just copy the old
-# touch step and add it to the end of the list.
-#
-# ************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
-# ************************************************
-
-# For example:
-#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
-#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
-#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
-#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
-
-# Start of Clean Step list:
-$(call add-clean-step, find $(OUT_DIR) -type f -iname "*blue*" -print0 | xargs -0 rm -f)
-$(call add-clean-step, find $(OUT_DIR) -type f -iname "*bdroid*" -print0 | xargs -0 rm -f)
-
-# ************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
-# ************************************************
diff --git a/EventLogTags.logtags b/EventLogTags.logtags
deleted file mode 100644
index dc1d239..0000000
--- a/EventLogTags.logtags
+++ /dev/null
@@ -1,38 +0,0 @@
-# The entries in this file map a sparse set of log tag numbers to tag names.
-# This is installed on the device, in /system/etc, and parsed by logcat.
-#
-# Tag numbers are decimal integers, from 0 to 2^31. (Let's leave the
-# negative values alone for now.)
-#
-# Tag names are one or more ASCII letters and numbers or underscores, i.e.
-# "[A-Z][a-z][0-9]_". Do not include spaces or punctuation (the former
-# impacts log readability, the latter makes regex searches more annoying).
-#
-# Tag numbers and names are separated by whitespace. Blank lines and lines
-# starting with '#' are ignored.
-#
-# Optionally, after the tag names can be put a description for the value(s)
-# of the tag. Description are in the format
-# (<name>|data type[|data unit])
-# Multiple values are separated by commas.
-#
-# The data type is a number from the following values:
-# 1: int
-# 2: long
-# 3: string
-# 4: list
-#
-# The data unit is a number taken from the following list:
-# 1: Number of objects
-# 2: Number of bytes
-# 3: Number of milliseconds
-# 4: Number of allocations
-# 5: Id
-# 6: Percent
-# Default value for data of type int/long is 2 (bytes).
-#
-# TODO: generate ".java" and ".h" files with integer constants from this file.
-
-1010000 bt_hci_timeout (opcode|1)
-1010001 bt_config_source (opcode|1)
-1010002 bt_hci_unknown_type (hci_type|1)
diff --git a/METADATA b/METADATA
deleted file mode 100644
index d97975c..0000000
--- a/METADATA
+++ /dev/null
@@ -1,3 +0,0 @@
-third_party {
- license_type: NOTICE
-}
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/NOTICE b/NOTICE
deleted file mode 100644
index d645695..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
diff --git a/OWNERS b/OWNERS
deleted file mode 100644
index e83a055..0000000
--- a/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-set noparent
-
-# Temporary block for b/196026708
-baligh@google.com
diff --git a/OWNERS_automotive b/OWNERS_automotive
deleted file mode 100644
index db6814a..0000000
--- a/OWNERS_automotive
+++ /dev/null
@@ -1,2 +0,0 @@
-# Temporary block for b/196026708
-baligh@google.com
diff --git a/OWNERS_chromeos b/OWNERS_chromeos
deleted file mode 100644
index db6814a..0000000
--- a/OWNERS_chromeos
+++ /dev/null
@@ -1,2 +0,0 @@
-# Temporary block for b/196026708
-baligh@google.com
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
deleted file mode 100644
index 04963df..0000000
--- a/PREUPLOAD.cfg
+++ /dev/null
@@ -1,13 +0,0 @@
-[Options]
-ignore_merged_commits = true
-
-[Builtin Hooks]
-clang_format = true
-rustfmt = true
-
-[Builtin Hooks Options]
-rustfmt = --config-path=rustfmt.toml
-
-[Hook Scripts]
-aosp_first = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} ".*$"
-yapf_hook = ./tools/scripts/yapf_checker.py
diff --git a/README.md b/README.md
index 44ceb71..8df253b 100644
--- a/README.md
+++ b/README.md
@@ -1,180 +1 @@
-# Fluoride Bluetooth stack
-
-## Building and running on AOSP
-Just build AOSP - Fluoride is there by default.
-
-## Building and running on Linux
-
-Instructions for a Debian based distribution:
-* Debian Bullseye or newer
-* Ubuntu 20.10 or newer
-* Clang-11 or Clang-12
-* Flex 2.6.x
-* Bison 3.x.x (tested with 3.0.x, 3.2.x and 3.7.x)
-
-You'll want to download some pre-requisite packages as well. If you're currently
-configured for AOSP development, you should have most required packages.
-Otherwise, you can use the following apt-get list or use the `--run-bootstrap`
-option on `build.py` (see below) to get a list of packages missing on your
-system:
-
-```sh
-sudo apt-get install repo git-core gnupg flex bison gperf build-essential \
- zip curl zlib1g-dev gcc-multilib g++-multilib \
- x11proto-core-dev libx11-dev libncurses5 \
- libgl1-mesa-dev libxml2-utils xsltproc unzip liblz4-tool libssl-dev \
- libc++-dev libevent-dev \
- flatbuffers-compiler libflatbuffers1 openssl \
- libflatbuffers-dev libtinyxml2-dev \
- libglib2.0-dev libevent-dev libnss3-dev libdbus-1-dev \
- libprotobuf-dev ninja-build generate-ninja protobuf-compiler \
- libre2-9 debmake \
- llvm libc++abi-dev
-```
-
-You will also need a recent-ish version of Rust and Cargo. Please follow the
-instructions on [Rustup](https://rustup.rs/) to install a recent version.
-
-### Download source
-
-```sh
-mkdir ~/fluoride
-cd ~/fluoride
-git clone https://android.googlesource.com/platform/system/bt
-```
-
-### Using --run-bootstrap on build.py
-
-`build.py` is the helper script used to build Fluoride for Linux (i.e. Floss).
-It accepts a `--run-bootstrap` option that will set up your build staging
-directory and also make sure you have all required system packages to build
-(should work on Debian and Ubuntu). You will still need to build some unpackaged
-dependencies (like libchrome, modp_b64, googletest, etc).
-
-To use it:
-```sh
-./build.py --run-bootstrap
-```
-
-This will install your bootstrapped build environment to `~/.floss`. If you want
-to change this, just pass in `--bootstrap-dir` to the script.
-
-### Build dependencies
-
-The following third-party dependencies are necessary but currently unavailable
-via a package manager. You may have to build these from source and install them
-to your local environment.
-
-* libchrome
-* modp_b64
-
-We provide a script to produce debian packages for those components. Please
-see the instructions in build/dpkg/README.txt for more details.
-
-```sh
-cd build/dpkg
-mkdir -p outdir/{modp_b64,libchrome}
-
-# Build and install modp_b64
-pushd modp_b64
-./gen-src-pkg.sh $(readlink -f ../outdir/modp_b64)
-popd
-sudo dpkg -i outdir/modp_b64/*.deb
-
-# Build and install libchrome
-pushd libchrome
-./gen-src-pkg.sh $(readlink -f ../outdir/libchrome)
-popd
-sudo dpkg -i outdir/libchrome/*.deb
-```
-
-The googletest packages provided by Debian/Ubuntu (libgmock-dev and
-libgtest-dev) do not provide pkg-config files, so you can build your own
-googletest using the steps below:
-
-```sh
-git clone https://github.com/google/googletest.git -b release-1.10.0
-cd googletest # Main directory of the cloned repository.
-mkdir build # Create a directory to hold the build output.
-cd build
-cmake .. # Generate native build scripts for GoogleTest.
-sudo make install -DCMAKE_INSTALL_PREFIX=/usr
-
-# Optional steps if pkgconfig isn't installed to desired location
-# Modify the source (/usr/lib/x86_64-linux-gnu) and target (/usr/lib) based on
-# your local installation.
-for f in $(ls /usr/lib/x86_64-linux-gnu/pkgconfig/{gtest,gmock}*); do \
- ln -sf $f /usr/lib/pkgconfig/$(basename $f);
-done
-```
-
-### Rust dependencies
-
-**Note**: Handled by `--run-bootstrap` option.
-
-Run the following to install Rust dependencies:
-```
-cargo install cxxbridge-cmd
-```
-
-### Stage your build environment
-
-**Note**: Handled by `--run-bootstrap` option.
-
-For host build, we depend on a few other repositories:
-* [Platform2](https://chromium.googlesource.com/chromiumos/platform2/)
-* [Rust crates](https://chromium.googlesource.com/chromiumos/third_party/rust_crates/)
-* [Proto logging](https://android.googlesource.com/platform/frameworks/proto_logging/)
-
-Clone these all somewhere and create your staging environment.
-```sh
-export STAGING_DIR=path/to/your/staging/dir
-mkdir ${STAGING_DIR}
-mkdir -p ${STAGING_DIR}/external
-ln -s $(readlink -f ${PLATFORM2_DIR}/common-mk) ${STAGING_DIR}/common-mk
-ln -s $(readlink -f ${PLATFORM2_DIR}/.gn) ${STAGING_DIR}/.gn
-ln -s $(readlink -f ${RUST_CRATE_DIR}) ${STAGING_DIR}/external/rust
-ln -s $(readlink -f ${PROTO_LOG_DIR}) ${STAGING_DIR}/external/proto_logging
-```
-
-### Build
-
-We provide a build script to automate building assuming you've staged your build
-environment already as above. At this point, make sure you have all the
-pre-requisites installed (i.e. bootstrap option and other dependencies above) or
-you will see failures. In addition, you may need to set a `--libdir=` if your
-libraries are not stored in `/usr/lib` by default.
-
-
-```sh
-./build.py
-```
-
-This will build all targets to the output directory at `--bootstrap-dir` (which
-defaults to `~/.floss`). You can also build each stage separately (if you want
-to iterate on something specific):
-
-* prepare - Generate the GN rules
-* tools - Generate host tools
-* rust - Build the rust portion of the build
-* main - Build all the C/C++ code
-* test - Build all targets and run the tests
-* clean - Clean the output directory
-
-You can choose to run only a specific stage by passing an arg via `--target`.
-
-Currently, Rust builds are a separate stage that uses Cargo to build. See
-[gd/rust/README.md](gd/rust/README.md) for more information. If you are
-iterating on Rust code and want to add new crates, you may also want to use the
-`--no-vendored-rust` option (which will let you use crates.io instead of using
-a pre-populated vendored crates repo).
-
-### Run
-
-By default on Linux, we statically link libbluetooth so you can just run the
-binary directly. By default, it will try to run on hci0 but you can pass it
---hci=N, where N corresponds to /sys/class/bluetooth/hciN.
-
-```sh
-$OUTPUT_DIR/debug/btadapterd --hci=$HCI INIT_gd_hci=true
-```
+This code has been migrated to platform/packages/modules/Bluetooth
diff --git a/TEST_MAPPING b/TEST_MAPPING
deleted file mode 100755
index 69a0709..0000000
--- a/TEST_MAPPING
+++ /dev/null
@@ -1,69 +0,0 @@
-{
- "postsubmit" : [
- {
- "name" : "bluetooth_test_common"
- },
- {
- "name" : "bluetoothtbd_test"
- },
- {
- "name" : "net_test_audio_a2dp_hw"
- },
- {
- "name" : "net_test_avrcp"
- },
- {
- "name" : "net_test_btcore"
- },
- {
- "name" : "net_test_btif"
- },
- {
- "name" : "net_test_btif_profile_queue"
- },
- {
- "name" : "net_test_btpackets"
- },
- {
- "name" : "net_test_device"
- },
- {
- "name" : "net_test_eatt"
- },
- {
- "name" : "net_test_hci"
- },
- {
- "name" : "net_test_performance"
- },
- {
- "name" : "net_test_stack"
- },
- {
- "name" : "net_test_stack_ad_parser"
- },
- {
- "name" : "net_test_stack_multi_adv"
- },
- {
- "name" : "net_test_stack_rfcomm"
- },
- {
- "name" : "net_test_stack_smp"
- },
- {
- "name" : "net_test_types"
- }
- ],
- "presubmit" : [
- {
- "name" : "net_test_hf_client_add_record"
- },
- {
- "name" : "net_test_btif_hf_client_service"
- },
- {
- "name" : "net_test_stack_btm"
- }
- ]
-}
diff --git a/apex/Android.bp b/apex/Android.bp
deleted file mode 100644
index c206dca..0000000
--- a/apex/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-apex {
- name: "com.android.bluetooth.updatable",
- enabled: false,
-
- manifest: "apex_manifest.json",
-
- native_shared_libs: [
- "libbluetooth_jni",
- "libbluetooth"
- ],
- apps: ["Bluetooth"],
-
- compile_multilib: "both",
-
- key: "com.android.bluetooth.updatable.key",
- certificate: ":com.android.bluetooth.updatable.certificate",
-}
-
-apex_key {
- name: "com.android.bluetooth.updatable.key",
- public_key: "com.android.bluetooth.updatable.avbpubkey",
- private_key: "com.android.bluetooth.updatable.pem",
-}
-
-android_app_certificate {
- name: "com.android.bluetooth.updatable.certificate",
- certificate: "com.android.bluetooth.updatable",
-}
diff --git a/apex/apex_manifest.json b/apex/apex_manifest.json
deleted file mode 100644
index 11f4d0b..0000000
--- a/apex/apex_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "com.android.bluetooth.updatable",
- "version": 2
-}
diff --git a/apex/com.android.bluetooth.updatable.avbpubkey b/apex/com.android.bluetooth.updatable.avbpubkey
deleted file mode 100644
index 969211f..0000000
--- a/apex/com.android.bluetooth.updatable.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/apex/com.android.bluetooth.updatable.pem b/apex/com.android.bluetooth.updatable.pem
deleted file mode 100644
index dcbd2be..0000000
--- a/apex/com.android.bluetooth.updatable.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKQIBAAKCAgEA1+wvczWqiosiDtTkbA3nEOUz1fjZhfsWGT5blDOTZFEq4mP6
-heTlEwEc/kYy9UTtG3zrzGtGR+6JueffuI9exjvsVWBdAZBcmb5cgJAkZkpqOMjl
-sS0nHLHtZUWaniASFJnoqFZPFsqR5f5nXCcDUQH2ltVV5+lApxnMgldgvn8nEAYv
-YvOT+N4zwkYv/iYp+/jRv3XRsDehJf62iLhXZYkJdHtqGSq52W5OZFSN61QLd1Zd
-t+8zOQE+nshagnbFdJXXZpITZ/WOAQUzuM9pZzh155yPXhzlE0dB532qUkwCUmcv
-EK09FkS/wEy2Dc9aduAvtRIiS4MobawZSRvq+I/MZp68ioxbdDAW3buB9URBC0k8
-eq7z4TaRgYY2QtQdRecyCP26GeZPP/kz9gYIAslGTY3+B58tRMYp9YwWnQOl37Jj
-2vTg9hmHFRo7gaB0gPj+YORtFhILppx/hu9ASklWV5X6vVqoExM3SFnb05LEGwmc
-Orgp0iKGFfqpRH796Yk2gu+qnupVoLyHRKeq2WKpDlxekRNF+hF27BXlDZMFR5eu
-JYwK7fAq2WndlUz0t2bFSsmTr/S0brr4938F2UUMObQqVr/ynwjE368ADPrihwZX
-gsjW/xXFwW/ftU1BSvdz+Ps+OkoqfM3ac3hTVjT06jtXOk9EJZIqgKUWmTcCAwEA
-AQKCAgEAgF+XxnN9tWkLEq5YMDYDzvO2YdzV1uZ1OQTuBaq0Usw/JuIyLDDuUOI0
-jqjF2zTjk5gtyRdubY3QrIrDZEM5Ibq2w/vK0Ac4Rt/6tyT7vyU3ChPHHBOwUUsn
-zTIYvzJqDX2D6bGGzBIbtBYQ9aTsP9le9kZYEM2I9tBL2qKAjkGiw9AplDclHq1d
-MH/yQLQH+hrw+VffF1m7oY9Sju6qZ1+WE37ckaHpZPBEAzqSNft95bGffp/kYFvx
-Ew4jYbWjp7D+o6jtiL1hdBHXsmT+UbQrxUw7oMSlHVUcRblc7hjquHtIbC3TR84Q
-AxCYnJVPP6YCNzFU2nhcLPhJAEJs68stR2JB6lFD/RLfESmkgGieobxV4UMHYlMc
-rTZgIwhpKTDAMDmBmfZdRVYa7n3euCHZ/dMiLLkMeeXqHpfZ4kDWfUo89DfRdgp2
-XLb0MZ+RriZDZS7QY7IN0aW9M2UBfNtK9XVuXmMhE7haYtEVxp5UZX2IUicYvi6j
-pko/oyCQJjEBQopYYU1to8izGpPsxARLSl3mn6RoRTCaHmXZniu6HztBzuf6cxH4
-Ze78tHKN/PnSOehGAiLGxVAjlah/D6rxrnmDnvwbF0dUSqSiSho78X2JcpeC+jJz
-XbfassFqvKxsZzEz8ZKdciGydcRJHv5kk0Yf6DDZBXeICId+kqECggEBAPRSpBu7
-3hqT75LIXrE7OHd93Zn61+l/ww0K/s8TSuIVYOZjYMSEUXjVJHsm2DHxaMb7/47P
-IR+LU9zcRuNMa6o0e3w9pACXl/VVbECY5F8oNTYa8tkZA1C4nhWjKJiCGsCSzHMA
-D3+tcwGb2sFJe8UYAkyoZozh4rSxphTLS1OgvQ/T24ofJ5afPT4ZX/vTcs4P4skK
-ScwCG9mBsAw03DONVvj7fWTLQLEOrIBwQkWemlTUU3+gWYXzDi+7Ab7oiCNVYCNc
-yMCv05XpZFW1/nOGXgj1z1EAyj09G8BSgnTH47n/7pmHzSVRxTWK3px5dQfDOoEd
-wae5bkGMrrsHSHsCggEBAOI+D0Ebw+RmhuiMGREE/v5VhSCODK0qfyyN5LIpIp8j
-7O1nLwg8uXljHSA6PIuZJptVvSgaKncpjmVLp8LHPEphFV1fH1lglm9hXUjZWmYL
-AONVuma/n6E5x5BbD2dLP4H8EXsZdHmPYaSOB8nD4k1FeMgBNSzCjW62GmT5WUbH
-ii72TTrzb0ytGoX6qEIlFjUL3ivNmywyVA4tHSHJmyuJNpHrLB+DaIUSnCK6VJWG
-a6aJlGDXcCFGJX+YAxL/wAXfySv5/fRd+RUQgNXagOzQ9AZFgERebyc77s2+zKOq
-o7emvQ2sNhGxw6nWEC0KFUSc7UkJ/kKrLwvHDc+gm3UCggEBAICqOLRGRlv2xjal
-gICTMFR1G0tot2XHG5/1x2Sjw062dXY+pYo4KHOaw4B7X2VFvaj0souxdr8W744j
-Ds3Kw/Q5eUJfb8vECYlwd/a4zaNzGDqrDHLZ4k4TO2UnrExMT+xUIoj5YjAZ1rPl
-MNmTajPMRgG6uW690lbYKx9ORBgBUS9RoY7mg0GmEGlwkYSbwRzVbtfyrBRck/AC
-hQSYndIkP8YVIt7+zs2vbZaiB7SEJsA/pM1UU3DgI/ts3yl7aZ456swUo8AdmC6d
-X3Jnyl1qSIEtegUthlOjp8arbPo0/i9IoY2G37kki9d7j2oV6FSzMk8mrYI3e+HX
-RXlHB5sCggEAJtRf6dzKEjlGjkL9Sl6BJUWoQ54drtrMWOlBhxJoTsfrshMzj0Zc
-zuij5xQXsB3o8mAUxv02rJ0FQ31onZV0U4+2CwB4cO6S4yrix84GJd1dmabtBxV8
-YD96cNwwGJphm/2XQnlr9DEXoRZ/X7Gu9XQm9qy+Y6BAhe/bN9lT6UH2BXlgZ+2/
-/Hj5RGVw22liFlijGQGA0GUS6Bv2FAZ2C1LRetnSCNaU6cH36j3wpnkboMmcHcLc
-C9nuNafxXyFl45w0+sc9PuOiDGt4sTt/RSXXu/vRt+o9SY6PveAxXyW6U5rad65G
-2WKZIl0LCa/hVpVYZGDCss6OlIblZ+04wQKCAQAPnQZKHYRAbMwf3hISiD3HVLQO
-ZRegAF1Jxfw19jSAzAuC4KTChilS2ta5N+ppigbdrXmMhQNloX3dNWf5Qfn83Wk6
-/1oVsZSGL0GAOXYfMFSB6d+o3V0NTCf3SDfV/Yk38ffRp0J1GIV5BOveS6vQICPV
-yGr7AjZzXdqkSkQNsn2Wy4Z9kWQyDBmCkqYBbTn6gw+1Qlg028q9YClQFRrANDx4
-VuORCKP2BCoYexICU+awXao/JtgO1fSBnD52vKjGYaaPnqKbYtDwBBo9MaQ1VSFC
-Jj9v2jUoc0j1uEO13IBAvzebnVuSp4S0EW8nM+oal+enrzTLwgWnGw6hTmwT
------END RSA PRIVATE KEY-----
diff --git a/apex/com.android.bluetooth.updatable.pk8 b/apex/com.android.bluetooth.updatable.pk8
deleted file mode 100644
index 59f489f..0000000
--- a/apex/com.android.bluetooth.updatable.pk8
+++ /dev/null
Binary files differ
diff --git a/apex/com.android.bluetooth.updatable.x509.pem b/apex/com.android.bluetooth.updatable.x509.pem
deleted file mode 100644
index 71c169c..0000000
--- a/apex/com.android.bluetooth.updatable.x509.pem
+++ /dev/null
@@ -1,35 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGKTCCBBGgAwIBAgIUZNVGFCcxcNXIbScs78HfUDxmLbEwDQYJKoZIhvcNAQEL
-BQAwgaIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
-DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
-b2lkMR4wHAYDVQQDDBVjb20uYW5kcm9pZC5ibHVldG9vdGgxIjAgBgkqhkiG9w0B
-CQEWE2FuZHJvaWRAYW5kcm9pZC5jb20wIBcNMTkxMTEwMDIyMzI5WhgPNDc1NzEw
-MDYwMjIzMjlaMIGiMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEW
-MBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UE
-CwwHQW5kcm9pZDEeMBwGA1UEAwwVY29tLmFuZHJvaWQuYmx1ZXRvb3RoMSIwIAYJ
-KoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29tMIICIjANBgkqhkiG9w0BAQEF
-AAOCAg8AMIICCgKCAgEAs4zDyliENHT++R/FRTzSoCv6103aAHme/pSrX0qWx8A7
-5IBEtevCaYR/DqCH/QlAZOndf3MPzf1eeGYSJ+YcBGXBNQ2nikUrpZd6a0cBaOXp
-4SQV3qzTasPCBzcOESEanijcSYdB31S5nAtFKQ1Qu3VtgmwyOw3C29A0DeSN1uDQ
-oZXL+11crJ+ZiVyvRA5OdNoKLppcX45fMFEf0Vel3Cp+XbdEBu3p1DkEN0PxKmPO
-43hS2/2hpaEmy3MM2J8v1SzRdyTj2Ftcv/H2JU1D9RUPKOO8iJkTWLgCewE8VVdC
-hZR4/h6vYKBT4v/fE4zTHS0sLlJhrCAz08BbnxNIUAB/WzcwHMy+EO0AaqZ4PLwh
-WfB2UBX4/mru/2BsoL47/aeXsfQi5+M8NrfnUR+KDUBu9SCqY9nSpvDVWLDJKMVh
-OQm2QBYCiPHoDRBClkkQxtBkQJ3CeH5Peufoamrd9oBcpJi8ZJCDtMWoi0Ie4dJR
-c9b4A/25GkxOwhSyNeIGmdnq3osSK6f1grDefi6GmxvTckyvBMQ0OS4BjfaMwqpw
-GpHe6NFZnDB3qfQPqwGOWcwChTFaoajkO/ETgv9m6RQelOBNQbB1lK3PmcIb1IC3
-9xq5Bp3bcb0DdTA/cKunE4kjDNE+zFSaTDKoexB6TtKjTWMMB6hQgx6KwZNWcc8C
-AwEAAaNTMFEwHQYDVR0OBBYEFAC1MgICiq6wSQUio2PzkQfMzAwmMB8GA1UdIwQY
-MBaAFAC1MgICiq6wSQUio2PzkQfMzAwmMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
-hvcNAQELBQADggIBAJmeqnXuhvxKmwEpsAGN2Y5moMNuch09KYssnqU7Nb94VxyT
-1qyrUHdiHxOffN0NKrxlgeoNqtbDIRf0LgmgOxRKGm0gf3+XEmw0KtBD29NyzxDy
-RfAvb+m7biTYhq6+V0wkCoT7HZqeuiSC+l+Gv03Qa3CHc613O5fJCpDJwAXIfRux
-/fvA5k/Pci3upra8kAu7xmZad6EMiY+HO4eK4ph8Kr3T8tFjkKMXzmYgj70zA4MD
-bNkZdUsGSsfVxrqfBJC0aCh0VwDskGXwIbs0q1Uc1RCpLLjdY0gMjkWVkgRKNq+u
-W/HiCaqLbjBk2QVOWugwIo6qqVhMOqCekpQjlIc+zJ8WZDunzFmF2OfmVKV4IkWU
-oHoU8Q2jo0211aO/jO8L7LuzsJb0oeGtOkMDaTm7IRE/cQOdN6bCxKV6da6EdZXw
-YTpTcfqg+D7q1/oYK4DzQsRfdfHrAh9PH/S8BU8buScST5ULdT6N+G4lcE5jAc3C
-c2/CTM3l6CWBAgYK+zDqh2Izjns3br25OT5WEtAcdrEU3igLsn3TU30gsK1+pefi
-Pa0ki00pGYj8Et6bIyBfHZ9nuu0SVAgIKNgtPWIu7QnxqpBHTsNH0GgLI/fCRNps
-XxeFStsf+Nj3NSGXAVUBgQZGAWgeMNjiG8siJJKa3A6ouRCkgiRrqcypYCCi
------END CERTIFICATE-----
diff --git a/apex/key.pem b/apex/key.pem
deleted file mode 100644
index 527a032..0000000
--- a/apex/key.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCzjMPKWIQ0dP75
-H8VFPNKgK/rXTdoAeZ7+lKtfSpbHwDvkgES168JphH8OoIf9CUBk6d1/cw/N/V54
-ZhIn5hwEZcE1DaeKRSull3prRwFo5enhJBXerNNqw8IHNw4RIRqeKNxJh0HfVLmc
-C0UpDVC7dW2CbDI7DcLb0DQN5I3W4NChlcv7XVysn5mJXK9EDk502goumlxfjl8w
-UR/RV6XcKn5dt0QG7enUOQQ3Q/EqY87jeFLb/aGloSbLcwzYny/VLNF3JOPYW1y/
-8fYlTUP1FQ8o47yImRNYuAJ7ATxVV0KFlHj+Hq9goFPi/98TjNMdLSwuUmGsIDPT
-wFufE0hQAH9bNzAczL4Q7QBqpng8vCFZ8HZQFfj+au7/YGygvjv9p5ex9CLn4zw2
-t+dRH4oNQG71IKpj2dKm8NVYsMkoxWE5CbZAFgKI8egNEEKWSRDG0GRAncJ4fk96
-5+hqat32gFykmLxkkIO0xaiLQh7h0lFz1vgD/bkaTE7CFLI14gaZ2ereixIrp/WC
-sN5+LoabG9NyTK8ExDQ5LgGN9ozCqnAakd7o0VmcMHep9A+rAY5ZzAKFMVqhqOQ7
-8ROC/2bpFB6U4E1BsHWUrc+ZwhvUgLf3GrkGndtxvQN1MD9wq6cTiSMM0T7MVJpM
-Mqh7EHpO0qNNYwwHqFCDHorBk1ZxzwIDAQABAoICAGXfODdWgaxBtWkj3YmrONYo
-HeqLAWXDm7JWJ+WpLGOpblH3dQTC/0tfIbfq3T10QlT/W+00G4OEflVRlHuO09aq
-5TR0ytpo5JrPl2XGo8YgrNJQ5xewd0PcTfpKAnE1lySlilctpvJP3//pZRQlueii
-d7/II7fd1vFg8CfxxYhlhfooQ9Qa5LoM09BcBhVXCKzECYLnkgGlhdykKqlcUX7Z
-nVkO4koMMt92ei3hHrQubPQjEOBAx7Zx+ND2NhOyPjF1fGNdSuk27Sj63+3KKQSl
-LjTFAfN+5rsvrDieOt0w5U1lMED+qALq9K2W/7rX6/Bh8O9XTpOasc0zFsjq59uI
-b+uBsZIPaGDpTjkYBKK3xrhNqIuq2ylN+0D14uAK4/z4sXsvP1XymjWkVNR9ii45
-doiDxANvZzqYoXcR5aEkJcO126RbDIw/SIglWTag6mRvNYCnLVcTzVf7uZXFyLXc
-Yk0NpTGAphVl4uVjXFgr8ZXfQIoM51zFvVVh3+dhosNGms1lgcvGHzJRKsOCzaA8
-EdWm3mGZrM8kvviqFoS4PndIIz6hB71MGhISEWbTUssF/AJSDWKdvJEWpTSLUjyY
-OoWaTABjZEjyCXpaIvssQilyOb+UVP6ayMAyfDjz5lDKB2216PhoQ9sOb9fIDrdK
-24XwqdMUqDZJV6GY8nQBAoIBAQDnS1DTUYeQwO1C831d1m8P8PhEDpwioBPv53y/
-owbmbwADTMxWvRfGnmXM5BYAeiDFfECp2HPnB5SGpkXOJOQ8H8WStgkhRglNHBbK
-yDaoLYTZqkk49enYEO6MNuFgTqiOWwgO+MVXPKmjreenhsoAQAKFFBPqyNU6v9a2
-WEHuIMc6Gv+2GkT7wkVwgmTZA1L58Y2EWX0wdDAYLS+0+6u+xJ5lPQI014Y7YNsa
-qvu7PG5gQ8fdU1fPmMRk9OOxiHilLc0GAQPtnF4fQYcNdcZ66FARMjHjZnFqHCPI
-irddmFReMkKj+HHufO6EVf8KkWgyIr9CzS9wh43PWW/CILwZAoIBAQDGuoM4DEV5
-tr+FmF3Rri1P0G+iC3Bm9oTa1S1AC4r8yPiY9Q8/lV009am2gbz6R5TFma+oFU1y
-R3pm6AaijeKmusmi2NGtdbqa9cUL98HtVAT7ZQmzyz9UepyZQmDy/0B4q2fGOUX1
-QnxKIOU2j8CFVUkbijUooRypZG7mIs/PsnTtmDb0JdOr54E26BLaBXbFcrxLuJxX
-STpQVbU3U/Y2jaLnRcPF4e6bCrQbrsH37wMLM3JTes8PRr0IcPDs4sp30Gj55rcL
-vSYZqfeVKadA312In5p4OPJV7/HSzRl4JE4JSWlCRLZepmAy36kFpQzI6N3LUVMp
-RuZtf+UXIVonAoIBAQCVLEIoyICCn6tmbtwAVXiz81prqnCQ9GVnaQlQH7knjZeY
-iUOQ/cwD0c0eZEy8aggQ1p5t7Khz7LOiVELZPXnmPSeUA8vHpgABt4gLqS13MkRo
-jidDkXcMX38693pMPu7/QT7lSRUduoY+hr7NkWVe2+nEIrrlxjmf9nJokGuVRZa4
-pwkdTbwIE7ftZGveewJdKal4Hq9bPNR4A0ytkVOnafAuozZ1FjwAt+sYPAa3L7aQ
-Z6bT3BjaT1D7O+ZObhJBllSQ9r6t1RfvWLfduoQUaRiavqDmZP/oy9VYVf8FYmWn
-iwrn7iitA+5hc4VWL4ngLADm+KcMEKEphilKLwqhAoIBAAC7FNpy6Rp+eovSOJ4Z
-xt7hRFfTNPGb/HcVi5oNsNAnKQre89RnBzW3pY0fQwOkmb50RzoWAffmnWOdfNDC
-NtAoJa+snnDF2w7Q0o2tto/Z3D7Ua0m2+J+l58eEf/jEyYboEnSfJ0u0l+Jp5o3h
-z3JuEtvAEVv547IXxXShMiRwYo+xHJqfPP0H1+jMx6z3ki09s8WPgzuq8ET1W7o9
-W81tjejNz999ajQ1wN3NMbdosJks8kGuVO6Ycv+B8tDcMKRqJsiseYXYhzhW8Ksi
-wROy/pQPCjFg/Dsmq7v7txlDAOp106ZDvGvyrq3hNqzno3llqdMilGy1bwl+C+ie
-3ccCggEBAISSVWD3owRf5n8unlVTmg64miLv3rM3s67F+Hn62qeyYmW3AhMSPyt2
-RIkEr2YrOKQ5D8Ijk3Gad4ae5UdyeCOPg495qk7bD5thcYG4Mo/MVvCQXxgdkeaK
-TFHpzzUttgKUe2EBfCbkxPjzWqf3ba0mvcnW621vUVA+VDqIUlBU9aosRMgDOFUi
-N+667Kj5P382oZHHxFnUZnCa3PczyGG3WLYBLRFAHl3n8kJ9mOUAAlVC8sRgcYmZ
-z2ZYfc22sUREah+kdxvDvR2ayopl86XoyrdTnK0XKEo+lU8Ghovc5Kbopf15KdWz
-/cAk+1ZkOAzn5RIZNaFGw2FKHds1ODQ=
------END PRIVATE KEY-----
diff --git a/audio_a2dp_hw/Android.bp b/audio_a2dp_hw/Android.bp
deleted file mode 100644
index 3ae1ee9..0000000
--- a/audio_a2dp_hw/Android.bp
+++ /dev/null
@@ -1,62 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-cc_defaults {
- name: "audio_a2dp_hw_defaults",
- defaults: ["libchrome_support_defaults"],
- include_dirs: [
- "system/bt",
- "system/bt/audio_a2dp_hw/include",
- "system/bt/gd",
- "system/bt/include",
- "system/bt/types",
- ],
-}
-
-// Audio A2DP shared library for target
-cc_library {
- name: "audio.a2dp.default",
- defaults: ["audio_a2dp_hw_defaults"],
- relative_install_path: "hw",
- srcs: [
- "src/audio_a2dp_hw.cc",
- "src/audio_a2dp_hw_utils.cc",
- ],
- shared_libs: [
- "liblog",
- "libcutils",
- ],
- static_libs: ["libosi"],
-}
-
-cc_library_static {
- name: "libaudio-a2dp-hw-utils",
- defaults: ["audio_a2dp_hw_defaults"],
- srcs: [
- "src/audio_a2dp_hw_utils.cc",
- ],
- host_supported: true,
-}
-
-// Audio A2DP library unit tests for target and host
-cc_test {
- name: "net_test_audio_a2dp_hw",
- test_suites: ["device-tests"],
- defaults: ["audio_a2dp_hw_defaults"],
- srcs: [
- "test/audio_a2dp_hw_test.cc",
- ],
- shared_libs: [
- "liblog",
- ],
- static_libs: [
- "audio.a2dp.default",
- "libosi",
- ],
-}
diff --git a/audio_a2dp_hw/include/audio_a2dp_hw.h b/audio_a2dp_hw/include/audio_a2dp_hw.h
deleted file mode 100644
index 3f380a6..0000000
--- a/audio_a2dp_hw/include/audio_a2dp_hw.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2009-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/*****************************************************************************
- *
- * Filename: audio_a2dp_hw.h
- *
- * Description:
- *
- *****************************************************************************/
-
-#ifndef AUDIO_A2DP_HW_H
-#define AUDIO_A2DP_HW_H
-
-#include <stdint.h>
-
-#include <hardware/bt_av.h>
-
-/*****************************************************************************
- * Constants & Macros
- *****************************************************************************/
-
-#define A2DP_AUDIO_HARDWARE_INTERFACE "audio.a2dp"
-#define A2DP_CTRL_PATH "/data/misc/bluedroid/.a2dp_ctrl"
-#define A2DP_DATA_PATH "/data/misc/bluedroid/.a2dp_data"
-
-// AUDIO_STREAM_OUTPUT_BUFFER_SZ controls the size of the audio socket buffer.
-// If one assumes the write buffer is always full during normal BT playback,
-// then increasing this value increases our playback latency.
-//
-// FIXME: The BT HAL should consume data at a constant rate.
-// AudioFlinger assumes that the HAL draws data at a constant rate, which is
-// true for most audio devices; however, the BT engine reads data at a variable
-// rate (over the short term), which confuses both AudioFlinger as well as
-// applications which deliver data at a (generally) fixed rate.
-//
-// 20 * 512 is not sufficient to smooth the variability for some BT devices,
-// resulting in mixer sleep and throttling. We increase this to 28 * 512 to help
-// reduce the effect of variable data consumption.
-#define AUDIO_STREAM_OUTPUT_BUFFER_SZ (28 * 512)
-#define AUDIO_STREAM_CONTROL_OUTPUT_BUFFER_SZ 256
-
-// AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is divided
-// for AudioFlinger data delivery. The AudioFlinger mixer delivers data in
-// chunks of AUDIO_STREAM_OUTPUT_BUFFER_SZ / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS.
-// If the number of periods is 2, the socket buffer represents "double
-// buffering" of the AudioFlinger mixer buffer.
-//
-// In general, AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * 16 * 4 should be a divisor
-// of AUDIO_STREAM_OUTPUT_BUFFER_SZ.
-//
-// These values should be chosen such that
-//
-// AUDIO_STREAM_BUFFER_SIZE * 1000 / (AUDIO_STREAM_OUTPUT_BUFFER_PERIODS
-// * AUDIO_STREAM_DEFAULT_RATE * 4) > 20 (ms)
-//
-// to avoid introducing the FastMixer in AudioFlinger. Using the FastMixer
-// results in unnecessary latency and CPU overhead for Bluetooth.
-#define AUDIO_STREAM_OUTPUT_BUFFER_PERIODS 2
-
-#define AUDIO_SKT_DISCONNECTED (-1)
-
-typedef enum {
- A2DP_CTRL_CMD_NONE,
- A2DP_CTRL_CMD_CHECK_READY,
- A2DP_CTRL_CMD_START,
- A2DP_CTRL_CMD_STOP,
- A2DP_CTRL_CMD_SUSPEND,
- A2DP_CTRL_GET_INPUT_AUDIO_CONFIG,
- A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG,
- A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG,
- A2DP_CTRL_GET_PRESENTATION_POSITION,
-} tA2DP_CTRL_CMD;
-
-typedef enum {
- A2DP_CTRL_ACK_SUCCESS,
- A2DP_CTRL_ACK_FAILURE,
- A2DP_CTRL_ACK_INCALL_FAILURE, /* Failure when in Call*/
- A2DP_CTRL_ACK_UNSUPPORTED,
- A2DP_CTRL_ACK_PENDING,
- A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS,
-} tA2DP_CTRL_ACK;
-
-typedef uint32_t tA2DP_SAMPLE_RATE;
-typedef uint8_t tA2DP_CHANNEL_COUNT;
-typedef uint8_t tA2DP_BITS_PER_SAMPLE;
-
-/*****************************************************************************
- * Type definitions for callback functions
- *****************************************************************************/
-
-/*****************************************************************************
- * Type definitions and return values
- *****************************************************************************/
-
-/*****************************************************************************
- * Extern variables and functions
- *****************************************************************************/
-
-/*****************************************************************************
- * Functions
- *****************************************************************************/
-
-// Computes the Audio A2DP HAL output buffer size.
-// |codec_sample_rate| is the sample rate of the output stream.
-// |codec_bits_per_sample| is the number of bits per sample of the output
-// stream.
-// |codec_channel_mode| is the channel mode of the output stream.
-//
-// The buffer size is computed by using the following formula:
-//
-// AUDIO_STREAM_OUTPUT_BUFFER_SIZE =
-// (TIME_PERIOD_MS * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS *
-// SAMPLE_RATE_HZ * NUMBER_OF_CHANNELS * (BITS_PER_SAMPLE / 8)) / 1000
-//
-// AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is
-// divided for AudioFlinger data delivery. The AudioFlinger mixer delivers
-// data in chunks of
-// (AUDIO_STREAM_OUTPUT_BUFFER_SIZE / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS) .
-// If the number of periods is 2, the socket buffer represents "double
-// buffering" of the AudioFlinger mixer buffer.
-//
-// Furthermore, the AudioFlinger expects the buffer size to be a multiple
-// of 16 frames.
-//
-// NOTE: Currently, the computation uses the conservative 20ms time period.
-//
-// Returns the computed buffer size. If any of the input parameters is
-// invalid, the return value is the default |AUDIO_STREAM_OUTPUT_BUFFER_SZ|.
-size_t audio_a2dp_hw_stream_compute_buffer_size(
- btav_a2dp_codec_sample_rate_t codec_sample_rate,
- btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample,
- btav_a2dp_codec_channel_mode_t codec_channel_mode);
-
-// Returns whether the delay reporting property is set.
-bool delay_reporting_enabled();
-
-// Returns a string representation of |event|.
-const char* audio_a2dp_hw_dump_ctrl_event(tA2DP_CTRL_CMD event);
-
-#endif /* A2DP_AUDIO_HW_H */
diff --git a/audio_a2dp_hw/src/audio_a2dp_hw.cc b/audio_a2dp_hw/src/audio_a2dp_hw.cc
deleted file mode 100644
index cfa30fd..0000000
--- a/audio_a2dp_hw/src/audio_a2dp_hw.cc
+++ /dev/null
@@ -1,1960 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2009-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/*****************************************************************************
- *
- * Filename: audio_a2dp_hw.c
- *
- * Description: Implements hal for bluedroid a2dp audio device
- *
- *****************************************************************************/
-
-#define LOG_TAG "bt_a2dp_hw"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <log/log.h>
-#include <stdint.h>
-#include <sys/errno.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <mutex>
-
-#include <hardware/audio.h>
-#include <hardware/hardware.h>
-#include <system/audio.h>
-
-#include "osi/include/hash_map_utils.h"
-#include "osi/include/osi.h"
-#include "osi/include/socket_utils/sockets.h"
-
-#include "audio_a2dp_hw.h"
-
-/*****************************************************************************
- * Constants & Macros
- *****************************************************************************/
-
-#define CTRL_CHAN_RETRY_COUNT 3
-#define USEC_PER_SEC 1000000L
-#define SOCK_SEND_TIMEOUT_MS 2000 /* Timeout for sending */
-#define SOCK_RECV_TIMEOUT_MS 5000 /* Timeout for receiving */
-#define SEC_TO_MS 1000
-#define SEC_TO_NS 1000000000
-#define MS_TO_NS 1000000
-#define DELAY_TO_NS 100000
-
-#define MIN_DELAY_MS 100
-#define MAX_DELAY_MS 1000
-
-// set WRITE_POLL_MS to 0 for blocking sockets, nonzero for polled non-blocking
-// sockets
-#define WRITE_POLL_MS 20
-
-#define FNLOG() ALOGV("%s:%d %s: ", __FILE__, __LINE__, __func__)
-#define DEBUG(fmt, args...) \
- ALOGD("%s:%d %s: " fmt, __FILE__, __LINE__, __func__, ##args)
-#define INFO(fmt, args...) \
- ALOGI("%s:%d %s: " fmt, __FILE__, __LINE__, __func__, ##args)
-#define WARN(fmt, args...) \
- ALOGW("%s:%d %s: " fmt, __FILE__, __LINE__, __func__, ##args)
-#define ERROR(fmt, args...) \
- ALOGE("%s:%d %s: " fmt, __FILE__, __LINE__, __func__, ##args)
-
-#define ASSERTC(cond, msg, val) \
- if (!(cond)) { \
- ERROR("### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, \
- val); \
- }
-
-/*****************************************************************************
- * Local type definitions
- *****************************************************************************/
-
-typedef enum {
- AUDIO_A2DP_STATE_STARTING,
- AUDIO_A2DP_STATE_STARTED,
- AUDIO_A2DP_STATE_STOPPING,
- AUDIO_A2DP_STATE_STOPPED,
- /* need explicit set param call to resume (suspend=false) */
- AUDIO_A2DP_STATE_SUSPENDED,
- AUDIO_A2DP_STATE_STANDBY /* allows write to autoresume */
-} a2dp_state_t;
-
-struct a2dp_stream_in;
-struct a2dp_stream_out;
-
-struct a2dp_audio_device {
- // Important: device must be first as an audio_hw_device* may be cast to
- // a2dp_audio_device* when the type is implicitly known.
- struct audio_hw_device device;
- std::recursive_mutex* mutex; // See note below on mutex acquisition order.
- struct a2dp_stream_in* input;
- struct a2dp_stream_out* output;
-};
-
-struct a2dp_config {
- uint32_t rate;
- audio_channel_mask_t channel_mask;
- bool is_stereo_to_mono; // True if fetching Stereo and mixing into Mono
- int format;
-};
-
-/* move ctrl_fd outside output stream and keep open until HAL unloaded ? */
-
-struct a2dp_stream_common {
- std::recursive_mutex* mutex; // See note below on mutex acquisition order.
- int ctrl_fd;
- int audio_fd;
- size_t buffer_sz;
- struct a2dp_config cfg;
- a2dp_state_t state;
-};
-
-struct a2dp_stream_out {
- struct audio_stream_out stream;
- struct a2dp_stream_common common;
- uint64_t frames_presented; // frames written, never reset
- uint64_t frames_rendered; // frames written, reset on standby
-};
-
-struct a2dp_stream_in {
- struct audio_stream_in stream;
- struct a2dp_stream_common common;
-};
-
-/*
- * Mutex acquisition order:
- *
- * The a2dp_audio_device (adev) mutex must be acquired before
- * the a2dp_stream_common (out or in) mutex.
- *
- * This may differ from other audio HALs.
- */
-
-/*****************************************************************************
- * Static variables
- *****************************************************************************/
-
-static bool enable_delay_reporting = false;
-
-/*****************************************************************************
- * Static functions
- *****************************************************************************/
-
-static size_t out_get_buffer_size(const struct audio_stream* stream);
-static uint32_t out_get_latency(const struct audio_stream_out* stream);
-
-/*****************************************************************************
- * Externs
- *****************************************************************************/
-
-/*****************************************************************************
- * Functions
- *****************************************************************************/
-static void a2dp_open_ctrl_path(struct a2dp_stream_common* common);
-
-/*****************************************************************************
- * Miscellaneous helper functions
- *****************************************************************************/
-static void hash_map_utils_dump_string_keys_string_values(
- std::unordered_map<std::string, std::string>& map) {
- for (const auto& ptr : map) {
- INFO("key: '%s' value: '%s'\n", ptr.first.c_str(), ptr.second.c_str());
- }
-}
-
-/* logs timestamp with microsec precision
- pprev is optional in case a dedicated diff is required */
-static void ts_log(UNUSED_ATTR const char* tag, UNUSED_ATTR int val,
- struct timespec* pprev_opt) {
- struct timespec now;
- static struct timespec prev = {0, 0};
- unsigned long long now_us;
- unsigned long long diff_us;
-
- clock_gettime(CLOCK_MONOTONIC, &now);
-
- now_us = now.tv_sec * USEC_PER_SEC + now.tv_nsec / 1000;
-
- if (pprev_opt) {
- diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC +
- (now.tv_nsec - prev.tv_nsec) / 1000;
- *pprev_opt = now;
- DEBUG("[%s] ts %08lld, *diff %08lld, val %d", tag, now_us, diff_us, val);
- } else {
- diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC +
- (now.tv_nsec - prev.tv_nsec) / 1000;
- prev = now;
- DEBUG("[%s] ts %08lld, diff %08lld, val %d", tag, now_us, diff_us, val);
- }
-}
-
-static int calc_audiotime_usec(struct a2dp_config cfg, int bytes) {
- int chan_count = audio_channel_count_from_out_mask(cfg.channel_mask);
- int bytes_per_sample;
-
- switch (cfg.format) {
- case AUDIO_FORMAT_PCM_8_BIT:
- bytes_per_sample = 1;
- break;
- case AUDIO_FORMAT_PCM_16_BIT:
- bytes_per_sample = 2;
- break;
- case AUDIO_FORMAT_PCM_24_BIT_PACKED:
- bytes_per_sample = 3;
- break;
- case AUDIO_FORMAT_PCM_8_24_BIT:
- bytes_per_sample = 4;
- break;
- case AUDIO_FORMAT_PCM_32_BIT:
- bytes_per_sample = 4;
- break;
- default:
- ASSERTC(false, "unsupported sample format", cfg.format);
- bytes_per_sample = 2;
- break;
- }
-
- return (
- int)(((int64_t)bytes * (USEC_PER_SEC / (chan_count * bytes_per_sample))) /
- cfg.rate);
-}
-
-/*****************************************************************************
- *
- * bluedroid stack adaptation
- *
- ****************************************************************************/
-
-static int skt_connect(const char* path, size_t buffer_sz) {
- int ret;
- int skt_fd;
- int len;
-
- INFO("connect to %s (sz %zu)", path, buffer_sz);
-
- skt_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
-
- if (osi_socket_local_client_connect(
- skt_fd, path, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0) {
- ERROR("failed to connect (%s)", strerror(errno));
- close(skt_fd);
- return -1;
- }
-
- len = buffer_sz;
- ret =
- setsockopt(skt_fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, (int)sizeof(len));
- if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
-
- ret =
- setsockopt(skt_fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, (int)sizeof(len));
- if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
-
- /* Socket send/receive timeout value */
- struct timeval tv;
- tv.tv_sec = SOCK_SEND_TIMEOUT_MS / 1000;
- tv.tv_usec = (SOCK_SEND_TIMEOUT_MS % 1000) * 1000;
-
- ret = setsockopt(skt_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
- if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
-
- tv.tv_sec = SOCK_RECV_TIMEOUT_MS / 1000;
- tv.tv_usec = (SOCK_RECV_TIMEOUT_MS % 1000) * 1000;
-
- ret = setsockopt(skt_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
- if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
-
- INFO("connected to stack fd = %d", skt_fd);
-
- return skt_fd;
-}
-
-static int skt_read(int fd, void* p, size_t len) {
- ssize_t read;
-
- FNLOG();
-
- ts_log("skt_read recv", len, NULL);
-
- OSI_NO_INTR(read = recv(fd, p, len, MSG_NOSIGNAL));
- if (read == -1) ERROR("read failed with errno=%d\n", errno);
-
- return (int)read;
-}
-
-static int skt_write(int fd, const void* p, size_t len) {
- ssize_t sent;
- FNLOG();
-
- ts_log("skt_write", len, NULL);
-
- if (WRITE_POLL_MS == 0) {
- // do not poll, use blocking send
- OSI_NO_INTR(sent = send(fd, p, len, MSG_NOSIGNAL));
- if (sent == -1) ERROR("write failed with error(%s)", strerror(errno));
-
- return (int)sent;
- }
-
- // use non-blocking send, poll
- int ms_timeout = SOCK_SEND_TIMEOUT_MS;
- size_t count = 0;
- while (count < len) {
- OSI_NO_INTR(sent = send(fd, p, len - count, MSG_NOSIGNAL | MSG_DONTWAIT));
- if (sent == -1) {
- if (errno != EAGAIN && errno != EWOULDBLOCK) {
- ERROR("write failed with error(%s)", strerror(errno));
- return -1;
- }
- if (ms_timeout >= WRITE_POLL_MS) {
- usleep(WRITE_POLL_MS * 1000);
- ms_timeout -= WRITE_POLL_MS;
- continue;
- }
- WARN("write timeout exceeded, sent %zu bytes", count);
- return -1;
- }
- count += sent;
- p = (const uint8_t*)p + sent;
- }
- return (int)count;
-}
-
-static int skt_disconnect(int fd) {
- INFO("fd %d", fd);
-
- if (fd != AUDIO_SKT_DISCONNECTED) {
- shutdown(fd, SHUT_RDWR);
- close(fd);
- }
- return 0;
-}
-
-/*****************************************************************************
- *
- * AUDIO CONTROL PATH
- *
- ****************************************************************************/
-
-static int a2dp_ctrl_receive(struct a2dp_stream_common* common, void* buffer,
- size_t length) {
- ssize_t ret;
- int i;
-
- for (i = 0;; i++) {
- OSI_NO_INTR(ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL));
- if (ret > 0) {
- break;
- }
- if (ret == 0) {
- ERROR("receive control data failed: peer closed");
- break;
- }
- if (errno != EWOULDBLOCK && errno != EAGAIN) {
- ERROR("receive control data failed: error(%s)", strerror(errno));
- break;
- }
- if (i == (CTRL_CHAN_RETRY_COUNT - 1)) {
- ERROR("receive control data failed: max retry count");
- break;
- }
- INFO("receive control data failed (%s), retrying", strerror(errno));
- }
- if (ret <= 0) {
- skt_disconnect(common->ctrl_fd);
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- }
- return ret;
-}
-
-// Sends control info for stream |common|. The data to send is stored in
-// |buffer| and has size |length|.
-// On success, returns the number of octets sent, otherwise -1.
-static int a2dp_ctrl_send(struct a2dp_stream_common* common, const void* buffer,
- size_t length) {
- ssize_t sent;
- size_t remaining = length;
- int i;
-
- if (length == 0) return 0; // Nothing to do
-
- for (i = 0;; i++) {
- OSI_NO_INTR(sent = send(common->ctrl_fd, buffer, remaining, MSG_NOSIGNAL));
- if (sent == static_cast<ssize_t>(remaining)) {
- remaining = 0;
- break;
- }
- if (sent > 0) {
- buffer = (static_cast<const char*>(buffer) + sent);
- remaining -= sent;
- continue;
- }
- if (sent < 0) {
- if (errno != EWOULDBLOCK && errno != EAGAIN) {
- ERROR("send control data failed: error(%s)", strerror(errno));
- break;
- }
- INFO("send control data failed (%s), retrying", strerror(errno));
- }
- if (i >= (CTRL_CHAN_RETRY_COUNT - 1)) {
- ERROR("send control data failed: max retry count");
- break;
- }
- }
- if (remaining > 0) {
- skt_disconnect(common->ctrl_fd);
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- return -1;
- }
- return length;
-}
-
-static int a2dp_command(struct a2dp_stream_common* common, tA2DP_CTRL_CMD cmd) {
- char ack;
-
- DEBUG("A2DP COMMAND %s", audio_a2dp_hw_dump_ctrl_event(cmd));
-
- if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) {
- INFO("starting up or recovering from previous error: command=%s",
- audio_a2dp_hw_dump_ctrl_event(cmd));
- a2dp_open_ctrl_path(common);
- if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) {
- ERROR("failure to open ctrl path: command=%s",
- audio_a2dp_hw_dump_ctrl_event(cmd));
- return -1;
- }
- }
-
- /* send command */
- ssize_t sent;
- OSI_NO_INTR(sent = send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL));
- if (sent == -1) {
- ERROR("cmd failed (%s): command=%s", strerror(errno),
- audio_a2dp_hw_dump_ctrl_event(cmd));
- skt_disconnect(common->ctrl_fd);
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- return -1;
- }
-
- /* wait for ack byte */
- if (a2dp_ctrl_receive(common, &ack, 1) < 0) {
- ERROR("A2DP COMMAND %s: no ACK", audio_a2dp_hw_dump_ctrl_event(cmd));
- return -1;
- }
-
- DEBUG("A2DP COMMAND %s DONE STATUS %d", audio_a2dp_hw_dump_ctrl_event(cmd),
- ack);
-
- if (ack == A2DP_CTRL_ACK_INCALL_FAILURE) {
- ERROR("A2DP COMMAND %s error %d", audio_a2dp_hw_dump_ctrl_event(cmd), ack);
- return ack;
- }
- if (ack != A2DP_CTRL_ACK_SUCCESS) {
- ERROR("A2DP COMMAND %s error %d", audio_a2dp_hw_dump_ctrl_event(cmd), ack);
- return -1;
- }
-
- return 0;
-}
-
-static int check_a2dp_ready(struct a2dp_stream_common* common) {
- if (a2dp_command(common, A2DP_CTRL_CMD_CHECK_READY) < 0) {
- ERROR("check a2dp ready failed");
- return -1;
- }
- return 0;
-}
-
-static int a2dp_read_input_audio_config(struct a2dp_stream_common* common) {
- tA2DP_SAMPLE_RATE sample_rate;
- tA2DP_CHANNEL_COUNT channel_count;
-
- if (a2dp_command(common, A2DP_CTRL_GET_INPUT_AUDIO_CONFIG) < 0) {
- ERROR("get a2dp input audio config failed");
- return -1;
- }
-
- if (a2dp_ctrl_receive(common, &sample_rate, sizeof(tA2DP_SAMPLE_RATE)) < 0)
- return -1;
- if (a2dp_ctrl_receive(common, &channel_count, sizeof(tA2DP_CHANNEL_COUNT)) <
- 0) {
- return -1;
- }
-
- switch (sample_rate) {
- case 44100:
- case 48000:
- common->cfg.rate = sample_rate;
- break;
- default:
- ERROR("Invalid sample rate: %" PRIu32, sample_rate);
- return -1;
- }
-
- switch (channel_count) {
- case 1:
- common->cfg.channel_mask = AUDIO_CHANNEL_IN_MONO;
- break;
- case 2:
- common->cfg.channel_mask = AUDIO_CHANNEL_IN_STEREO;
- break;
- default:
- ERROR("Invalid channel count: %" PRIu32, channel_count);
- return -1;
- }
-
- // TODO: For now input audio format is always hard-coded as PCM 16-bit
- common->cfg.format = AUDIO_FORMAT_PCM_16_BIT;
-
- INFO("got input audio config %d %d", common->cfg.format, common->cfg.rate);
-
- return 0;
-}
-
-static int a2dp_read_output_audio_config(
- struct a2dp_stream_common* common, btav_a2dp_codec_config_t* codec_config,
- btav_a2dp_codec_config_t* codec_capability, bool update_stream_config) {
- struct a2dp_config stream_config;
-
- if (a2dp_command(common, A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG) < 0) {
- ERROR("get a2dp output audio config failed");
- return -1;
- }
-
- // Receive the current codec config
- if (a2dp_ctrl_receive(common, &codec_config->sample_rate,
- sizeof(btav_a2dp_codec_sample_rate_t)) < 0) {
- return -1;
- }
- if (a2dp_ctrl_receive(common, &codec_config->bits_per_sample,
- sizeof(btav_a2dp_codec_bits_per_sample_t)) < 0) {
- return -1;
- }
- if (a2dp_ctrl_receive(common, &codec_config->channel_mode,
- sizeof(btav_a2dp_codec_channel_mode_t)) < 0) {
- return -1;
- }
-
- // Receive the current codec capability
- if (a2dp_ctrl_receive(common, &codec_capability->sample_rate,
- sizeof(btav_a2dp_codec_sample_rate_t)) < 0) {
- return -1;
- }
- if (a2dp_ctrl_receive(common, &codec_capability->bits_per_sample,
- sizeof(btav_a2dp_codec_bits_per_sample_t)) < 0) {
- return -1;
- }
- if (a2dp_ctrl_receive(common, &codec_capability->channel_mode,
- sizeof(btav_a2dp_codec_channel_mode_t)) < 0) {
- return -1;
- }
-
- // Check the codec config sample rate
- switch (codec_config->sample_rate) {
- case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
- stream_config.rate = 44100;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
- stream_config.rate = 48000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
- stream_config.rate = 88200;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
- stream_config.rate = 96000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
- stream_config.rate = 176400;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
- stream_config.rate = 192000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE:
- default:
- ERROR("Invalid sample rate: 0x%x", codec_config->sample_rate);
- return -1;
- }
-
- // Check the codec config bits per sample
- switch (codec_config->bits_per_sample) {
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
- stream_config.format = AUDIO_FORMAT_PCM_16_BIT;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
- stream_config.format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
- stream_config.format = AUDIO_FORMAT_PCM_32_BIT;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
- default:
- ERROR("Invalid bits per sample: 0x%x", codec_config->bits_per_sample);
- return -1;
- }
-
- // Check the codec config channel mode
- switch (codec_config->channel_mode) {
- case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
- stream_config.channel_mask = AUDIO_CHANNEL_OUT_MONO;
- stream_config.is_stereo_to_mono = true;
- break;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
- stream_config.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
- stream_config.is_stereo_to_mono = false;
- break;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
- default:
- ERROR("Invalid channel mode: 0x%x", codec_config->channel_mode);
- return -1;
- }
- if (stream_config.is_stereo_to_mono) {
- stream_config.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
- }
-
- // Update the output stream configuration
- if (update_stream_config) {
- common->cfg.rate = stream_config.rate;
- common->cfg.channel_mask = stream_config.channel_mask;
- common->cfg.is_stereo_to_mono = stream_config.is_stereo_to_mono;
- common->cfg.format = stream_config.format;
- common->buffer_sz = audio_a2dp_hw_stream_compute_buffer_size(
- codec_config->sample_rate, codec_config->bits_per_sample,
- codec_config->channel_mode);
- if (common->cfg.is_stereo_to_mono) {
- // We need to fetch twice as much data from the Audio framework
- common->buffer_sz *= 2;
- }
- }
-
- INFO(
- "got output codec config (update_stream_config=%s): "
- "sample_rate=0x%x bits_per_sample=0x%x channel_mode=0x%x",
- update_stream_config ? "true" : "false", codec_config->sample_rate,
- codec_config->bits_per_sample, codec_config->channel_mode);
-
- INFO(
- "got output codec capability: sample_rate=0x%x bits_per_sample=0x%x "
- "channel_mode=0x%x",
- codec_capability->sample_rate, codec_capability->bits_per_sample,
- codec_capability->channel_mode);
-
- return 0;
-}
-
-static int a2dp_write_output_audio_config(struct a2dp_stream_common* common) {
- btav_a2dp_codec_config_t codec_config;
-
- if (a2dp_command(common, A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG) < 0) {
- ERROR("set a2dp output audio config failed");
- return -1;
- }
-
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
-
- switch (common->cfg.rate) {
- case 44100:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
- break;
- case 48000:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_48000;
- break;
- case 88200:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_88200;
- break;
- case 96000:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_96000;
- break;
- case 176400:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_176400;
- break;
- case 192000:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_192000;
- break;
- default:
- ERROR("Invalid sample rate: %" PRIu32, common->cfg.rate);
- return -1;
- }
-
- switch (common->cfg.format) {
- case AUDIO_FORMAT_PCM_16_BIT:
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;
- break;
- case AUDIO_FORMAT_PCM_24_BIT_PACKED:
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24;
- break;
- case AUDIO_FORMAT_PCM_32_BIT:
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32;
- break;
- case AUDIO_FORMAT_PCM_8_24_BIT:
- // All 24-bit audio is expected in AUDIO_FORMAT_PCM_24_BIT_PACKED format
- FALLTHROUGH_INTENDED; /* FALLTHROUGH */
- default:
- ERROR("Invalid audio format: 0x%x", common->cfg.format);
- return -1;
- }
-
- switch (common->cfg.channel_mask) {
- case AUDIO_CHANNEL_OUT_MONO:
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
- break;
- case AUDIO_CHANNEL_OUT_STEREO:
- if (common->cfg.is_stereo_to_mono) {
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
- } else {
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
- }
- break;
- default:
- ERROR("Invalid channel mask: 0x%x", common->cfg.channel_mask);
- return -1;
- }
-
- // Send the current codec config that has been selected by us
- if (a2dp_ctrl_send(common, &codec_config.sample_rate,
- sizeof(btav_a2dp_codec_sample_rate_t)) < 0)
- return -1;
- if (a2dp_ctrl_send(common, &codec_config.bits_per_sample,
- sizeof(btav_a2dp_codec_bits_per_sample_t)) < 0) {
- return -1;
- }
- if (a2dp_ctrl_send(common, &codec_config.channel_mode,
- sizeof(btav_a2dp_codec_channel_mode_t)) < 0) {
- return -1;
- }
-
- INFO(
- "sent output codec config: sample_rate=0x%x bits_per_sample=0x%x "
- "channel_mode=0x%x",
- codec_config.sample_rate, codec_config.bits_per_sample,
- codec_config.channel_mode);
-
- return 0;
-}
-
-static int a2dp_get_presentation_position_cmd(struct a2dp_stream_common* common,
- uint64_t* bytes, uint16_t* delay,
- struct timespec* timestamp) {
- if ((common->ctrl_fd == AUDIO_SKT_DISCONNECTED) ||
- (common->state != AUDIO_A2DP_STATE_STARTED)) { // Audio is not streaming
- return -1;
- }
-
- if (a2dp_command(common, A2DP_CTRL_GET_PRESENTATION_POSITION) < 0) {
- return -1;
- }
-
- if (a2dp_ctrl_receive(common, bytes, sizeof(*bytes)) < 0) {
- return -1;
- }
-
- if (a2dp_ctrl_receive(common, delay, sizeof(*delay)) < 0) {
- return -1;
- }
-
- uint32_t seconds;
- if (a2dp_ctrl_receive(common, &seconds, sizeof(seconds)) < 0) {
- return -1;
- }
-
- uint32_t nsec;
- if (a2dp_ctrl_receive(common, &nsec, sizeof(nsec)) < 0) {
- return -1;
- }
-
- timestamp->tv_sec = seconds;
- timestamp->tv_nsec = nsec;
- return 0;
-}
-
-static void a2dp_open_ctrl_path(struct a2dp_stream_common* common) {
- int i;
-
- if (common->ctrl_fd != AUDIO_SKT_DISCONNECTED) return; // already connected
-
- /* retry logic to catch any timing variations on control channel */
- for (i = 0; i < CTRL_CHAN_RETRY_COUNT; i++) {
- /* connect control channel if not already connected */
- if ((common->ctrl_fd = skt_connect(
- A2DP_CTRL_PATH, AUDIO_STREAM_CONTROL_OUTPUT_BUFFER_SZ)) >= 0) {
- /* success, now check if stack is ready */
- if (check_a2dp_ready(common) == 0) break;
-
- ERROR("error : a2dp not ready, wait 250 ms and retry");
- usleep(250000);
- skt_disconnect(common->ctrl_fd);
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- }
-
- /* ctrl channel not ready, wait a bit */
- usleep(250000);
- }
-}
-
-/*****************************************************************************
- *
- * AUDIO DATA PATH
- *
- ****************************************************************************/
-
-static void a2dp_stream_common_init(struct a2dp_stream_common* common) {
- FNLOG();
-
- common->mutex = new std::recursive_mutex;
-
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- common->audio_fd = AUDIO_SKT_DISCONNECTED;
- common->state = AUDIO_A2DP_STATE_STOPPED;
-
- /* manages max capacity of socket pipe */
- common->buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ;
-}
-
-static void a2dp_stream_common_destroy(struct a2dp_stream_common* common) {
- FNLOG();
-
- delete common->mutex;
- common->mutex = NULL;
-}
-
-static int start_audio_datapath(struct a2dp_stream_common* common) {
- INFO("state %d", common->state);
-
- int oldstate = common->state;
- common->state = AUDIO_A2DP_STATE_STARTING;
-
- int a2dp_status = a2dp_command(common, A2DP_CTRL_CMD_START);
- if (a2dp_status < 0) {
- ERROR("Audiopath start failed (status %d)", a2dp_status);
- goto error;
- } else if (a2dp_status == A2DP_CTRL_ACK_INCALL_FAILURE) {
- ERROR("Audiopath start failed - in call, move to suspended");
- goto error;
- }
-
- /* connect socket if not yet connected */
- if (common->audio_fd == AUDIO_SKT_DISCONNECTED) {
- common->audio_fd = skt_connect(A2DP_DATA_PATH, common->buffer_sz);
- if (common->audio_fd < 0) {
- ERROR("Audiopath start failed - error opening data socket");
- goto error;
- }
- }
- common->state = (a2dp_state_t)AUDIO_A2DP_STATE_STARTED;
-
- /* check to see if delay reporting is enabled */
- enable_delay_reporting = delay_reporting_enabled();
-
- return 0;
-
-error:
- common->state = (a2dp_state_t)oldstate;
- return -1;
-}
-
-static int stop_audio_datapath(struct a2dp_stream_common* common) {
- int oldstate = common->state;
-
- INFO("state %d", common->state);
-
- /* prevent any stray output writes from autostarting the stream
- while stopping audiopath */
- common->state = AUDIO_A2DP_STATE_STOPPING;
-
- if (a2dp_command(common, A2DP_CTRL_CMD_STOP) < 0) {
- ERROR("audiopath stop failed");
- common->state = (a2dp_state_t)oldstate;
- return -1;
- }
-
- common->state = (a2dp_state_t)AUDIO_A2DP_STATE_STOPPED;
-
- /* disconnect audio path */
- skt_disconnect(common->audio_fd);
- common->audio_fd = AUDIO_SKT_DISCONNECTED;
-
- return 0;
-}
-
-static int suspend_audio_datapath(struct a2dp_stream_common* common,
- bool standby) {
- INFO("state %d", common->state);
-
- if (common->state == AUDIO_A2DP_STATE_STOPPING) return -1;
-
- if (a2dp_command(common, A2DP_CTRL_CMD_SUSPEND) < 0) return -1;
-
- if (standby)
- common->state = AUDIO_A2DP_STATE_STANDBY;
- else
- common->state = AUDIO_A2DP_STATE_SUSPENDED;
-
- /* disconnect audio path */
- skt_disconnect(common->audio_fd);
-
- common->audio_fd = AUDIO_SKT_DISCONNECTED;
-
- return 0;
-}
-
-/*****************************************************************************
- *
- * audio output callbacks
- *
- ****************************************************************************/
-
-static ssize_t out_write(struct audio_stream_out* stream, const void* buffer,
- size_t bytes) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
- int sent = -1;
- size_t write_bytes = bytes;
-
- DEBUG("write %zu bytes (fd %d)", bytes, out->common.audio_fd);
-
- std::unique_lock<std::recursive_mutex> lock(*out->common.mutex);
- if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED ||
- out->common.state == AUDIO_A2DP_STATE_STOPPING) {
- DEBUG("stream suspended or closing");
- goto finish;
- }
-
- /* only allow autostarting if we are in stopped or standby */
- if ((out->common.state == AUDIO_A2DP_STATE_STOPPED) ||
- (out->common.state == AUDIO_A2DP_STATE_STANDBY)) {
- if (start_audio_datapath(&out->common) < 0) {
- goto finish;
- }
- } else if (out->common.state != AUDIO_A2DP_STATE_STARTED) {
- ERROR("stream not in stopped or standby");
- goto finish;
- }
-
- // Mix the stereo into mono if necessary
- if (out->common.cfg.is_stereo_to_mono) {
- const size_t frames = bytes / audio_stream_out_frame_size(stream);
- int16_t* src = (int16_t*)buffer;
- int16_t* dst = (int16_t*)buffer;
- for (size_t i = 0; i < frames; i++, dst++, src += 2) {
- *dst = (int16_t)(((int32_t)src[0] + (int32_t)src[1]) >> 1);
- }
- write_bytes /= 2;
- DEBUG("stereo-to-mono mixing: write %zu bytes (fd %d)", write_bytes,
- out->common.audio_fd);
- }
-
- lock.unlock();
- sent = skt_write(out->common.audio_fd, buffer, write_bytes);
- lock.lock();
-
- if (sent == -1) {
- skt_disconnect(out->common.audio_fd);
- out->common.audio_fd = AUDIO_SKT_DISCONNECTED;
- if ((out->common.state != AUDIO_A2DP_STATE_SUSPENDED) &&
- (out->common.state != AUDIO_A2DP_STATE_STOPPING)) {
- out->common.state = AUDIO_A2DP_STATE_STOPPED;
- } else {
- ERROR("write failed : stream suspended, avoid resetting state");
- }
- goto finish;
- }
-
-finish:;
- const size_t frames = bytes / audio_stream_out_frame_size(stream);
- out->frames_rendered += frames;
- out->frames_presented += frames;
- lock.unlock();
-
- // If send didn't work out, sleep to emulate write delay.
- if (sent == -1) {
- const int us_delay = calc_audiotime_usec(out->common.cfg, bytes);
- DEBUG("emulate a2dp write delay (%d us)", us_delay);
- usleep(us_delay);
- }
- return bytes;
-}
-
-static uint32_t out_get_sample_rate(const struct audio_stream* stream) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- DEBUG("rate %" PRIu32, out->common.cfg.rate);
-
- return out->common.cfg.rate;
-}
-
-static int out_set_sample_rate(struct audio_stream* stream, uint32_t rate) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- DEBUG("out_set_sample_rate : %" PRIu32, rate);
-
- out->common.cfg.rate = rate;
-
- return 0;
-}
-
-static size_t out_get_buffer_size(const struct audio_stream* stream) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
- // period_size is the AudioFlinger mixer buffer size.
- const size_t period_size =
- out->common.buffer_sz / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS;
-
- DEBUG("socket buffer size: %zu period size: %zu", out->common.buffer_sz,
- period_size);
-
- return period_size;
-}
-
-size_t audio_a2dp_hw_stream_compute_buffer_size(
- btav_a2dp_codec_sample_rate_t codec_sample_rate,
- btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample,
- btav_a2dp_codec_channel_mode_t codec_channel_mode) {
- size_t buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ; // Default value
- const uint64_t time_period_ms = 20; // Conservative 20ms
- uint32_t sample_rate;
- uint32_t bits_per_sample;
- uint32_t number_of_channels;
-
- // Check the codec config sample rate
- switch (codec_sample_rate) {
- case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
- sample_rate = 44100;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
- sample_rate = 48000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
- sample_rate = 88200;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
- sample_rate = 96000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
- sample_rate = 176400;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
- sample_rate = 192000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE:
- default:
- ERROR("Invalid sample rate: 0x%x", codec_sample_rate);
- return buffer_sz;
- }
-
- // Check the codec config bits per sample
- switch (codec_bits_per_sample) {
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
- bits_per_sample = 16;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
- bits_per_sample = 24;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
- bits_per_sample = 32;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
- default:
- ERROR("Invalid bits per sample: 0x%x", codec_bits_per_sample);
- return buffer_sz;
- }
-
- // Check the codec config channel mode
- switch (codec_channel_mode) {
- case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
- number_of_channels = 1;
- break;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
- number_of_channels = 2;
- break;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
- default:
- ERROR("Invalid channel mode: 0x%x", codec_channel_mode);
- return buffer_sz;
- }
-
- //
- // The buffer size is computed by using the following formula:
- //
- // AUDIO_STREAM_OUTPUT_BUFFER_SIZE =
- // (TIME_PERIOD_MS * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS *
- // SAMPLE_RATE_HZ * NUMBER_OF_CHANNELS * (BITS_PER_SAMPLE / 8)) / 1000
- //
- // AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is
- // divided for AudioFlinger data delivery. The AudioFlinger mixer delivers
- // data in chunks of
- // (AUDIO_STREAM_OUTPUT_BUFFER_SIZE / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS) .
- // If the number of periods is 2, the socket buffer represents "double
- // buffering" of the AudioFlinger mixer buffer.
- //
- // Furthermore, the AudioFlinger expects the buffer size to be a multiple
- // of 16 frames.
- const size_t divisor = (AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * 16 *
- number_of_channels * bits_per_sample) /
- 8;
-
- buffer_sz = (time_period_ms * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS *
- sample_rate * number_of_channels * (bits_per_sample / 8)) /
- 1000;
-
- // Adjust the buffer size so it can be divided by the divisor
- const size_t remainder = buffer_sz % divisor;
- if (remainder != 0) {
- buffer_sz += divisor - remainder;
- }
-
- return buffer_sz;
-}
-
-static audio_channel_mask_t out_get_channels(
- const struct audio_stream* stream) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- DEBUG("channels 0x%" PRIx32, out->common.cfg.channel_mask);
-
- return (audio_channel_mask_t)out->common.cfg.channel_mask;
-}
-
-static audio_format_t out_get_format(const struct audio_stream* stream) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
- DEBUG("format 0x%x", out->common.cfg.format);
- return (audio_format_t)out->common.cfg.format;
-}
-
-static int out_set_format(UNUSED_ATTR struct audio_stream* stream,
- UNUSED_ATTR audio_format_t format) {
- DEBUG("setting format not yet supported (0x%x)", format);
- return -ENOSYS;
-}
-
-static int out_standby(struct audio_stream* stream) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
- int retVal = 0;
-
- FNLOG();
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
- // Do nothing in SUSPENDED state.
- if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED)
- retVal = suspend_audio_datapath(&out->common, true);
- out->frames_rendered = 0; // rendered is reset, presented is not
-
- return retVal;
-}
-
-static int out_dump(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR int fd) {
- FNLOG();
- return 0;
-}
-
-static int out_set_parameters(struct audio_stream* stream,
- const char* kvpairs) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- INFO("state %d kvpairs %s", out->common.state, kvpairs);
-
- std::unordered_map<std::string, std::string> params =
- hash_map_utils_new_from_string_params(kvpairs);
- int status = 0;
-
- if (params.empty()) return status;
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
-
- /* dump params */
- hash_map_utils_dump_string_keys_string_values(params);
-
- if (params["closing"].compare("true") == 0) {
- DEBUG("stream closing, disallow any writes");
- out->common.state = AUDIO_A2DP_STATE_STOPPING;
- }
-
- if (params["A2dpSuspended"].compare("true") == 0) {
- if (out->common.state == AUDIO_A2DP_STATE_STARTED)
- status = suspend_audio_datapath(&out->common, false);
- } else {
- /* Do not start the streaming automatically. If the phone was streaming
- * prior to being suspended, the next out_write shall trigger the
- * AVDTP start procedure */
- if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED)
- out->common.state = AUDIO_A2DP_STATE_STANDBY;
- /* Irrespective of the state, return 0 */
- }
-
- return status;
-}
-
-static char* out_get_parameters(const struct audio_stream* stream,
- const char* keys) {
- FNLOG();
-
- btav_a2dp_codec_config_t codec_config;
- btav_a2dp_codec_config_t codec_capability;
-
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- std::unordered_map<std::string, std::string> params =
- hash_map_utils_new_from_string_params(keys);
- std::unordered_map<std::string, std::string> return_params;
-
- if (params.empty()) return strdup("");
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
-
- if (a2dp_read_output_audio_config(&out->common, &codec_config,
- &codec_capability,
- false /* update_stream_config */) < 0) {
- ERROR("a2dp_read_output_audio_config failed");
- goto done;
- }
-
- // Add the format
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_FORMATS) != params.end()) {
- std::string param;
- if (codec_capability.bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16) {
- if (!param.empty()) param += "|";
- param += "AUDIO_FORMAT_PCM_16_BIT";
- }
- if (codec_capability.bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24) {
- if (!param.empty()) param += "|";
- param += "AUDIO_FORMAT_PCM_24_BIT_PACKED";
- }
- if (codec_capability.bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32) {
- if (!param.empty()) param += "|";
- param += "AUDIO_FORMAT_PCM_32_BIT";
- }
- if (param.empty()) {
- ERROR("Invalid codec capability bits_per_sample=0x%x",
- codec_capability.bits_per_sample);
- goto done;
- } else {
- return_params[AUDIO_PARAMETER_STREAM_SUP_FORMATS] = param;
- }
- }
-
- // Add the sample rate
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES) != params.end()) {
- std::string param;
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_44100) {
- if (!param.empty()) param += "|";
- param += "44100";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_48000) {
- if (!param.empty()) param += "|";
- param += "48000";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_88200) {
- if (!param.empty()) param += "|";
- param += "88200";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_96000) {
- if (!param.empty()) param += "|";
- param += "96000";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_176400) {
- if (!param.empty()) param += "|";
- param += "176400";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_192000) {
- if (!param.empty()) param += "|";
- param += "192000";
- }
- if (param.empty()) {
- ERROR("Invalid codec capability sample_rate=0x%x",
- codec_capability.sample_rate);
- goto done;
- } else {
- return_params[AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES] = param;
- }
- }
-
- // Add the channel mask
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_CHANNELS) != params.end()) {
- std::string param;
- if (codec_capability.channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_MONO) {
- if (!param.empty()) param += "|";
- param += "AUDIO_CHANNEL_OUT_MONO";
- }
- if (codec_capability.channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO) {
- if (!param.empty()) param += "|";
- param += "AUDIO_CHANNEL_OUT_STEREO";
- }
- if (param.empty()) {
- ERROR("Invalid codec capability channel_mode=0x%x",
- codec_capability.channel_mode);
- goto done;
- } else {
- return_params[AUDIO_PARAMETER_STREAM_SUP_CHANNELS] = param;
- }
- }
-
-done:
- std::string result;
- for (const auto& ptr : return_params) {
- result += ptr.first + "=" + ptr.second + ";";
- }
-
- INFO("get parameters result = %s", result.c_str());
-
- return strdup(result.c_str());
-}
-
-static uint32_t out_get_latency(const struct audio_stream_out* stream) {
- int latency_us;
-
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- FNLOG();
-
- latency_us =
- ((out->common.buffer_sz * 1000) /
- audio_stream_out_frame_size(&out->stream) / out->common.cfg.rate) *
- 1000;
-
- return (latency_us / 1000) + 200;
-}
-
-static int out_set_volume(UNUSED_ATTR struct audio_stream_out* stream,
- UNUSED_ATTR float left, UNUSED_ATTR float right) {
- FNLOG();
-
- /* volume controlled in audioflinger mixer (digital) */
-
- return -ENOSYS;
-}
-
-static int out_get_presentation_position(const struct audio_stream_out* stream,
- uint64_t* frames,
- struct timespec* timestamp) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- FNLOG();
- if (stream == NULL || frames == NULL || timestamp == NULL) return -EINVAL;
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
-
- // bytes is the total number of bytes sent by the Bluetooth stack to a
- // remote headset
- uint64_t bytes = 0;
-
- // delay_report is the audio delay from the remote headset receiving data to
- // the headset playing sound in units of 1/10ms
- uint16_t delay_report = 0;
-
- // If for some reason getting a delay fails or delay reports are disabled,
- // default to old delay
- if (enable_delay_reporting &&
- a2dp_get_presentation_position_cmd(&out->common, &bytes, &delay_report,
- timestamp) == 0) {
- uint64_t delay_ns = delay_report * DELAY_TO_NS;
- if (delay_ns > MIN_DELAY_MS * MS_TO_NS &&
- delay_ns < MAX_DELAY_MS * MS_TO_NS) {
- *frames = bytes / audio_stream_out_frame_size(stream);
-
- timestamp->tv_nsec += delay_ns;
- if (timestamp->tv_nsec > 1 * SEC_TO_NS) {
- timestamp->tv_sec++;
- timestamp->tv_nsec -= SEC_TO_NS;
- }
- return 0;
- }
- }
-
- uint64_t latency_frames =
- (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
- if (out->frames_presented >= latency_frames) {
- clock_gettime(CLOCK_MONOTONIC, timestamp);
- *frames = out->frames_presented - latency_frames;
- return 0;
- }
-
- return -EWOULDBLOCK;
-}
-
-static int out_get_render_position(const struct audio_stream_out* stream,
- uint32_t* dsp_frames) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- FNLOG();
- if (stream == NULL || dsp_frames == NULL) return -EINVAL;
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
- uint64_t latency_frames =
- (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
- if (out->frames_rendered >= latency_frames) {
- *dsp_frames = (uint32_t)(out->frames_rendered - latency_frames);
- } else {
- *dsp_frames = 0;
- }
- return 0;
-}
-
-static int out_add_audio_effect(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR effect_handle_t effect) {
- FNLOG();
- return 0;
-}
-
-static int out_remove_audio_effect(
- UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR effect_handle_t effect) {
- FNLOG();
- return 0;
-}
-
-/*
- * AUDIO INPUT STREAM
- */
-
-static uint32_t in_get_sample_rate(const struct audio_stream* stream) {
- struct a2dp_stream_in* in = (struct a2dp_stream_in*)stream;
-
- FNLOG();
- return in->common.cfg.rate;
-}
-
-static int in_set_sample_rate(struct audio_stream* stream, uint32_t rate) {
- struct a2dp_stream_in* in = (struct a2dp_stream_in*)stream;
-
- FNLOG();
-
- if (in->common.cfg.rate > 0 && in->common.cfg.rate == rate)
- return 0;
- else
- return -1;
-}
-
-static size_t in_get_buffer_size(
- UNUSED_ATTR const struct audio_stream* stream) {
- FNLOG();
- return 320;
-}
-
-static audio_channel_mask_t in_get_channels(const struct audio_stream* stream) {
- struct a2dp_stream_in* in = (struct a2dp_stream_in*)stream;
-
- FNLOG();
- return (audio_channel_mask_t)in->common.cfg.channel_mask;
-}
-
-static audio_format_t in_get_format(
- UNUSED_ATTR const struct audio_stream* stream) {
- FNLOG();
- return AUDIO_FORMAT_PCM_16_BIT;
-}
-
-static int in_set_format(UNUSED_ATTR struct audio_stream* stream,
- UNUSED_ATTR audio_format_t format) {
- FNLOG();
- if (format == AUDIO_FORMAT_PCM_16_BIT)
- return 0;
- else
- return -1;
-}
-
-static int in_standby(UNUSED_ATTR struct audio_stream* stream) {
- FNLOG();
- return 0;
-}
-
-static int in_dump(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR int fd) {
- FNLOG();
- return 0;
-}
-
-static int in_set_parameters(UNUSED_ATTR struct audio_stream* stream,
- UNUSED_ATTR const char* kvpairs) {
- FNLOG();
- return 0;
-}
-
-static char* in_get_parameters(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR const char* keys) {
- FNLOG();
- return strdup("");
-}
-
-static int in_set_gain(UNUSED_ATTR struct audio_stream_in* stream,
- UNUSED_ATTR float gain) {
- FNLOG();
- return 0;
-}
-
-static ssize_t in_read(struct audio_stream_in* stream, void* buffer,
- size_t bytes) {
- struct a2dp_stream_in* in = (struct a2dp_stream_in*)stream;
- int read;
- int us_delay;
-
- DEBUG("read %zu bytes, state: %d", bytes, in->common.state);
-
- std::unique_lock<std::recursive_mutex> lock(*in->common.mutex);
- if (in->common.state == AUDIO_A2DP_STATE_SUSPENDED ||
- in->common.state == AUDIO_A2DP_STATE_STOPPING) {
- DEBUG("stream suspended");
- goto error;
- }
-
- /* only allow autostarting if we are in stopped or standby */
- if ((in->common.state == AUDIO_A2DP_STATE_STOPPED) ||
- (in->common.state == AUDIO_A2DP_STATE_STANDBY)) {
- if (start_audio_datapath(&in->common) < 0) {
- goto error;
- }
- } else if (in->common.state != AUDIO_A2DP_STATE_STARTED) {
- ERROR("stream not in stopped or standby");
- goto error;
- }
-
- lock.unlock();
- read = skt_read(in->common.audio_fd, buffer, bytes);
- lock.lock();
- if (read == -1) {
- skt_disconnect(in->common.audio_fd);
- in->common.audio_fd = AUDIO_SKT_DISCONNECTED;
- if ((in->common.state != AUDIO_A2DP_STATE_SUSPENDED) &&
- (in->common.state != AUDIO_A2DP_STATE_STOPPING)) {
- in->common.state = AUDIO_A2DP_STATE_STOPPED;
- } else {
- ERROR("read failed : stream suspended, avoid resetting state");
- }
- goto error;
- } else if (read == 0) {
- DEBUG("read time out - return zeros");
- memset(buffer, 0, bytes);
- read = bytes;
- }
- lock.unlock();
-
- DEBUG("read %d bytes out of %zu bytes", read, bytes);
- return read;
-
-error:
- memset(buffer, 0, bytes);
- us_delay = calc_audiotime_usec(in->common.cfg, bytes);
- DEBUG("emulate a2dp read delay (%d us)", us_delay);
-
- usleep(us_delay);
- return bytes;
-}
-
-static uint32_t in_get_input_frames_lost(
- UNUSED_ATTR struct audio_stream_in* stream) {
- FNLOG();
- return 0;
-}
-
-static int in_add_audio_effect(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR effect_handle_t effect) {
- FNLOG();
- return 0;
-}
-
-static int in_remove_audio_effect(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR effect_handle_t effect) {
- FNLOG();
-
- return 0;
-}
-
-static int adev_open_output_stream(struct audio_hw_device* dev,
- UNUSED_ATTR audio_io_handle_t handle,
- UNUSED_ATTR audio_devices_t devices,
- UNUSED_ATTR audio_output_flags_t flags,
- struct audio_config* config,
- struct audio_stream_out** stream_out,
- UNUSED_ATTR const char* address)
-
-{
- struct a2dp_audio_device* a2dp_dev = (struct a2dp_audio_device*)dev;
- struct a2dp_stream_out* out;
- int ret = 0;
-
- INFO("opening output");
- // protect against adev->output and stream_out from being inconsistent
- std::lock_guard<std::recursive_mutex> lock(*a2dp_dev->mutex);
- out = (struct a2dp_stream_out*)calloc(1, sizeof(struct a2dp_stream_out));
-
- if (!out) return -ENOMEM;
-
- out->stream.common.get_sample_rate = out_get_sample_rate;
- out->stream.common.set_sample_rate = out_set_sample_rate;
- out->stream.common.get_buffer_size = out_get_buffer_size;
- out->stream.common.get_channels = out_get_channels;
- out->stream.common.get_format = out_get_format;
- out->stream.common.set_format = out_set_format;
- out->stream.common.standby = out_standby;
- out->stream.common.dump = out_dump;
- out->stream.common.set_parameters = out_set_parameters;
- out->stream.common.get_parameters = out_get_parameters;
- out->stream.common.add_audio_effect = out_add_audio_effect;
- out->stream.common.remove_audio_effect = out_remove_audio_effect;
- out->stream.get_latency = out_get_latency;
- out->stream.set_volume = out_set_volume;
- out->stream.write = out_write;
- out->stream.get_render_position = out_get_render_position;
- out->stream.get_presentation_position = out_get_presentation_position;
-
- /* initialize a2dp specifics */
- a2dp_stream_common_init(&out->common);
-
- // Make sure we always have the feeding parameters configured
- btav_a2dp_codec_config_t codec_config;
- btav_a2dp_codec_config_t codec_capability;
- if (a2dp_read_output_audio_config(&out->common, &codec_config,
- &codec_capability,
- true /* update_stream_config */) < 0) {
- ERROR("a2dp_read_output_audio_config failed");
- ret = -1;
- goto err_open;
- }
- // a2dp_read_output_audio_config() opens the socket control path (or fails)
-
- /* set output config values */
- if (config != nullptr) {
- // Try to use the config parameters and send it to the remote side
- // TODO: Shall we use out_set_format() and similar?
- if (config->format != 0) out->common.cfg.format = config->format;
- if (config->sample_rate != 0) out->common.cfg.rate = config->sample_rate;
- if (config->channel_mask != 0)
- out->common.cfg.channel_mask = config->channel_mask;
- if ((out->common.cfg.format != 0) || (out->common.cfg.rate != 0) ||
- (out->common.cfg.channel_mask != 0)) {
- if (a2dp_write_output_audio_config(&out->common) < 0) {
- ERROR("a2dp_write_output_audio_config failed");
- ret = -1;
- goto err_open;
- }
- // Read again and make sure we use the same parameters as the remote side
- if (a2dp_read_output_audio_config(&out->common, &codec_config,
- &codec_capability,
- true /* update_stream_config */) < 0) {
- ERROR("a2dp_read_output_audio_config failed");
- ret = -1;
- goto err_open;
- }
- }
- config->format = out_get_format((const struct audio_stream*)&out->stream);
- config->sample_rate =
- out_get_sample_rate((const struct audio_stream*)&out->stream);
- config->channel_mask =
- out_get_channels((const struct audio_stream*)&out->stream);
-
- INFO(
- "Output stream config: format=0x%x sample_rate=%d channel_mask=0x%x "
- "buffer_sz=%zu",
- config->format, config->sample_rate, config->channel_mask,
- out->common.buffer_sz);
- }
- *stream_out = &out->stream;
- a2dp_dev->output = out;
-
- DEBUG("success");
- /* Delay to ensure Headset is in proper state when START is initiated from
- * DUT immediately after the connection due to ongoing music playback. */
- usleep(250000);
- return 0;
-
-err_open:
- a2dp_stream_common_destroy(&out->common);
- free(out);
- *stream_out = NULL;
- a2dp_dev->output = NULL;
- ERROR("failed");
- return ret;
-}
-
-static void adev_close_output_stream(struct audio_hw_device* dev,
- struct audio_stream_out* stream) {
- struct a2dp_audio_device* a2dp_dev = (struct a2dp_audio_device*)dev;
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- INFO("%s: state %d", __func__, out->common.state);
-
- // prevent interference with adev_set_parameters.
- std::lock_guard<std::recursive_mutex> lock(*a2dp_dev->mutex);
- {
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
- const a2dp_state_t state = out->common.state;
- INFO("closing output (state %d)", (int)state);
- if ((state == AUDIO_A2DP_STATE_STARTED) ||
- (state == AUDIO_A2DP_STATE_STOPPING)) {
- stop_audio_datapath(&out->common);
- }
-
- skt_disconnect(out->common.ctrl_fd);
- out->common.ctrl_fd = AUDIO_SKT_DISCONNECTED;
- }
-
- a2dp_stream_common_destroy(&out->common);
- free(stream);
- a2dp_dev->output = NULL;
-
- DEBUG("done");
-}
-
-static int adev_set_parameters(struct audio_hw_device* dev,
- const char* kvpairs) {
- struct a2dp_audio_device* a2dp_dev = (struct a2dp_audio_device*)dev;
- int retval = 0;
-
- // prevent interference with adev_close_output_stream
- std::lock_guard<std::recursive_mutex> lock(*a2dp_dev->mutex);
- struct a2dp_stream_out* out = a2dp_dev->output;
-
- if (out == NULL) return retval;
-
- INFO("state %d", out->common.state);
-
- retval =
- out->stream.common.set_parameters((struct audio_stream*)out, kvpairs);
-
- return retval;
-}
-
-static char* adev_get_parameters(UNUSED_ATTR const struct audio_hw_device* dev,
- const char* keys) {
- FNLOG();
-
- std::unordered_map<std::string, std::string> params =
- hash_map_utils_new_from_string_params(keys);
- hash_map_utils_dump_string_keys_string_values(params);
-
- return strdup("");
-}
-
-static int adev_init_check(UNUSED_ATTR const struct audio_hw_device* dev) {
- FNLOG();
-
- return 0;
-}
-
-static int adev_set_voice_volume(UNUSED_ATTR struct audio_hw_device* dev,
- UNUSED_ATTR float volume) {
- FNLOG();
-
- return -ENOSYS;
-}
-
-static int adev_set_master_volume(UNUSED_ATTR struct audio_hw_device* dev,
- UNUSED_ATTR float volume) {
- FNLOG();
-
- return -ENOSYS;
-}
-
-static int adev_set_mode(UNUSED_ATTR struct audio_hw_device* dev,
- UNUSED_ATTR audio_mode_t mode) {
- FNLOG();
-
- return 0;
-}
-
-static int adev_set_mic_mute(UNUSED_ATTR struct audio_hw_device* dev,
- UNUSED_ATTR bool state) {
- FNLOG();
-
- return -ENOSYS;
-}
-
-static int adev_get_mic_mute(UNUSED_ATTR const struct audio_hw_device* dev,
- UNUSED_ATTR bool* state) {
- FNLOG();
-
- return -ENOSYS;
-}
-
-static size_t adev_get_input_buffer_size(
- UNUSED_ATTR const struct audio_hw_device* dev,
- UNUSED_ATTR const struct audio_config* config) {
- FNLOG();
-
- return 320;
-}
-
-static int adev_open_input_stream(struct audio_hw_device* dev,
- UNUSED_ATTR audio_io_handle_t handle,
- UNUSED_ATTR audio_devices_t devices,
- UNUSED_ATTR struct audio_config* config,
- struct audio_stream_in** stream_in,
- UNUSED_ATTR audio_input_flags_t flags,
- UNUSED_ATTR const char* address,
- UNUSED_ATTR audio_source_t source) {
- struct a2dp_audio_device* a2dp_dev = (struct a2dp_audio_device*)dev;
- struct a2dp_stream_in* in;
- int ret;
-
- FNLOG();
-
- // protect against adev->input and stream_in from being inconsistent
- std::lock_guard<std::recursive_mutex> lock(*a2dp_dev->mutex);
- in = (struct a2dp_stream_in*)calloc(1, sizeof(struct a2dp_stream_in));
-
- if (!in) return -ENOMEM;
-
- in->stream.common.get_sample_rate = in_get_sample_rate;
- in->stream.common.set_sample_rate = in_set_sample_rate;
- in->stream.common.get_buffer_size = in_get_buffer_size;
- in->stream.common.get_channels = in_get_channels;
- in->stream.common.get_format = in_get_format;
- in->stream.common.set_format = in_set_format;
- in->stream.common.standby = in_standby;
- in->stream.common.dump = in_dump;
- in->stream.common.set_parameters = in_set_parameters;
- in->stream.common.get_parameters = in_get_parameters;
- in->stream.common.add_audio_effect = in_add_audio_effect;
- in->stream.common.remove_audio_effect = in_remove_audio_effect;
- in->stream.set_gain = in_set_gain;
- in->stream.read = in_read;
- in->stream.get_input_frames_lost = in_get_input_frames_lost;
-
- /* initialize a2dp specifics */
- a2dp_stream_common_init(&in->common);
-
- *stream_in = &in->stream;
- a2dp_dev->input = in;
-
- if (a2dp_read_input_audio_config(&in->common) < 0) {
- ERROR("a2dp_read_input_audio_config failed (%s)", strerror(errno));
- ret = -1;
- goto err_open;
- }
- // a2dp_read_input_audio_config() opens socket control path (or fails)
-
- DEBUG("success");
- return 0;
-
-err_open:
- a2dp_stream_common_destroy(&in->common);
- free(in);
- *stream_in = NULL;
- a2dp_dev->input = NULL;
- ERROR("failed");
- return ret;
-}
-
-static void adev_close_input_stream(struct audio_hw_device* dev,
- struct audio_stream_in* stream) {
- struct a2dp_audio_device* a2dp_dev = (struct a2dp_audio_device*)dev;
- struct a2dp_stream_in* in = (struct a2dp_stream_in*)stream;
-
- std::lock_guard<std::recursive_mutex> lock(*a2dp_dev->mutex);
- {
- std::lock_guard<std::recursive_mutex> lock(*in->common.mutex);
- const a2dp_state_t state = in->common.state;
- INFO("closing input (state %d)", (int)state);
-
- if ((state == AUDIO_A2DP_STATE_STARTED) ||
- (state == AUDIO_A2DP_STATE_STOPPING))
- stop_audio_datapath(&in->common);
-
- skt_disconnect(in->common.ctrl_fd);
- in->common.ctrl_fd = AUDIO_SKT_DISCONNECTED;
- }
- a2dp_stream_common_destroy(&in->common);
- free(stream);
- a2dp_dev->input = NULL;
-
- DEBUG("done");
-}
-
-static int adev_dump(UNUSED_ATTR const audio_hw_device_t* device,
- UNUSED_ATTR int fd) {
- FNLOG();
-
- return 0;
-}
-
-static int adev_close(hw_device_t* device) {
- struct a2dp_audio_device* a2dp_dev = (struct a2dp_audio_device*)device;
- FNLOG();
-
- delete a2dp_dev->mutex;
- a2dp_dev->mutex = nullptr;
- free(device);
- return 0;
-}
-
-static int adev_open(const hw_module_t* module, const char* name,
- hw_device_t** device) {
- struct a2dp_audio_device* adev;
-
- INFO(" adev_open in A2dp_hw module");
- FNLOG();
-
- if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) {
- ERROR("interface %s not matching [%s]", name, AUDIO_HARDWARE_INTERFACE);
- return -EINVAL;
- }
-
- adev = (struct a2dp_audio_device*)calloc(1, sizeof(struct a2dp_audio_device));
-
- if (!adev) return -ENOMEM;
-
- adev->mutex = new std::recursive_mutex;
-
- adev->device.common.tag = HARDWARE_DEVICE_TAG;
- adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
- adev->device.common.module = (struct hw_module_t*)module;
- adev->device.common.close = adev_close;
-
- adev->device.init_check = adev_init_check;
- adev->device.set_voice_volume = adev_set_voice_volume;
- adev->device.set_master_volume = adev_set_master_volume;
- adev->device.set_mode = adev_set_mode;
- adev->device.set_mic_mute = adev_set_mic_mute;
- adev->device.get_mic_mute = adev_get_mic_mute;
- adev->device.set_parameters = adev_set_parameters;
- adev->device.get_parameters = adev_get_parameters;
- adev->device.get_input_buffer_size = adev_get_input_buffer_size;
- adev->device.open_output_stream = adev_open_output_stream;
- adev->device.close_output_stream = adev_close_output_stream;
- adev->device.open_input_stream = adev_open_input_stream;
- adev->device.close_input_stream = adev_close_input_stream;
- adev->device.dump = adev_dump;
-
- adev->output = NULL;
-
- *device = &adev->device.common;
-
- return 0;
-}
-
-static struct hw_module_methods_t hal_module_methods = {
- .open = adev_open,
-};
-
-__attribute__((
- visibility("default"))) struct audio_module HAL_MODULE_INFO_SYM = {
- .common =
- {
- .tag = HARDWARE_MODULE_TAG,
- .version_major = 1,
- .version_minor = 0,
- .id = AUDIO_HARDWARE_MODULE_ID,
- .name = "A2DP Audio HW HAL",
- .author = "The Android Open Source Project",
- .methods = &hal_module_methods,
- },
-};
diff --git a/audio_a2dp_hw/src/audio_a2dp_hw_utils.cc b/audio_a2dp_hw/src/audio_a2dp_hw_utils.cc
deleted file mode 100644
index b4115c6..0000000
--- a/audio_a2dp_hw/src/audio_a2dp_hw_utils.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2009-2012 Broadcom Corporation
- *
- * 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 "audio_a2dp_hw.h"
-#include "osi/include/properties.h"
-
-#define CASE_RETURN_STR(const) \
- case const: \
- return #const;
-
-const char* audio_a2dp_hw_dump_ctrl_event(tA2DP_CTRL_CMD event) {
- switch (event) {
- CASE_RETURN_STR(A2DP_CTRL_CMD_NONE)
- CASE_RETURN_STR(A2DP_CTRL_CMD_CHECK_READY)
- CASE_RETURN_STR(A2DP_CTRL_CMD_START)
- CASE_RETURN_STR(A2DP_CTRL_CMD_STOP)
- CASE_RETURN_STR(A2DP_CTRL_CMD_SUSPEND)
- CASE_RETURN_STR(A2DP_CTRL_GET_INPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(A2DP_CTRL_GET_PRESENTATION_POSITION)
- }
-
- return "UNKNOWN A2DP_CTRL_CMD";
-}
-
-bool delay_reporting_enabled() {
- return !osi_property_get_bool("persist.bluetooth.disabledelayreports", false);
-}
diff --git a/audio_a2dp_hw/test/audio_a2dp_hw_test.cc b/audio_a2dp_hw/test/audio_a2dp_hw_test.cc
deleted file mode 100644
index 8fcbae5..0000000
--- a/audio_a2dp_hw/test/audio_a2dp_hw_test.cc
+++ /dev/null
@@ -1,146 +0,0 @@
-/******************************************************************************
- *
- * Copyright 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.
- *
- ******************************************************************************/
-
-#include <gtest/gtest.h>
-
-#include "audio_a2dp_hw/include/audio_a2dp_hw.h"
-
-namespace {
-static uint32_t codec_sample_rate2value(
- btav_a2dp_codec_sample_rate_t codec_sample_rate) {
- switch (codec_sample_rate) {
- case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
- return 44100;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
- return 48000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
- return 88200;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
- return 96000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
- return 176400;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
- return 192000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
- return 16000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
- return 24000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE:
- break;
- }
- return 0;
-}
-
-static uint32_t codec_bits_per_sample2value(
- btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample) {
- switch (codec_bits_per_sample) {
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
- return 16;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
- return 24;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
- return 32;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
- break;
- }
- return 0;
-}
-
-static uint32_t codec_channel_mode2value(
- btav_a2dp_codec_channel_mode_t codec_channel_mode) {
- switch (codec_channel_mode) {
- case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
- return 1;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
- return 2;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
- break;
- }
- return 0;
-}
-
-} // namespace
-
-class AudioA2dpHwTest : public ::testing::Test {
- protected:
- AudioA2dpHwTest() {}
-
- private:
-};
-
-TEST_F(AudioA2dpHwTest, test_compute_buffer_size) {
- const btav_a2dp_codec_sample_rate_t codec_sample_rate_array[] = {
- BTAV_A2DP_CODEC_SAMPLE_RATE_NONE, BTAV_A2DP_CODEC_SAMPLE_RATE_44100,
- BTAV_A2DP_CODEC_SAMPLE_RATE_48000, BTAV_A2DP_CODEC_SAMPLE_RATE_88200,
- BTAV_A2DP_CODEC_SAMPLE_RATE_96000, BTAV_A2DP_CODEC_SAMPLE_RATE_176400,
- BTAV_A2DP_CODEC_SAMPLE_RATE_192000};
-
- const btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample_array[] = {
- BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE, BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16,
- BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24, BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32};
-
- const btav_a2dp_codec_channel_mode_t codec_channel_mode_array[] = {
- BTAV_A2DP_CODEC_CHANNEL_MODE_NONE, BTAV_A2DP_CODEC_CHANNEL_MODE_MONO,
- BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO};
-
- for (const auto codec_sample_rate : codec_sample_rate_array) {
- for (const auto codec_bits_per_sample : codec_bits_per_sample_array) {
- for (const auto codec_channel_mode : codec_channel_mode_array) {
- size_t buffer_size = audio_a2dp_hw_stream_compute_buffer_size(
- codec_sample_rate, codec_bits_per_sample, codec_channel_mode);
-
- // Check for invalid input
- if ((codec_sample_rate == BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) ||
- (codec_bits_per_sample == BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) ||
- (codec_channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE)) {
- EXPECT_EQ(buffer_size,
- static_cast<size_t>(AUDIO_STREAM_OUTPUT_BUFFER_SZ));
- continue;
- }
-
- uint32_t sample_rate = codec_sample_rate2value(codec_sample_rate);
- EXPECT_TRUE(sample_rate != 0);
-
- uint32_t bits_per_sample =
- codec_bits_per_sample2value(codec_bits_per_sample);
- EXPECT_TRUE(bits_per_sample != 0);
-
- uint32_t number_of_channels =
- codec_channel_mode2value(codec_channel_mode);
- EXPECT_TRUE(number_of_channels != 0);
-
- const uint64_t time_period_ms = 20; // TODO: Must be a parameter
- size_t expected_buffer_size =
- (time_period_ms * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * sample_rate *
- number_of_channels * (bits_per_sample / 8)) /
- 1000;
-
- // Compute the divisor and adjust the buffer size
- const size_t divisor = (AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * 16 *
- number_of_channels * bits_per_sample) /
- 8;
- const size_t remainder = expected_buffer_size % divisor;
- if (remainder != 0) {
- expected_buffer_size += divisor - remainder;
- }
-
- EXPECT_EQ(buffer_size, expected_buffer_size);
- }
- }
- }
-}
diff --git a/audio_bluetooth_hw/Android.bp b/audio_bluetooth_hw/Android.bp
deleted file mode 100644
index e52f1db..0000000
--- a/audio_bluetooth_hw/Android.bp
+++ /dev/null
@@ -1,59 +0,0 @@
-// The format of the name is audio.<type>.<hardware/etc>.so
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-cc_library_shared {
- name: "audio.bluetooth.default",
- relative_install_path: "hw",
- proprietary: true,
- srcs: [
- "audio_bluetooth_hw.cc",
- "stream_apis.cc",
- "device_port_proxy.cc",
- "utils.cc",
- ],
- header_libs: ["libhardware_headers"],
- shared_libs: [
- "android.hardware.bluetooth.audio@2.0",
- "android.hardware.bluetooth.audio@2.1",
- "libaudioutils",
- "libbase",
- "libbluetooth_audio_session",
- "libcutils",
- "libfmq",
- "libhidlbase",
- "liblog",
- "libutils",
- ],
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-unused-parameter",
- ],
-}
-
-cc_test {
- name: "audio_bluetooth_hw_test",
- srcs: [
- "utils.cc",
- "utils_unittest.cc",
- ],
- shared_libs: [
- "libbase",
- "libcutils",
- "liblog",
- "libutils",
- ],
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-unused-parameter",
- ],
-}
diff --git a/audio_bluetooth_hw/audio_bluetooth_hw.cc b/audio_bluetooth_hw/audio_bluetooth_hw.cc
deleted file mode 100644
index 887c4e3..0000000
--- a/audio_bluetooth_hw/audio_bluetooth_hw.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#define LOG_TAG "BTAudioHw"
-
-#include <android-base/logging.h>
-#include <errno.h>
-#include <hardware/hardware.h>
-#include <log/log.h>
-#include <malloc.h>
-#include <string.h>
-#include <system/audio.h>
-
-#include "stream_apis.h"
-#include "utils.h"
-
-using ::android::bluetooth::audio::utils::GetAudioParamString;
-using ::android::bluetooth::audio::utils::ParseAudioParams;
-
-static int adev_set_parameters(struct audio_hw_device* dev,
- const char* kvpairs) {
- LOG(VERBOSE) << __func__ << ": kevpairs=[" << kvpairs << "]";
- std::unordered_map<std::string, std::string> params =
- ParseAudioParams(kvpairs);
- if (params.empty()) return 0;
-
- LOG(VERBOSE) << __func__ << ": ParamsMap=[" << GetAudioParamString(params)
- << "]";
- if (params.find("A2dpSuspended") == params.end()) {
- return -ENOSYS;
- }
-
- auto* bluetooth_device = reinterpret_cast<BluetoothAudioDevice*>(dev);
- std::lock_guard<std::mutex> guard(bluetooth_device->mutex_);
- for (auto sout : bluetooth_device->opened_stream_outs_) {
- if (sout->stream_out_.common.set_parameters != nullptr) {
- sout->stream_out_.common.set_parameters(&sout->stream_out_.common,
- kvpairs);
- }
- }
- return 0;
-}
-
-static char* adev_get_parameters(const struct audio_hw_device* dev,
- const char* keys) {
- LOG(VERBOSE) << __func__ << ": keys=[" << keys << "]";
- return strdup("");
-}
-
-static int adev_init_check(const struct audio_hw_device* dev) { return 0; }
-
-static int adev_set_voice_volume(struct audio_hw_device* dev, float volume) {
- LOG(VERBOSE) << __func__ << ": volume=" << volume;
- return -ENOSYS;
-}
-
-static int adev_set_master_volume(struct audio_hw_device* dev, float volume) {
- LOG(VERBOSE) << __func__ << ": volume=" << volume;
- return -ENOSYS;
-}
-
-static int adev_get_master_volume(struct audio_hw_device* dev, float* volume) {
- return -ENOSYS;
-}
-
-static int adev_set_master_mute(struct audio_hw_device* dev, bool muted) {
- LOG(VERBOSE) << __func__ << ": mute=" << muted;
- return -ENOSYS;
-}
-
-static int adev_get_master_mute(struct audio_hw_device* dev, bool* muted) {
- return -ENOSYS;
-}
-
-static int adev_set_mode(struct audio_hw_device* dev, audio_mode_t mode) {
- LOG(VERBOSE) << __func__ << ": mode=" << mode;
- return 0;
-}
-
-static int adev_set_mic_mute(struct audio_hw_device* dev, bool state) {
- LOG(VERBOSE) << __func__ << ": state=" << state;
- return -ENOSYS;
-}
-
-static int adev_get_mic_mute(const struct audio_hw_device* dev, bool* state) {
- return -ENOSYS;
-}
-
-static int adev_dump(const audio_hw_device_t* device, int fd) { return 0; }
-
-static int adev_close(hw_device_t* device) {
- auto* bluetooth_device = reinterpret_cast<BluetoothAudioDevice*>(device);
- delete bluetooth_device;
- return 0;
-}
-
-static int adev_open(const hw_module_t* module, const char* name,
- hw_device_t** device) {
- LOG(VERBOSE) << __func__ << ": name=[" << name << "]";
- if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
-
- auto bluetooth_audio_device = new BluetoothAudioDevice{};
- struct audio_hw_device* adev = &bluetooth_audio_device->audio_device_;
- if (!adev) return -ENOMEM;
-
- adev->common.tag = HARDWARE_DEVICE_TAG;
- adev->common.version = AUDIO_DEVICE_API_VERSION_2_0;
- adev->common.module = (struct hw_module_t*)module;
- adev->common.close = adev_close;
-
- adev->init_check = adev_init_check;
- adev->set_voice_volume = adev_set_voice_volume;
- adev->set_master_volume = adev_set_master_volume;
- adev->get_master_volume = adev_get_master_volume;
- adev->set_mode = adev_set_mode;
- adev->set_mic_mute = adev_set_mic_mute;
- adev->get_mic_mute = adev_get_mic_mute;
- adev->set_parameters = adev_set_parameters;
- adev->get_parameters = adev_get_parameters;
- adev->get_input_buffer_size = adev_get_input_buffer_size;
- adev->open_output_stream = adev_open_output_stream;
- adev->close_output_stream = adev_close_output_stream;
- adev->open_input_stream = adev_open_input_stream;
- adev->close_input_stream = adev_close_input_stream;
- adev->dump = adev_dump;
- adev->set_master_mute = adev_set_master_mute;
- adev->get_master_mute = adev_get_master_mute;
-
- *device = &adev->common;
- return 0;
-}
-
-static struct hw_module_methods_t hal_module_methods = {
- .open = adev_open,
-};
-
-struct audio_module HAL_MODULE_INFO_SYM = {
- .common =
- {
- .tag = HARDWARE_MODULE_TAG,
- .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
- .hal_api_version = HARDWARE_HAL_API_VERSION,
- .id = AUDIO_HARDWARE_MODULE_ID,
- .name = "Bluetooth Audio HW HAL",
- .author = "The Android Open Source Project",
- .methods = &hal_module_methods,
- },
-};
diff --git a/audio_bluetooth_hw/device_port_proxy.cc b/audio_bluetooth_hw/device_port_proxy.cc
deleted file mode 100644
index afa8742..0000000
--- a/audio_bluetooth_hw/device_port_proxy.cc
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#define LOG_TAG "BTAudioHalDeviceProxy"
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <audio_utils/primitives.h>
-#include <inttypes.h>
-#include <log/log.h>
-#include <stdlib.h>
-
-#include "BluetoothAudioSessionControl_2_1.h"
-#include "device_port_proxy.h"
-#include "stream_apis.h"
-#include "utils.h"
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-
-using ::android::base::StringPrintf;
-using ::android::bluetooth::audio::BluetoothAudioSessionControl_2_1;
-using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
-using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
-using ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
-using SampleRate = ::android::hardware::bluetooth::audio::V2_0::SampleRate;
-using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate;
-using BluetoothAudioStatus =
- ::android::hardware::bluetooth::audio::V2_0::Status;
-using ControlResultCallback = std::function<void(
- uint16_t cookie, bool start_resp, const BluetoothAudioStatus& status)>;
-using SessionChangedCallback = std::function<void(uint16_t cookie)>;
-
-namespace {
-
-unsigned int SampleRateToAudioFormat(SampleRate_2_1 sample_rate) {
- switch (sample_rate) {
- case SampleRate_2_1::RATE_8000:
- return 8000;
- case SampleRate_2_1::RATE_16000:
- return 16000;
- case SampleRate_2_1::RATE_24000:
- return 24000;
- case SampleRate_2_1::RATE_32000:
- return 32000;
- case SampleRate_2_1::RATE_44100:
- return 44100;
- case SampleRate_2_1::RATE_48000:
- return 48000;
- case SampleRate_2_1::RATE_88200:
- return 88200;
- case SampleRate_2_1::RATE_96000:
- return 96000;
- case SampleRate_2_1::RATE_176400:
- return 176400;
- case SampleRate_2_1::RATE_192000:
- return 192000;
- default:
- return kBluetoothDefaultSampleRate;
- }
-}
-audio_channel_mask_t OutputChannelModeToAudioFormat(ChannelMode channel_mode) {
- switch (channel_mode) {
- case ChannelMode::MONO:
- return AUDIO_CHANNEL_OUT_MONO;
- case ChannelMode::STEREO:
- return AUDIO_CHANNEL_OUT_STEREO;
- default:
- return kBluetoothDefaultOutputChannelModeMask;
- }
-}
-
-audio_channel_mask_t InputChannelModeToAudioFormat(ChannelMode channel_mode) {
- switch (channel_mode) {
- case ChannelMode::MONO:
- return AUDIO_CHANNEL_IN_MONO;
- case ChannelMode::STEREO:
- return AUDIO_CHANNEL_IN_STEREO;
- default:
- return kBluetoothDefaultInputChannelModeMask;
- }
-}
-
-audio_format_t BitsPerSampleToAudioFormat(BitsPerSample bits_per_sample) {
- switch (bits_per_sample) {
- case BitsPerSample::BITS_16:
- return AUDIO_FORMAT_PCM_16_BIT;
- case BitsPerSample::BITS_24:
- return AUDIO_FORMAT_PCM_24_BIT_PACKED;
- case BitsPerSample::BITS_32:
- return AUDIO_FORMAT_PCM_32_BIT;
- default:
- return kBluetoothDefaultAudioFormatBitsPerSample;
- }
-}
-
-// The maximum time to wait in std::condition_variable::wait_for()
-constexpr unsigned int kMaxWaitingTimeMs = 4500;
-
-} // namespace
-
-BluetoothAudioPort::BluetoothAudioPort()
- : cookie_(android::bluetooth::audio::kObserversCookieUndefined),
- state_(BluetoothStreamState::DISABLED),
- session_type_(SessionType_2_1::UNKNOWN) {}
-
-bool BluetoothAudioPort::SetUp(audio_devices_t devices) {
- if (!init_session_type(devices)) return false;
-
- state_ = BluetoothStreamState::STANDBY;
-
- auto control_result_cb = [port = this](uint16_t cookie, bool start_resp,
- const BluetoothAudioStatus& status) {
- if (!port->in_use()) {
- LOG(ERROR) << "control_result_cb: BluetoothAudioPort is not in use";
- return;
- }
- if (port->cookie_ != cookie) {
- LOG(ERROR) << "control_result_cb: proxy of device port (cookie=" << StringPrintf("%#hx", cookie)
- << ") is corrupted";
- return;
- }
- port->ControlResultHandler(status);
- };
- auto session_changed_cb = [port = this](uint16_t cookie) {
- if (!port->in_use()) {
- LOG(ERROR) << "session_changed_cb: BluetoothAudioPort is not in use";
- return;
- }
- if (port->cookie_ != cookie) {
- LOG(ERROR) << "session_changed_cb: proxy of device port (cookie=" << StringPrintf("%#hx", cookie)
- << ") is corrupted";
- return;
- }
- port->SessionChangedHandler();
- };
- ::android::bluetooth::audio::PortStatusCallbacks cbacks = {
- .control_result_cb_ = control_result_cb,
- .session_changed_cb_ = session_changed_cb};
- cookie_ = BluetoothAudioSessionControl_2_1::RegisterControlResultCback(
- session_type_, cbacks);
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_);
-
- return (cookie_ != android::bluetooth::audio::kObserversCookieUndefined);
-}
-
-bool BluetoothAudioPort::init_session_type(audio_devices_t device) {
- switch (device) {
- case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
- case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
- case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
- LOG(VERBOSE) << __func__ << ": device=AUDIO_DEVICE_OUT_BLUETOOTH_A2DP (HEADPHONES/SPEAKER) ("
- << StringPrintf("%#x", device) << ")";
- session_type_ = SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH;
- break;
- case AUDIO_DEVICE_OUT_HEARING_AID:
- LOG(VERBOSE) << __func__ << ": device=AUDIO_DEVICE_OUT_HEARING_AID (MEDIA/VOICE) (" << StringPrintf("%#x", device)
- << ")";
- session_type_ = SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH;
- break;
- case AUDIO_DEVICE_OUT_BLE_HEADSET:
- LOG(VERBOSE) << __func__
- << ": device=AUDIO_DEVICE_OUT_BLE_HEADSET (MEDIA/VOICE) ("
- << StringPrintf("%#x", device) << ")";
- session_type_ = SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH;
- break;
- case AUDIO_DEVICE_OUT_BLE_SPEAKER:
- LOG(VERBOSE) << __func__
- << ": device=AUDIO_DEVICE_OUT_BLE_SPEAKER (MEDIA) ("
- << StringPrintf("%#x", device) << ")";
- session_type_ = SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH;
- break;
- case AUDIO_DEVICE_IN_BLE_HEADSET:
- LOG(VERBOSE) << __func__
- << ": device=AUDIO_DEVICE_IN_BLE_HEADSET (VOICE) ("
- << StringPrintf("%#x", device) << ")";
- session_type_ = SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH;
- break;
- default:
- LOG(ERROR) << __func__ << ": unknown device=" << StringPrintf("%#x", device);
- return false;
- }
-
- if (!BluetoothAudioSessionControl_2_1::IsSessionReady(session_type_)) {
- LOG(ERROR) << __func__ << ": device=" << StringPrintf("%#x", device) << ", session_type=" << toString(session_type_)
- << " is not ready";
- return false;
- }
- return true;
-}
-
-void BluetoothAudioPort::TearDown() {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << " unknown monitor";
- return;
- }
-
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_);
- BluetoothAudioSessionControl_2_1::UnregisterControlResultCback(session_type_,
- cookie_);
- cookie_ = android::bluetooth::audio::kObserversCookieUndefined;
-}
-
-void BluetoothAudioPort::ControlResultHandler(
- const BluetoothAudioStatus& status) {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPortis not in use";
- return;
- }
- std::unique_lock<std::mutex> port_lock(cv_mutex_);
- BluetoothStreamState previous_state = state_;
- LOG(INFO) << "control_result_cb: session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", previous_state=" << previous_state
- << ", status=" << toString(status);
-
- switch (previous_state) {
- case BluetoothStreamState::STARTING:
- if (status == BluetoothAudioStatus::SUCCESS) {
- state_ = BluetoothStreamState::STARTED;
- } else {
- // Set to standby since the stack may be busy switching between outputs
- LOG(WARNING) << "control_result_cb: status=" << toString(status)
- << " failure for session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", previous_state=" << previous_state;
- state_ = BluetoothStreamState::STANDBY;
- }
- break;
- case BluetoothStreamState::SUSPENDING:
- if (status == BluetoothAudioStatus::SUCCESS) {
- state_ = BluetoothStreamState::STANDBY;
- } else {
- // It will be failed if the headset is disconnecting, and set to disable
- // to wait for re-init again
- LOG(WARNING) << "control_result_cb: status=" << toString(status)
- << " failure for session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", previous_state=" << previous_state;
- state_ = BluetoothStreamState::DISABLED;
- }
- break;
- default:
- LOG(ERROR) << "control_result_cb: unexpected status=" << toString(status)
- << " for session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
- << ", previous_state=" << previous_state;
- return;
- }
- port_lock.unlock();
- internal_cv_.notify_all();
-}
-
-void BluetoothAudioPort::SessionChangedHandler() {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
- return;
- }
- std::unique_lock<std::mutex> port_lock(cv_mutex_);
- BluetoothStreamState previous_state = state_;
- LOG(INFO) << "session_changed_cb: session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", previous_state=" << previous_state;
- if (previous_state != BluetoothStreamState::DISABLED) {
- state_ = BluetoothStreamState::DISABLED;
- } else {
- state_ = BluetoothStreamState::STANDBY;
- }
- port_lock.unlock();
- internal_cv_.notify_all();
-}
-
-bool BluetoothAudioPort::in_use() const {
- return (cookie_ != android::bluetooth::audio::kObserversCookieUndefined);
-}
-
-bool BluetoothAudioPortOut::LoadAudioConfig(audio_config_t* audio_cfg) const {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPortOut is not in use";
- audio_cfg->sample_rate = kBluetoothDefaultSampleRate;
- audio_cfg->channel_mask = kBluetoothDefaultOutputChannelModeMask;
- audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample;
- return false;
- }
-
- const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration&
- hal_audio_cfg =
- BluetoothAudioSessionControl_2_1::GetAudioConfig(session_type_);
- if (hal_audio_cfg.getDiscriminator() !=
- ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
- hidl_discriminator::pcmConfig) {
- audio_cfg->sample_rate = kBluetoothDefaultSampleRate;
- audio_cfg->channel_mask = kBluetoothDefaultOutputChannelModeMask;
- audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample;
- return false;
- }
- const ::android::hardware::bluetooth::audio::V2_1::PcmParameters& pcm_cfg =
- hal_audio_cfg.pcmConfig();
- LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << ", PcmConfig=["
- << toString(pcm_cfg) << "]";
- if (pcm_cfg.sampleRate == SampleRate_2_1::RATE_UNKNOWN ||
- pcm_cfg.channelMode == ChannelMode::UNKNOWN ||
- pcm_cfg.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
- return false;
- }
- audio_cfg->sample_rate = SampleRateToAudioFormat(pcm_cfg.sampleRate);
- audio_cfg->channel_mask =
- (is_stereo_to_mono_
- ? AUDIO_CHANNEL_OUT_STEREO
- : OutputChannelModeToAudioFormat(pcm_cfg.channelMode));
- audio_cfg->format = BitsPerSampleToAudioFormat(pcm_cfg.bitsPerSample);
- return true;
-}
-
-bool BluetoothAudioPortIn::LoadAudioConfig(audio_config_t* audio_cfg) const {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPortIn is not in use";
- audio_cfg->sample_rate = kBluetoothDefaultSampleRate;
- audio_cfg->channel_mask = kBluetoothDefaultInputChannelModeMask;
- audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample;
- return false;
- }
-
- const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration&
- hal_audio_cfg =
- BluetoothAudioSessionControl_2_1::GetAudioConfig(session_type_);
- if (hal_audio_cfg.getDiscriminator() !=
- ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
- hidl_discriminator::pcmConfig) {
- audio_cfg->sample_rate = kBluetoothDefaultSampleRate;
- audio_cfg->channel_mask = kBluetoothDefaultInputChannelModeMask;
- audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample;
- return false;
- }
- const ::android::hardware::bluetooth::audio::V2_1::PcmParameters& pcm_cfg =
- hal_audio_cfg.pcmConfig();
- LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_)
- << ", state=" << state_ << ", PcmConfig=[" << toString(pcm_cfg)
- << "]";
- if (pcm_cfg.sampleRate == SampleRate_2_1::RATE_UNKNOWN ||
- pcm_cfg.channelMode == ChannelMode::UNKNOWN ||
- pcm_cfg.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
- return false;
- }
-
- audio_cfg->sample_rate = SampleRateToAudioFormat(pcm_cfg.sampleRate);
- audio_cfg->channel_mask = InputChannelModeToAudioFormat(pcm_cfg.channelMode);
- audio_cfg->format = BitsPerSampleToAudioFormat(pcm_cfg.bitsPerSample);
- return true;
-}
-
-bool BluetoothAudioPort::CondwaitState(BluetoothStreamState state) {
- bool retval;
- std::unique_lock<std::mutex> port_lock(cv_mutex_);
- switch (state) {
- case BluetoothStreamState::STARTING:
- LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << " waiting for STARTED";
- retval = internal_cv_.wait_for(
- port_lock, std::chrono::milliseconds(kMaxWaitingTimeMs),
- [this] { return this->state_ != BluetoothStreamState::STARTING; });
- retval = retval && state_ == BluetoothStreamState::STARTED;
- break;
- case BluetoothStreamState::SUSPENDING:
- LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << " waiting for SUSPENDED";
- retval = internal_cv_.wait_for(
- port_lock, std::chrono::milliseconds(kMaxWaitingTimeMs),
- [this] { return this->state_ != BluetoothStreamState::SUSPENDING; });
- retval = retval && state_ == BluetoothStreamState::STANDBY;
- break;
- default:
- LOG(WARNING) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << " waiting for KNOWN";
- return false;
- }
-
- return retval; // false if any failure like timeout
-}
-
-bool BluetoothAudioPort::Start() {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
- return false;
- }
-
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
- << ", state=" << state_ << ", mono=" << (is_stereo_to_mono_ ? "true" : "false") << " request";
- bool retval = false;
- if (state_ == BluetoothStreamState::STANDBY) {
- state_ = BluetoothStreamState::STARTING;
- if (BluetoothAudioSessionControl_2_1::StartStream(session_type_)) {
- retval = CondwaitState(BluetoothStreamState::STARTING);
- } else {
- LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " Hal fails";
- }
- }
-
- if (retval) {
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_
- << ", mono=" << (is_stereo_to_mono_ ? "true" : "false") << " done";
- } else {
- LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " failure";
- }
-
- return retval; // false if any failure like timeout
-}
-
-bool BluetoothAudioPort::Suspend() {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
- return false;
- }
-
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
- << ", state=" << state_ << " request";
- bool retval = false;
- if (state_ == BluetoothStreamState::STARTED) {
- state_ = BluetoothStreamState::SUSPENDING;
- if (BluetoothAudioSessionControl_2_1::SuspendStream(session_type_)) {
- retval = CondwaitState(BluetoothStreamState::SUSPENDING);
- } else {
- LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " Hal fails";
- }
- }
-
- if (retval) {
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " done";
- } else {
- LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " failure";
- }
-
- return retval; // false if any failure like timeout
-}
-
-void BluetoothAudioPort::Stop() {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
- return;
- }
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
- << ", state=" << state_ << " request";
- state_ = BluetoothStreamState::DISABLED;
- BluetoothAudioSessionControl_2_1::StopStream(session_type_);
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
- << ", state=" << state_ << " done";
-}
-
-size_t BluetoothAudioPortOut::WriteData(const void* buffer, size_t bytes) const {
- if (!in_use()) return 0;
- if (!is_stereo_to_mono_) {
- return BluetoothAudioSessionControl_2_1::OutWritePcmData(session_type_,
- buffer, bytes);
- }
-
- // WAR to mix the stereo into Mono (16 bits per sample)
- const size_t write_frames = bytes >> 2;
- if (write_frames == 0) return 0;
- auto src = static_cast<const int16_t*>(buffer);
- std::unique_ptr<int16_t[]> dst{new int16_t[write_frames]};
- downmix_to_mono_i16_from_stereo_i16(dst.get(), src, write_frames);
- // a frame is 16 bits, and the size of a mono frame is equal to half a stereo.
- return BluetoothAudioSessionControl_2_1::OutWritePcmData(
- session_type_, dst.get(), write_frames * 2) *
- 2;
-}
-
-size_t BluetoothAudioPortIn::ReadData(void* buffer, size_t bytes) const {
- if (!in_use()) return 0;
- return BluetoothAudioSessionControl_2_1::InReadPcmData(session_type_, buffer,
- bytes);
-}
-
-bool BluetoothAudioPort::GetPresentationPosition(uint64_t* delay_ns,
- uint64_t* bytes,
- timespec* timestamp) const {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
- return false;
- }
- bool retval = BluetoothAudioSessionControl_2_1::GetPresentationPosition(
- session_type_, delay_ns, bytes, timestamp);
- LOG(VERBOSE) << __func__ << ": session_type=" << StringPrintf("%#hhx", session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << ", delay=" << *delay_ns
- << "ns, data=" << *bytes << " bytes, timestamp=" << timestamp->tv_sec << "."
- << StringPrintf("%09ld", timestamp->tv_nsec) << "s";
-
- return retval;
-}
-
-void BluetoothAudioPort::UpdateMetadata(
- const source_metadata* source_metadata) const {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
- return;
- }
- LOG(DEBUG) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
- << ", state=" << state_ << ", " << source_metadata->track_count << " track(s)";
- if (source_metadata->track_count == 0) return;
- BluetoothAudioSessionControl_2_1::UpdateTracksMetadata(session_type_,
- source_metadata);
-}
-
-BluetoothStreamState BluetoothAudioPort::GetState() const { return state_; }
-
-void BluetoothAudioPort::SetState(BluetoothStreamState state) {
- state_ = state;
-}
-
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/audio_bluetooth_hw/device_port_proxy.h b/audio_bluetooth_hw/device_port_proxy.h
deleted file mode 100644
index 9e11392..0000000
--- a/audio_bluetooth_hw/device_port_proxy.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#pragma once
-
-#include <android/hardware/bluetooth/audio/2.1/types.h>
-#include <hardware/audio.h>
-#include <condition_variable>
-#include <mutex>
-#include <unordered_map>
-
-enum class BluetoothStreamState : uint8_t;
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-
-using SessionType_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::SessionType;
-
-// Proxy for Bluetooth Audio HW Module to communicate with Bluetooth Audio
-// Session Control. All methods are not thread safe, so users must acquire a
-// lock. Note: currently, in stream_apis.cc, if GetState() is only used for
-// verbose logging, it is not locked, so the state may not be synchronized.
-class BluetoothAudioPort {
- public:
- BluetoothAudioPort();
- virtual ~BluetoothAudioPort() = default;
-
- // Fetch output control / data path of BluetoothAudioPort and setup
- // callbacks into BluetoothAudioProvider. If SetUp() returns false, the audio
- // HAL must delete this BluetoothAudioPort and return EINVAL to caller
- bool SetUp(audio_devices_t devices);
-
- // Unregister this BluetoothAudioPort from BluetoothAudioSessionControl.
- // Audio HAL must delete this BluetoothAudioPort after calling this.
- void TearDown();
-
- // When the Audio framework / HAL tries to query audio config about format,
- // channel mask and sample rate, it uses this function to fetch from the
- // Bluetooth stack
- virtual bool LoadAudioConfig(audio_config_t* audio_cfg) const = 0;
-
- // WAR to support Mono mode / 16 bits per sample
- void ForcePcmStereoToMono(bool force) {
- is_stereo_to_mono_ = force;
- }
-
- // When the Audio framework / HAL wants to change the stream state, it invokes
- // these 3 functions to control the Bluetooth stack (Audio Control Path).
- // Note: Both Start() and Suspend() will return ture when there are no errors.
- // Called by Audio framework / HAL to start the stream
- bool Start();
- // Called by Audio framework / HAL to suspend the stream
- bool Suspend();
- // Called by Audio framework / HAL to stop the stream
- void Stop();
-
- // Called by the Audio framework / HAL to fetch informaiton about audio frames
- // presented to an external sink, or frames presented fror an internal sink
- bool GetPresentationPosition(uint64_t* delay_ns, uint64_t* bytes,
- timespec* timestamp) const;
-
- // Called by the Audio framework / HAL when the metadata of the stream's
- // source has been changed.
- void UpdateMetadata(const source_metadata* source_metadata) const;
-
- // Return the current BluetoothStreamState
- BluetoothStreamState GetState() const;
-
- // Set the current BluetoothStreamState
- void SetState(BluetoothStreamState state);
-
- bool IsA2dp() const {
- return session_type_ == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
- session_type_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH;
- }
-
- protected:
- uint16_t cookie_;
- BluetoothStreamState state_;
- SessionType_2_1 session_type_;
- // WR to support Mono: True if fetching Stereo and mixing into Mono
- bool is_stereo_to_mono_ = false;
- bool in_use() const;
-
- private:
- mutable std::mutex cv_mutex_;
- std::condition_variable internal_cv_;
-
- // Check and initialize session type for |devices| If failed, this
- // BluetoothAudioPort is not initialized and must be deleted.
- bool init_session_type(audio_devices_t device);
-
- bool CondwaitState(BluetoothStreamState state);
-
- void ControlResultHandler(
- const ::android::hardware::bluetooth::audio::V2_0::Status& status);
- void SessionChangedHandler();
-};
-
-class BluetoothAudioPortOut : public BluetoothAudioPort {
- public:
- ~BluetoothAudioPortOut() = default;
-
- // The audio data path to the Bluetooth stack (Software encoding)
- size_t WriteData(const void* buffer, size_t bytes) const;
- bool LoadAudioConfig(audio_config_t* audio_cfg) const;
-};
-
-class BluetoothAudioPortIn : public BluetoothAudioPort {
- public:
- ~BluetoothAudioPortIn() = default;
-
- // The audio data path from the Bluetooth stack (Software decoded)
- size_t ReadData(void* buffer, size_t bytes) const;
- bool LoadAudioConfig(audio_config_t* audio_cfg) const;
-};
-
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/audio_bluetooth_hw/stream_apis.cc b/audio_bluetooth_hw/stream_apis.cc
deleted file mode 100644
index f202d7bc..0000000
--- a/audio_bluetooth_hw/stream_apis.cc
+++ /dev/null
@@ -1,1216 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#define LOG_TAG "BTAudioHalStream"
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <cutils/properties.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <log/log.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "stream_apis.h"
-#include "utils.h"
-
-using ::android::base::StringPrintf;
-using ::android::bluetooth::audio::BluetoothAudioPortOut;
-using ::android::bluetooth::audio::utils::GetAudioParamString;
-using ::android::bluetooth::audio::utils::ParseAudioParams;
-
-namespace {
-
-constexpr unsigned int kMinimumDelayMs = 50;
-constexpr unsigned int kMaximumDelayMs = 1000;
-constexpr int kExtraAudioSyncMs = 200;
-
-std::ostream& operator<<(std::ostream& os, const audio_config& config) {
- return os << "audio_config[sample_rate=" << config.sample_rate
- << ", channels=" << StringPrintf("%#x", config.channel_mask)
- << ", format=" << config.format << "]";
-}
-
-void out_calculate_feeding_delay_ms(const BluetoothStreamOut* out,
- uint32_t* latency_ms,
- uint64_t* frames = nullptr,
- struct timespec* timestamp = nullptr) {
- if (latency_ms == nullptr && frames == nullptr && timestamp == nullptr) {
- return;
- }
-
- // delay_report is the audio delay from the remote headset receiving data to
- // the headset playing sound in units of nanoseconds
- uint64_t delay_report_ns = 0;
- uint64_t delay_report_ms = 0;
- // absorbed_bytes is the total number of bytes sent by the Bluetooth stack to
- // a remote headset
- uint64_t absorbed_bytes = 0;
- // absorbed_timestamp is the ...
- struct timespec absorbed_timestamp = {};
- bool timestamp_fetched = false;
-
- std::unique_lock<std::mutex> lock(out->mutex_);
- if (out->bluetooth_output_.GetPresentationPosition(
- &delay_report_ns, &absorbed_bytes, &absorbed_timestamp)) {
- delay_report_ms = delay_report_ns / 1000000;
- // assume kMinimumDelayMs (50ms) < delay_report_ns < kMaximumDelayMs
- // (1000ms), or it is invalid / ignored and use old delay calculated
- // by ourselves.
- if (delay_report_ms > kMinimumDelayMs &&
- delay_report_ms < kMaximumDelayMs) {
- timestamp_fetched = true;
- } else if (delay_report_ms >= kMaximumDelayMs) {
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", delay_report=" << delay_report_ns << "ns abnormal";
- }
- }
- if (!timestamp_fetched) {
- // default to old delay if any failure is found when fetching from ports
- // audio_a2dp_hw:
- // frames_count = buffer_size / frame_size
- // latency (sec.) = frames_count / samples_per_second (sample_rate)
- // Sync from audio_a2dp_hw to add extra delay kExtraAudioSyncMs(+200ms)
- delay_report_ms =
- out->frames_count_ * 1000 / out->sample_rate_ + kExtraAudioSyncMs;
- if (timestamp != nullptr) {
- clock_gettime(CLOCK_MONOTONIC, &absorbed_timestamp);
- }
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " uses the legacy delay " << delay_report_ms << " ms";
- }
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", delay=" << delay_report_ms << "ms, data=" << absorbed_bytes
- << " bytes, timestamp=" << absorbed_timestamp.tv_sec << "."
- << StringPrintf("%09ld", absorbed_timestamp.tv_nsec) << "s";
-
- if (latency_ms != nullptr) {
- *latency_ms = delay_report_ms;
- }
- if (frames != nullptr) {
- const uint64_t latency_frames = delay_report_ms * out->sample_rate_ / 1000;
- *frames = absorbed_bytes / audio_stream_out_frame_size(&out->stream_out_);
- if (out->frames_presented_ < *frames) {
- // Are we (the audio HAL) reset?! The stack counter is obsoleted.
- *frames = out->frames_presented_;
- } else if ((out->frames_presented_ - *frames) > latency_frames) {
- // Is the Bluetooth output reset / restarted by AVDTP reconfig?! Its
- // counter was reset but could not be used.
- *frames = out->frames_presented_;
- }
- // suppose frames would be queued in the headset buffer for delay_report
- // period, so those frames in buffers should not be included in the number
- // of presented frames at the timestamp.
- if (*frames > latency_frames) {
- *frames -= latency_frames;
- } else {
- *frames = 0;
- }
- }
- if (timestamp != nullptr) {
- *timestamp = absorbed_timestamp;
- }
-}
-
-void in_calculate_starving_delay_ms(const BluetoothStreamIn* in,
- int64_t* frames, int64_t* time) {
- // delay_report is the audio delay from the remote headset receiving data to
- // the headset playing sound in units of nanoseconds
- uint64_t delay_report_ns = 0;
- uint64_t delay_report_ms = 0;
- // dispersed_bytes is the total number of bytes received by the Bluetooth
- // stack from a remote headset
- uint64_t dispersed_bytes = 0;
- struct timespec dispersed_timestamp = {};
-
- std::unique_lock<std::mutex> lock(in->mutex_);
- in->bluetooth_input_.GetPresentationPosition(
- &delay_report_ns, &dispersed_bytes, &dispersed_timestamp);
- delay_report_ms = delay_report_ns / 1000000;
-
- const uint64_t latency_frames = delay_report_ms * in->sample_rate_ / 1000;
- *frames = dispersed_bytes / audio_stream_in_frame_size(&in->stream_in_);
-
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", delay=" << delay_report_ms
- << "ms, data=" << dispersed_bytes
- << " bytes, timestamp=" << dispersed_timestamp.tv_sec << "."
- << StringPrintf("%09ld", dispersed_timestamp.tv_nsec) << "s";
-
- if (in->frames_presented_ < *frames) {
- // Was audio HAL reset?! The stack counter is obsoleted.
- *frames = in->frames_presented_;
- } else if ((in->frames_presented_ - *frames) > latency_frames) {
- // Is the Bluetooth input reset ?! Its counter was reset but could not be
- // used.
- *frames = in->frames_presented_;
- }
- // suppose frames would be queued in the headset buffer for delay_report
- // period, so those frames in buffers should not be included in the number
- // of presented frames at the timestamp.
- if (*frames > latency_frames) {
- *frames -= latency_frames;
- } else {
- *frames = 0;
- }
-
- *time = (dispersed_timestamp.tv_sec * 1000000000LL +
- dispersed_timestamp.tv_nsec) /
- 1000;
-}
-
-} // namespace
-
-std::ostream& operator<<(std::ostream& os, const BluetoothStreamState& state) {
- switch (state) {
- case BluetoothStreamState::DISABLED:
- return os << "DISABLED";
- case BluetoothStreamState::STANDBY:
- return os << "STANDBY";
- case BluetoothStreamState::STARTING:
- return os << "STARTING";
- case BluetoothStreamState::STARTED:
- return os << "STARTED";
- case BluetoothStreamState::SUSPENDING:
- return os << "SUSPENDING";
- case BluetoothStreamState::UNKNOWN:
- return os << "UNKNOWN";
- default:
- return os << StringPrintf("%#hhx", state);
- }
-}
-
-static uint32_t out_get_sample_rate(const struct audio_stream* stream) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- audio_config_t audio_cfg;
- if (out->bluetooth_output_.LoadAudioConfig(&audio_cfg)) {
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " audio_cfg=" << audio_cfg;
- return audio_cfg.sample_rate;
- } else {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", sample_rate=" << out->sample_rate_ << " failed";
- return out->sample_rate_;
- }
-}
-
-static int out_set_sample_rate(struct audio_stream* stream, uint32_t rate) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", sample_rate=" << out->sample_rate_;
- return (rate == out->sample_rate_ ? 0 : -1);
-}
-
-static size_t out_get_buffer_size(const struct audio_stream* stream) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- size_t buffer_size =
- out->frames_count_ * audio_stream_out_frame_size(&out->stream_out_);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", buffer_size=" << buffer_size;
- return buffer_size;
-}
-
-static audio_channel_mask_t out_get_channels(
- const struct audio_stream* stream) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- audio_config_t audio_cfg;
- if (out->bluetooth_output_.LoadAudioConfig(&audio_cfg)) {
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " audio_cfg=" << audio_cfg;
- return audio_cfg.channel_mask;
- } else {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", channels=" << StringPrintf("%#x", out->channel_mask_) << " failure";
- return out->channel_mask_;
- }
-}
-
-static audio_format_t out_get_format(const struct audio_stream* stream) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- audio_config_t audio_cfg;
- if (out->bluetooth_output_.LoadAudioConfig(&audio_cfg)) {
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " audio_cfg=" << audio_cfg;
- return audio_cfg.format;
- } else {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", format=" << out->format_ << " failure";
- return out->format_;
- }
-}
-
-static int out_set_format(struct audio_stream* stream, audio_format_t format) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", format=" << out->format_;
- return (format == out->format_ ? 0 : -1);
-}
-
-static int out_standby(struct audio_stream* stream) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- std::unique_lock<std::mutex> lock(out->mutex_);
- int retval = 0;
-
- // out->last_write_time_us_ = 0; unnecessary as a stale write time has same
- // effect
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " being standby (suspend)";
- if (out->bluetooth_output_.GetState() == BluetoothStreamState::STARTED) {
- out->frames_rendered_ = 0;
- retval = (out->bluetooth_output_.Suspend() ? 0 : -EIO);
- } else if (out->bluetooth_output_.GetState() ==
- BluetoothStreamState::STARTING ||
- out->bluetooth_output_.GetState() ==
- BluetoothStreamState::SUSPENDING) {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " NOT ready to be standby";
- retval = -EBUSY;
- } else {
- LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " standby already";
- }
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " standby (suspend) retval=" << retval;
-
- return retval;
-}
-
-static int out_dump(const struct audio_stream* stream, int fd) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState();
- return 0;
-}
-
-static int out_set_parameters(struct audio_stream* stream,
- const char* kvpairs) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- std::unique_lock<std::mutex> lock(out->mutex_);
- int retval = 0;
-
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", kvpairs=[" << kvpairs << "]";
-
- std::unordered_map<std::string, std::string> params =
- ParseAudioParams(kvpairs);
- if (params.empty()) return retval;
-
- LOG(VERBOSE) << __func__ << ": ParamsMap=[" << GetAudioParamString(params)
- << "]";
-
- audio_config_t audio_cfg;
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES) != params.end() ||
- params.find(AUDIO_PARAMETER_STREAM_SUP_CHANNELS) != params.end() ||
- params.find(AUDIO_PARAMETER_STREAM_SUP_FORMATS) != params.end()) {
- if (out->bluetooth_output_.LoadAudioConfig(&audio_cfg)) {
- out->sample_rate_ = audio_cfg.sample_rate;
- out->channel_mask_ = audio_cfg.channel_mask;
- out->format_ = audio_cfg.format;
- LOG(VERBOSE) << "state=" << out->bluetooth_output_.GetState() << ", sample_rate=" << out->sample_rate_
- << ", channels=" << StringPrintf("%#x", out->channel_mask_) << ", format=" << out->format_;
- } else {
- LOG(WARNING) << __func__
- << ": state=" << out->bluetooth_output_.GetState()
- << " failed to get audio config";
- }
- }
-
- if (params.find("routing") != params.end()) {
- auto routing_param = params.find("routing");
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", stream param '" << routing_param->first.c_str() << "="
- << routing_param->second.c_str() << "'";
- }
-
- if (params.find("A2dpSuspended") != params.end() &&
- out->bluetooth_output_.IsA2dp()) {
- if (params["A2dpSuspended"] == "true") {
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " stream param stopped";
- out->frames_rendered_ = 0;
- if (out->bluetooth_output_.GetState() == BluetoothStreamState::STARTED) {
- out->bluetooth_output_.Suspend();
- out->bluetooth_output_.SetState(BluetoothStreamState::DISABLED);
- } else if (out->bluetooth_output_.GetState() !=
- BluetoothStreamState::DISABLED) {
- out->bluetooth_output_.Stop();
- }
- } else {
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " stream param standby";
- if (out->bluetooth_output_.GetState() == BluetoothStreamState::DISABLED) {
- out->bluetooth_output_.SetState(BluetoothStreamState::STANDBY);
- }
- }
- }
-
- if (params.find("closing") != params.end()) {
- if (params["closing"] == "true") {
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " stream param closing, disallow any writes?";
- if (out->bluetooth_output_.GetState() != BluetoothStreamState::DISABLED) {
- out->frames_rendered_ = 0;
- out->frames_presented_ = 0;
- out->bluetooth_output_.Stop();
- }
- }
- }
-
- if (params.find("exiting") != params.end()) {
- if (params["exiting"] == "1") {
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " stream param exiting";
- if (out->bluetooth_output_.GetState() != BluetoothStreamState::DISABLED) {
- out->frames_rendered_ = 0;
- out->frames_presented_ = 0;
- out->bluetooth_output_.Stop();
- }
- }
- }
-
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", kvpairs=[" << kvpairs << "], retval=" << retval;
- return retval;
-}
-
-static char* out_get_parameters(const struct audio_stream* stream,
- const char* keys) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- std::unique_lock<std::mutex> lock(out->mutex_);
-
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", keys=[" << keys << "]";
-
- std::unordered_map<std::string, std::string> params = ParseAudioParams(keys);
- if (params.empty()) return strdup("");
-
- audio_config_t audio_cfg;
- if (out->bluetooth_output_.LoadAudioConfig(&audio_cfg)) {
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " audio_cfg=" << audio_cfg;
- } else {
- LOG(ERROR) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " failed to get audio config";
- }
-
- std::unordered_map<std::string, std::string> return_params;
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES) != params.end()) {
- std::string param;
- if (audio_cfg.sample_rate == 16000) {
- param = "16000";
- }
- if (audio_cfg.sample_rate == 24000) {
- param = "24000";
- }
- if (audio_cfg.sample_rate == 44100) {
- param = "44100";
- }
- if (audio_cfg.sample_rate == 48000) {
- param = "48000";
- }
- if (audio_cfg.sample_rate == 88200) {
- param = "88200";
- }
- if (audio_cfg.sample_rate == 96000) {
- param = "96000";
- }
- if (audio_cfg.sample_rate == 176400) {
- param = "176400";
- }
- if (audio_cfg.sample_rate == 192000) {
- param = "192000";
- }
- return_params[AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES] = param;
- }
-
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_CHANNELS) != params.end()) {
- std::string param;
- if (audio_cfg.channel_mask == AUDIO_CHANNEL_OUT_MONO) {
- param = "AUDIO_CHANNEL_OUT_MONO";
- }
- if (audio_cfg.channel_mask == AUDIO_CHANNEL_OUT_STEREO) {
- param = "AUDIO_CHANNEL_OUT_STEREO";
- }
- return_params[AUDIO_PARAMETER_STREAM_SUP_CHANNELS] = param;
- }
-
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_FORMATS) != params.end()) {
- std::string param;
- if (audio_cfg.format == AUDIO_FORMAT_PCM_16_BIT) {
- param = "AUDIO_FORMAT_PCM_16_BIT";
- }
- if (audio_cfg.format == AUDIO_FORMAT_PCM_24_BIT_PACKED) {
- param = "AUDIO_FORMAT_PCM_24_BIT_PACKED";
- }
- if (audio_cfg.format == AUDIO_FORMAT_PCM_32_BIT) {
- param = "AUDIO_FORMAT_PCM_32_BIT";
- }
- return_params[AUDIO_PARAMETER_STREAM_SUP_FORMATS] = param;
- }
-
- std::string result;
- for (const auto& ptr : return_params) {
- result += ptr.first + "=" + ptr.second + ";";
- }
-
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", result=[" << result << "]";
- return strdup(result.c_str());
-}
-
-static uint32_t out_get_latency_ms(const struct audio_stream_out* stream) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- uint32_t latency_ms = 0;
- out_calculate_feeding_delay_ms(out, &latency_ms);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", latency=" << latency_ms << "ms";
- return latency_ms;
-}
-
-static int out_set_volume(struct audio_stream_out* stream, float left,
- float right) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", Left=" << left << ", Right=" << right;
- return -1;
-}
-
-static ssize_t out_write(struct audio_stream_out* stream, const void* buffer,
- size_t bytes) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- std::unique_lock<std::mutex> lock(out->mutex_);
- size_t totalWritten = 0;
-
- if (out->bluetooth_output_.GetState() != BluetoothStreamState::STARTED) {
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " first time bytes=" << bytes;
- lock.unlock();
- if (stream->resume(stream)) {
- LOG(ERROR) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " failed to resume";
- if (out->bluetooth_output_.GetState() == BluetoothStreamState::DISABLED) {
- // drop data for cases of A2dpSuspended=true / closing=true
- totalWritten = bytes;
- }
- usleep(kBluetoothDefaultOutputBufferMs * 1000);
- return totalWritten;
- }
- lock.lock();
- }
- lock.unlock();
- totalWritten = out->bluetooth_output_.WriteData(buffer, bytes);
- lock.lock();
-
- struct timespec ts = {.tv_sec = 0, .tv_nsec = 0};
- clock_gettime(CLOCK_MONOTONIC, &ts);
- if (totalWritten) {
- const size_t frames = bytes / audio_stream_out_frame_size(stream);
- out->frames_rendered_ += frames;
- out->frames_presented_ += frames;
- out->last_write_time_us_ = (ts.tv_sec * 1000000000LL + ts.tv_nsec) / 1000;
- } else {
- const int64_t now = (ts.tv_sec * 1000000000LL + ts.tv_nsec) / 1000;
- const int64_t elapsed_time_since_last_write =
- now - out->last_write_time_us_;
- // frames_count = written_data / frame_size
- // play_time (ms) = frames_count / (sample_rate (Sec.) / 1000000)
- // sleep_time (ms) = play_time - elapsed_time
- int64_t sleep_time = bytes * 1000000LL /
- audio_stream_out_frame_size(stream) /
- out_get_sample_rate(&stream->common) -
- elapsed_time_since_last_write;
- if (sleep_time > 0) {
- LOG(VERBOSE) << __func__ << ": sleep " << (sleep_time / 1000)
- << " ms when writting FMQ datapath";
- lock.unlock();
- usleep(sleep_time);
- lock.lock();
- } else {
- // we don't sleep when we exit standby (this is typical for a real alsa
- // buffer).
- sleep_time = 0;
- }
- out->last_write_time_us_ = now + sleep_time;
- }
- return totalWritten;
-}
-
-static int out_get_render_position(const struct audio_stream_out* stream,
- uint32_t* dsp_frames) {
- if (dsp_frames == nullptr) return -EINVAL;
-
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- // frames = (latency (ms) / 1000) * samples_per_second (sample_rate)
- const uint64_t latency_frames =
- (uint64_t)out_get_latency_ms(stream) * out->sample_rate_ / 1000;
- if (out->frames_rendered_ >= latency_frames) {
- *dsp_frames = (uint32_t)(out->frames_rendered_ - latency_frames);
- } else {
- *dsp_frames = 0;
- }
-
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", dsp_frames=" << *dsp_frames;
- return 0;
-}
-
-static int out_add_audio_effect(const struct audio_stream* stream,
- effect_handle_t effect) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", effect=" << effect;
- return 0;
-}
-
-static int out_remove_audio_effect(const struct audio_stream* stream,
- effect_handle_t effect) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", effect=" << effect;
- return 0;
-}
-
-static int out_get_next_write_timestamp(const struct audio_stream_out* stream,
- int64_t* timestamp) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- *timestamp = 0;
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", timestamp=" << *timestamp;
- return -EINVAL;
-}
-
-static int out_pause(struct audio_stream_out* stream) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- std::unique_lock<std::mutex> lock(out->mutex_);
- int retval = 0;
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", pausing (suspend)";
- if (out->bluetooth_output_.GetState() == BluetoothStreamState::STARTED) {
- out->frames_rendered_ = 0;
- retval = (out->bluetooth_output_.Suspend() ? 0 : -EIO);
- } else if (out->bluetooth_output_.GetState() ==
- BluetoothStreamState::STARTING ||
- out->bluetooth_output_.GetState() ==
- BluetoothStreamState::SUSPENDING) {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " NOT ready to pause?!";
- retval = -EBUSY;
- } else {
- LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " paused already";
- }
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", pausing (suspend) retval=" << retval;
-
- return retval;
-}
-
-static int out_resume(struct audio_stream_out* stream) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- std::unique_lock<std::mutex> lock(out->mutex_);
- int retval = 0;
-
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", resuming (start)";
- if (out->bluetooth_output_.GetState() == BluetoothStreamState::STANDBY) {
- retval = (out->bluetooth_output_.Start() ? 0 : -EIO);
- } else if (out->bluetooth_output_.GetState() ==
- BluetoothStreamState::STARTING ||
- out->bluetooth_output_.GetState() ==
- BluetoothStreamState::SUSPENDING) {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " NOT ready to resume?!";
- retval = -EBUSY;
- } else if (out->bluetooth_output_.GetState() ==
- BluetoothStreamState::DISABLED) {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " NOT allow to resume?!";
- retval = -EINVAL;
- } else {
- LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " resumed already";
- }
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", resuming (start) retval=" << retval;
-
- return retval;
-}
-
-static int out_get_presentation_position(const struct audio_stream_out* stream,
- uint64_t* frames,
- struct timespec* timestamp) {
- if (frames == nullptr || timestamp == nullptr) {
- return -EINVAL;
- }
-
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- out_calculate_feeding_delay_ms(out, nullptr, frames, timestamp);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", frames=" << *frames << ", timestamp=" << timestamp->tv_sec
- << "." << StringPrintf("%09ld", timestamp->tv_nsec) << "s";
- return 0;
-}
-
-static void out_update_source_metadata(
- struct audio_stream_out* stream,
- const struct source_metadata* source_metadata) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- std::unique_lock<std::mutex> lock(out->mutex_);
- if (source_metadata == nullptr || source_metadata->track_count == 0) {
- return;
- }
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", " << source_metadata->track_count << " track(s)";
- out->bluetooth_output_.UpdateMetadata(source_metadata);
-}
-
-static size_t samples_per_ticks(size_t milliseconds, uint32_t sample_rate,
- size_t channel_count) {
- return milliseconds * sample_rate * channel_count / 1000;
-}
-
-int adev_open_output_stream(struct audio_hw_device* dev,
- audio_io_handle_t handle, audio_devices_t devices,
- audio_output_flags_t flags,
- struct audio_config* config,
- struct audio_stream_out** stream_out,
- const char* address __unused) {
- *stream_out = nullptr;
- auto* out = new BluetoothStreamOut{};
- if (!out->bluetooth_output_.SetUp(devices)) {
- delete out;
- return -EINVAL;
- }
- LOG(VERBOSE) << __func__ << ": device=" << StringPrintf("%#x", devices);
-
- out->stream_out_.common.get_sample_rate = out_get_sample_rate;
- out->stream_out_.common.set_sample_rate = out_set_sample_rate;
- out->stream_out_.common.get_buffer_size = out_get_buffer_size;
- out->stream_out_.common.get_channels = out_get_channels;
- out->stream_out_.common.get_format = out_get_format;
- out->stream_out_.common.set_format = out_set_format;
- out->stream_out_.common.standby = out_standby;
- out->stream_out_.common.dump = out_dump;
- out->stream_out_.common.set_parameters = out_set_parameters;
- out->stream_out_.common.get_parameters = out_get_parameters;
- out->stream_out_.common.add_audio_effect = out_add_audio_effect;
- out->stream_out_.common.remove_audio_effect = out_remove_audio_effect;
- out->stream_out_.get_latency = out_get_latency_ms;
- out->stream_out_.set_volume = out_set_volume;
- out->stream_out_.write = out_write;
- out->stream_out_.get_render_position = out_get_render_position;
- out->stream_out_.get_next_write_timestamp = out_get_next_write_timestamp;
- out->stream_out_.pause = out_pause;
- out->stream_out_.resume = out_resume;
- out->stream_out_.get_presentation_position = out_get_presentation_position;
- out->stream_out_.update_source_metadata = out_update_source_metadata;
-
- if (!out->bluetooth_output_.LoadAudioConfig(config)) {
- LOG(ERROR) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " failed to get audio config";
- }
- // WAR to support Mono / 16 bits per sample as the Bluetooth stack required
- if (config->channel_mask == AUDIO_CHANNEL_OUT_MONO && config->format == AUDIO_FORMAT_PCM_16_BIT) {
- LOG(INFO) << __func__ << ": force channels=" << StringPrintf("%#x", out->channel_mask_)
- << " to be AUDIO_CHANNEL_OUT_STEREO";
- out->bluetooth_output_.ForcePcmStereoToMono(true);
- config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
- }
- out->sample_rate_ = config->sample_rate;
- out->channel_mask_ = config->channel_mask;
- out->format_ = config->format;
- // frame is number of samples per channel
- out->frames_count_ =
- samples_per_ticks(kBluetoothDefaultOutputBufferMs, out->sample_rate_, 1);
- out->frames_rendered_ = 0;
- out->frames_presented_ = 0;
-
- {
- auto* bluetooth_device = reinterpret_cast<BluetoothAudioDevice*>(dev);
- std::lock_guard<std::mutex> guard(bluetooth_device->mutex_);
- bluetooth_device->opened_stream_outs_.push_back(out);
- }
- *stream_out = &out->stream_out_;
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState() << ", sample_rate=" << out->sample_rate_
- << ", channels=" << StringPrintf("%#x", out->channel_mask_) << ", format=" << out->format_
- << ", frames=" << out->frames_count_;
- return 0;
-}
-
-void adev_close_output_stream(struct audio_hw_device* dev,
- struct audio_stream_out* stream) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", stopping";
- {
- auto* bluetooth_device = reinterpret_cast<BluetoothAudioDevice*>(dev);
- std::lock_guard<std::mutex> guard(bluetooth_device->mutex_);
- bluetooth_device->opened_stream_outs_.remove(out);
- }
- if (out->bluetooth_output_.GetState() != BluetoothStreamState::DISABLED) {
- out->frames_rendered_ = 0;
- out->frames_presented_ = 0;
- out->bluetooth_output_.Stop();
- }
- out->bluetooth_output_.TearDown();
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", stopped";
- delete out;
-}
-
-size_t adev_get_input_buffer_size(const struct audio_hw_device* dev,
- const struct audio_config* config) {
- /* TODO: Adjust this value */
- LOG(VERBOSE) << __func__;
- return 320;
-}
-
-static uint32_t in_get_sample_rate(const struct audio_stream* stream) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
-
- return in->sample_rate_;
-}
-
-static int in_set_sample_rate(struct audio_stream* stream, uint32_t rate) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
-
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", sample_rate=" << in->sample_rate_;
- return (rate == in->sample_rate_ ? 0 : -ENOSYS);
-}
-
-static size_t in_get_buffer_size(const struct audio_stream* stream) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- size_t buffer_size =
- in->frames_count_ * audio_stream_in_frame_size(&in->stream_in_);
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", buffer_size=" << buffer_size;
- return buffer_size;
-}
-
-static audio_channel_mask_t in_get_channels(const struct audio_stream* stream) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- audio_config_t audio_cfg;
- if (in->bluetooth_input_.LoadAudioConfig(&audio_cfg)) {
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " audio_cfg=" << audio_cfg;
- return audio_cfg.channel_mask;
- } else {
- LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", channels=" << StringPrintf("%#x", in->channel_mask_)
- << " failure";
- return in->channel_mask_;
- }
-}
-
-static audio_format_t in_get_format(const struct audio_stream* stream) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- audio_config_t audio_cfg;
- if (in->bluetooth_input_.LoadAudioConfig(&audio_cfg)) {
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " audio_cfg=" << audio_cfg;
- return audio_cfg.format;
- } else {
- LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", format=" << in->format_ << " failure";
- return in->format_;
- }
-}
-
-static int in_set_format(struct audio_stream* stream, audio_format_t format) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", format=" << in->format_;
- return (format == in->format_ ? 0 : -ENOSYS);
-}
-
-static bool in_state_transition_timeout(BluetoothStreamIn* in,
- std::unique_lock<std::mutex>& lock,
- const BluetoothStreamState& state,
- uint16_t timeout_ms) {
- /* Don't loose suspend request, AF will not retry */
- while (in->bluetooth_input_.GetState() == state) {
- lock.unlock();
- usleep(1000);
- lock.lock();
-
- /* Don't block AF forever */
- if (--timeout_ms <= 0) {
- LOG(WARNING) << __func__ << ", can't suspend - stucked in: "
- << static_cast<int>(state) << " state";
- return false;
- }
- }
-
- return true;
-}
-
-static int in_standby(struct audio_stream* stream) {
- auto* in = reinterpret_cast<BluetoothStreamIn*>(stream);
- std::unique_lock<std::mutex> lock(in->mutex_);
- int retval = 0;
-
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " being standby (suspend)";
-
- /* Give some time to start up */
- if (!in_state_transition_timeout(in, lock, BluetoothStreamState::STARTING,
- kBluetoothDefaultInputStateTimeoutMs)) {
- LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " NOT ready to by standby";
- return retval;
- }
-
- if (in->bluetooth_input_.GetState() == BluetoothStreamState::STARTED) {
- retval = (in->bluetooth_input_.Suspend() ? 0 : -EIO);
- } else if (in->bluetooth_input_.GetState() !=
- BluetoothStreamState::SUSPENDING) {
- LOG(DEBUG) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " standby already";
- return retval;
- }
-
- /* Give some time to suspend */
- if (!in_state_transition_timeout(in, lock, BluetoothStreamState::SUSPENDING,
- kBluetoothDefaultInputStateTimeoutMs)) {
- LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " NOT ready to by standby";
- return 0;
- }
-
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " standby (suspend) retval=" << retval;
-
- return retval;
-}
-
-static int in_dump(const struct audio_stream* stream, int fd) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState();
-
- return 0;
-}
-
-static int in_set_parameters(struct audio_stream* stream, const char* kvpairs) {
- auto* in = reinterpret_cast<BluetoothStreamIn*>(stream);
- std::unique_lock<std::mutex> lock(in->mutex_);
- int retval = 0;
-
- LOG(INFO) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState()
- << ", kvpairs=[" << kvpairs << "]";
-
- std::unordered_map<std::string, std::string> params =
- ParseAudioParams(kvpairs);
-
- if (params.empty()) return retval;
-
- LOG(INFO) << __func__ << ": ParamsMap=[" << GetAudioParamString(params)
- << "]";
-
- return retval;
-}
-
-static char* in_get_parameters(const struct audio_stream* stream,
- const char* keys) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- std::unique_lock<std::mutex> lock(in->mutex_);
-
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState()
- << ", keys=[" << keys << "]";
-
- std::unordered_map<std::string, std::string> params = ParseAudioParams(keys);
- if (params.empty()) return strdup("");
-
- audio_config_t audio_cfg;
- if (in->bluetooth_input_.LoadAudioConfig(&audio_cfg)) {
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " audio_cfg=" << audio_cfg;
- } else {
- LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " failed to get audio config";
- }
-
- std::unordered_map<std::string, std::string> return_params;
-
- /* TODO: Implement parameter getter */
-
- std::string result;
- for (const auto& ptr : return_params) {
- result += ptr.first + "=" + ptr.second + ";";
- }
-
- return strdup(result.c_str());
-}
-
-static int in_add_audio_effect(const struct audio_stream* stream,
- effect_handle_t effect) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", effect=" << effect;
- return 0;
-}
-
-static int in_remove_audio_effect(const struct audio_stream* stream,
- effect_handle_t effect) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", effect=" << effect;
- return 0;
-}
-
-static int in_set_gain(struct audio_stream_in* stream, float gain) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return 0;
-}
-
-static ssize_t in_read(struct audio_stream_in* stream, void* buffer,
- size_t bytes) {
- auto* in = reinterpret_cast<BluetoothStreamIn*>(stream);
- std::unique_lock<std::mutex> lock(in->mutex_);
- size_t totalRead = 0;
-
- /* Give some time to start up */
- if (!in_state_transition_timeout(in, lock, BluetoothStreamState::STARTING,
- kBluetoothDefaultInputStateTimeoutMs))
- return -EBUSY;
-
- if (in->bluetooth_input_.GetState() != BluetoothStreamState::STARTED) {
- LOG(INFO) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " first time bytes=" << bytes;
-
- int retval = 0;
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", starting";
- if (in->bluetooth_input_.GetState() == BluetoothStreamState::STANDBY) {
- retval = (in->bluetooth_input_.Start() ? 0 : -EIO);
- } else if (in->bluetooth_input_.GetState() ==
- BluetoothStreamState::SUSPENDING) {
- LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " NOT ready to start?!";
- retval = -EBUSY;
- } else if (in->bluetooth_input_.GetState() ==
- BluetoothStreamState::DISABLED) {
- LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " NOT allow to start?!";
- retval = -EINVAL;
- } else {
- LOG(DEBUG) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " started already";
- }
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", starting (start) retval=" << retval;
-
- if (retval) {
- LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " failed to start";
- return retval;
- }
- }
-
- lock.unlock();
- totalRead = in->bluetooth_input_.ReadData(buffer, bytes);
- lock.lock();
-
- struct timespec ts = {.tv_sec = 0, .tv_nsec = 0};
- clock_gettime(CLOCK_MONOTONIC, &ts);
- in->last_read_time_us_ = (ts.tv_sec * 1000000000LL + ts.tv_nsec) / 1000;
-
- const size_t frames = totalRead / audio_stream_in_frame_size(stream);
- in->frames_presented_ += frames;
-
- return totalRead;
-}
-
-static uint32_t in_get_input_frames_lost(struct audio_stream_in* stream) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return 0;
-}
-
-static int in_get_capture_position(const struct audio_stream_in* stream,
- int64_t* frames, int64_t* time) {
- if (stream == NULL || frames == NULL || time == NULL) {
- return -EINVAL;
- }
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
-
- if (in->bluetooth_input_.GetState() == BluetoothStreamState::STANDBY) {
- LOG(WARNING) << __func__ << ": state= " << in->bluetooth_input_.GetState();
- return -ENOSYS;
- }
-
- in_calculate_starving_delay_ms(in, frames, time);
-
- return 0;
-}
-
-static int in_start(const struct audio_stream_in* stream) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return 0;
-}
-
-static int in_stop(const struct audio_stream_in* stream) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return 0;
-}
-
-static int in_create_mmap_buffer(const struct audio_stream_in* stream,
- int32_t min_size_frames,
- struct audio_mmap_buffer_info* info) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return -ENOSYS;
-}
-
-static int in_get_mmap_position(const struct audio_stream_in* stream,
- struct audio_mmap_position* position) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return -ENOSYS;
-}
-
-static int in_get_active_microphones(
- const struct audio_stream_in* stream,
- struct audio_microphone_characteristic_t* mic_array, size_t* mic_count) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return -ENOSYS;
-}
-
-static int in_set_microphone_direction(const struct audio_stream_in* stream,
- audio_microphone_direction_t direction) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return -ENOSYS;
-}
-
-static int in_set_microphone_field_dimension(
- const struct audio_stream_in* stream, float zoom) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return -ENOSYS;
-}
-
-static void in_update_sink_metadata(struct audio_stream_in* stream,
- const struct sink_metadata* sink_metadata) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-}
-
-int adev_open_input_stream(struct audio_hw_device* dev,
- audio_io_handle_t handle, audio_devices_t devices,
- struct audio_config* config,
- struct audio_stream_in** stream_in,
- audio_input_flags_t flags __unused,
- const char* address __unused,
- audio_source_t source __unused) {
- *stream_in = nullptr;
- auto* in = new BluetoothStreamIn{};
- if (!in->bluetooth_input_.SetUp(devices)) {
- delete in;
- return -EINVAL;
- }
-
- LOG(INFO) << __func__ << ": device=" << StringPrintf("%#x", devices);
-
- in->stream_in_.common.get_sample_rate = in_get_sample_rate;
- in->stream_in_.common.set_sample_rate = in_set_sample_rate;
- in->stream_in_.common.get_buffer_size = in_get_buffer_size;
- in->stream_in_.common.get_channels = in_get_channels;
- in->stream_in_.common.get_format = in_get_format;
- in->stream_in_.common.set_format = in_set_format;
- in->stream_in_.common.standby = in_standby;
- in->stream_in_.common.dump = in_dump;
- in->stream_in_.common.set_parameters = in_set_parameters;
- in->stream_in_.common.get_parameters = in_get_parameters;
- in->stream_in_.common.add_audio_effect = in_add_audio_effect;
- in->stream_in_.common.remove_audio_effect = in_remove_audio_effect;
- in->stream_in_.set_gain = in_set_gain;
- in->stream_in_.read = in_read;
- in->stream_in_.get_input_frames_lost = in_get_input_frames_lost;
- in->stream_in_.get_capture_position = in_get_capture_position;
- in->stream_in_.start = in_start;
- in->stream_in_.stop = in_stop;
- in->stream_in_.create_mmap_buffer = in_create_mmap_buffer;
- in->stream_in_.get_mmap_position = in_get_mmap_position;
- in->stream_in_.get_active_microphones = in_get_active_microphones;
- in->stream_in_.set_microphone_direction = in_set_microphone_direction;
- in->stream_in_.set_microphone_field_dimension =
- in_set_microphone_field_dimension;
- in->stream_in_.update_sink_metadata = in_update_sink_metadata;
-
- if (!in->bluetooth_input_.LoadAudioConfig(config)) {
- LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " failed to get audio config";
- return -EINVAL;
- }
-
- in->sample_rate_ = config->sample_rate;
- in->channel_mask_ = config->channel_mask;
- in->format_ = config->format;
- // frame is number of samples per channel
- in->frames_count_ =
- samples_per_ticks(kBluetoothDefaultInputBufferMs, in->sample_rate_, 1);
- in->frames_presented_ = 0;
-
- *stream_in = &in->stream_in_;
- LOG(INFO) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", sample_rate=" << in->sample_rate_
- << ", channels=" << StringPrintf("%#x", in->channel_mask_)
- << ", format=" << in->format_ << ", frames=" << in->frames_count_;
-
- return 0;
-}
-
-void adev_close_input_stream(struct audio_hw_device* dev,
- struct audio_stream_in* stream) {
- auto* in = reinterpret_cast<BluetoothStreamIn*>(stream);
-
- if (in->bluetooth_input_.GetState() != BluetoothStreamState::DISABLED) {
- in->bluetooth_input_.Stop();
- }
-
- in->bluetooth_input_.TearDown();
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", stopped";
-
- delete in;
-}
diff --git a/audio_bluetooth_hw/stream_apis.h b/audio_bluetooth_hw/stream_apis.h
deleted file mode 100644
index ae1a842..0000000
--- a/audio_bluetooth_hw/stream_apis.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#pragma once
-
-#include <hardware/audio.h>
-#include <system/audio.h>
-#include <list>
-
-#include "device_port_proxy.h"
-
-constexpr unsigned int kBluetoothDefaultSampleRate = 44100;
-constexpr audio_format_t kBluetoothDefaultAudioFormatBitsPerSample =
- AUDIO_FORMAT_PCM_16_BIT;
-
-constexpr unsigned int kBluetoothDefaultInputBufferMs = 20;
-constexpr unsigned int kBluetoothDefaultInputStateTimeoutMs = 20;
-
-constexpr unsigned int kBluetoothDefaultOutputBufferMs = 2;
-constexpr audio_channel_mask_t kBluetoothDefaultOutputChannelModeMask =
- AUDIO_CHANNEL_OUT_STEREO;
-constexpr audio_channel_mask_t kBluetoothDefaultInputChannelModeMask =
- AUDIO_CHANNEL_IN_MONO;
-
-enum class BluetoothStreamState : uint8_t {
- DISABLED = 0, // This stream is closing or set param "suspend=true"
- STANDBY,
- STARTING,
- STARTED,
- SUSPENDING,
- UNKNOWN,
-};
-
-std::ostream& operator<<(std::ostream& os, const BluetoothStreamState& state);
-
-struct BluetoothStreamOut {
- // Must be the first member so it can be cast from audio_stream
- // or audio_stream_out pointer
- audio_stream_out stream_out_{};
- ::android::bluetooth::audio::BluetoothAudioPortOut bluetooth_output_;
- int64_t last_write_time_us_;
- // Audio PCM Configs
- uint32_t sample_rate_;
- audio_channel_mask_t channel_mask_;
- audio_format_t format_;
- // frame is the number of samples per channel
- // frames count per tick
- size_t frames_count_;
- // total frames written, reset on standby
- uint64_t frames_rendered_;
- // total frames written after opened, never reset
- uint64_t frames_presented_;
- mutable std::mutex mutex_;
-};
-
-struct BluetoothAudioDevice {
- // Important: device must be first as an audio_hw_device* may be cast to
- // BluetoothAudioDevice* when the type is implicitly known.
- audio_hw_device audio_device_{};
- // protect against device->output and stream_out from being inconsistent
- std::mutex mutex_;
- std::list<BluetoothStreamOut*> opened_stream_outs_ =
- std::list<BluetoothStreamOut*>(0);
-};
-
-struct BluetoothStreamIn {
- // Must be the first member so it can be cast from audio_stream
- // or audio_stream_in pointer
- audio_stream_in stream_in_;
- ::android::bluetooth::audio::BluetoothAudioPortIn bluetooth_input_;
- int64_t last_read_time_us_;
- // Audio PCM Configs
- uint32_t sample_rate_;
- audio_channel_mask_t channel_mask_;
- audio_format_t format_;
- // frame is the number of samples per channel
- // frames count per tick
- size_t frames_count_;
- // total frames read after opened, never reset
- uint64_t frames_presented_;
- mutable std::mutex mutex_;
-};
-
-int adev_open_output_stream(struct audio_hw_device* dev,
- audio_io_handle_t handle, audio_devices_t devices,
- audio_output_flags_t flags,
- struct audio_config* config,
- struct audio_stream_out** stream_out,
- const char* address __unused);
-
-void adev_close_output_stream(struct audio_hw_device* dev,
- struct audio_stream_out* stream);
-
-size_t adev_get_input_buffer_size(const struct audio_hw_device* dev,
- const struct audio_config* config);
-
-int adev_open_input_stream(struct audio_hw_device* dev,
- audio_io_handle_t handle, audio_devices_t devices,
- struct audio_config* config,
- struct audio_stream_in** stream_in,
- audio_input_flags_t flags __unused,
- const char* address __unused,
- audio_source_t source __unused);
-
-void adev_close_input_stream(struct audio_hw_device* dev,
- struct audio_stream_in* in);
diff --git a/audio_bluetooth_hw/utils.cc b/audio_bluetooth_hw/utils.cc
deleted file mode 100644
index b3ac7a5..0000000
--- a/audio_bluetooth_hw/utils.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#define LOG_TAG "BTAudioHalUtils"
-
-#include "utils.h"
-
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-#include <log/log.h>
-#include <stdlib.h>
-#include <sstream>
-#include <vector>
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-namespace utils {
-
-std::unordered_map<std::string, std::string> ParseAudioParams(
- const std::string& params) {
- std::vector<std::string> segments = android::base::Split(params, ";");
- std::unordered_map<std::string, std::string> params_map;
- for (const auto& segment : segments) {
- if (segment.length() == 0) {
- continue;
- }
- std::vector<std::string> kv = android::base::Split(segment, "=");
- if (kv[0].empty()) {
- LOG(WARNING) << __func__ << ": Invalid audio parameter " << segment;
- continue;
- }
- params_map[kv[0]] = (kv.size() > 1 ? kv[1] : "");
- }
- return params_map;
-}
-
-std::string GetAudioParamString(
- std::unordered_map<std::string, std::string>& params_map) {
- std::ostringstream sout;
- for (const auto& ptr : params_map) {
- sout << "key: '" << ptr.first << "' value: '" << ptr.second << "'\n";
- }
- return sout.str();
-}
-
-} // namespace utils
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/audio_bluetooth_hw/utils.h b/audio_bluetooth_hw/utils.h
deleted file mode 100644
index 817a432..0000000
--- a/audio_bluetooth_hw/utils.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#pragma once
-
-#include <string>
-#include <unordered_map>
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-namespace utils {
-
-// Creates a hash map based on the |params| string containing key and value
-// pairs. Pairs are expected in the form "key=value" separated by the ';'
-// character. Both ';' and '=' characters are invalid in keys or values.
-// Examples:
-// "key0" -> map: [key0]=""
-// "key0=value0;key1=value1;" -> map: [key0]="value0" [key1]="value1"
-// "key0=;key1=value1;" -> map: [key0]="" [key1]="value1"
-// "=value0;key1=value1;" -> map: [key1]="value1"
-std::unordered_map<std::string, std::string> ParseAudioParams(
- const std::string& params);
-
-// Dumps the contents of the hash_map to the log for debugging purposes.
-// If |map| is not NULL, all entries of |map| will be dumped, otherwise
-// nothing will be dumped. Note that this function does not take the ownership
-// of the |map|.
-std::string GetAudioParamString(
- std::unordered_map<std::string, std::string>& params_map);
-
-} // namespace utils
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/audio_bluetooth_hw/utils_unittest.cc b/audio_bluetooth_hw/utils_unittest.cc
deleted file mode 100644
index 665dea6..0000000
--- a/audio_bluetooth_hw/utils_unittest.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#include <gtest/gtest.h>
-#include <unordered_map>
-
-#include "utils.h"
-
-namespace {
-
-using ::android::bluetooth::audio::utils::ParseAudioParams;
-
-class UtilsTest : public testing::Test {
- protected:
- void SetUp() override {}
- void TearDown() override { map_.clear(); }
-
- std::unordered_map<std::string, std::string> map_;
-};
-
-TEST_F(UtilsTest, HashMapEmptyParams) {
- std::string params = "";
- map_ = ParseAudioParams(params);
- // map = {}
- EXPECT_TRUE(map_.empty());
-}
-
-TEST_F(UtilsTest, HashMapDelimitOnly) {
- std::string params = ";";
- map_ = ParseAudioParams(params);
- // map = {}
- EXPECT_TRUE(map_.empty());
-}
-
-TEST_F(UtilsTest, HashMapNotKeyValuePair) {
- std::string params = "key0";
- map_ = ParseAudioParams(params);
- // map = {[key0]=""}
- EXPECT_EQ(map_.size(), 1);
- EXPECT_NE(map_.find("key0"), map_.end());
- EXPECT_EQ(map_["key0"].length(), 0);
-}
-
-TEST_F(UtilsTest, HashMapEmptyValue) {
- std::string params = "key0=";
- map_ = ParseAudioParams(params);
- // map = {[key0]=""}
- EXPECT_EQ(map_.size(), 1);
- EXPECT_NE(map_.find("key0"), map_.end());
- EXPECT_EQ(map_["key0"].length(), 0);
-}
-
-TEST_F(UtilsTest, HashMapEmptyValueWithDelimit) {
- std::string params = "key0=;";
- map_ = ParseAudioParams(params);
- // map = {[key0]=""}
- EXPECT_EQ(map_.size(), 1);
- EXPECT_NE(map_.find("key0"), map_.end());
- EXPECT_EQ(map_["key0"].length(), 0);
-}
-
-TEST_F(UtilsTest, HashMapOneKeyValuePair) {
- std::string params = "key0=value0";
- map_ = ParseAudioParams(params);
- // map = {[key0]="value0"}
- EXPECT_EQ(map_.size(), 1);
- EXPECT_EQ(map_["key0"], "value0");
-}
-
-TEST_F(UtilsTest, HashMapOneKeyValuePairWithDelimit) {
- std::string params = "key0=value0;";
- map_ = ParseAudioParams(params);
- // map = {[key0]="value0"}
- EXPECT_EQ(map_.size(), 1);
- EXPECT_EQ(map_["key0"], "value0");
-}
-
-TEST_F(UtilsTest, HashMapTwoKeyValuePairs) {
- std::string params = "key0=value0;key1=value1";
- map_ = ParseAudioParams(params);
- // map = {[key0]="value0", [key1]="value1"}
- EXPECT_EQ(map_.size(), 2);
- EXPECT_EQ(map_["key0"], "value0");
- EXPECT_EQ(map_["key1"], "value1");
-}
-
-TEST_F(UtilsTest, HashMapEmptyKey) {
- std::string params = "=value";
- map_ = ParseAudioParams(params);
- // map = {}
- EXPECT_TRUE(map_.empty());
-}
-
-TEST_F(UtilsTest, HashMapEmptyKeyWithDelimit) {
- std::string params = "=value;";
- map_ = ParseAudioParams(params);
- // map = {}
- EXPECT_TRUE(map_.empty());
-}
-
-TEST_F(UtilsTest, HashMapEquivalentOnly) {
- std::string params = "=";
- map_ = ParseAudioParams(params);
- // map = {}
- EXPECT_TRUE(map_.empty());
-}
-
-TEST_F(UtilsTest, HashMapNoKeyValuePair) {
- std::string params = "=;";
- map_ = ParseAudioParams(params);
- // map = {}
- EXPECT_TRUE(map_.empty());
-}
-
-TEST_F(UtilsTest, HashMapTwoPairsWithFirstKeyEmpty) {
- std::string params = "=value0;key1=value1";
- map_ = ParseAudioParams(params);
- // map = {[key1]="value1"}
- EXPECT_EQ(map_.size(), 1);
- EXPECT_EQ(map_["key1"], "value1");
-}
-
-} // namespace
diff --git a/audio_hal_interface/Android.bp b/audio_hal_interface/Android.bp
deleted file mode 100644
index c41ad16..0000000
--- a/audio_hal_interface/Android.bp
+++ /dev/null
@@ -1,87 +0,0 @@
-// Bluetooth Audio library for target
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-cc_library_static {
- name: "libbt-audio-hal-interface",
- defaults: ["fluoride_defaults"],
- include_dirs: [
- "system/bt",
- "system/bt/gd",
- "system/bt/bta/include",
- "system/bt/bta/sys",
- "system/bt/btif/include",
- "system/bt/stack/include",
- "system/bt/gd/rust/shim",
- ],
- shared_libs: [
- "android.hardware.bluetooth.audio@2.0",
- "android.hardware.bluetooth.audio@2.1",
- "libhidlbase",
- ],
- static_libs: [
- "libosi",
- "libbt-common",
- ],
- target: {
- android: {
- shared_libs: [
- "libfmq",
- ],
- srcs: [
- "a2dp_encoding.cc",
- "client_interface.cc",
- "codec_status.cc",
- "hearing_aid_software_encoding.cc",
- "le_audio_software.cc",
- ],
- },
- host: {
- srcs: [
- "a2dp_encoding_host.cc",
- "hearing_aid_software_encoding_host.cc",
- "le_audio_software_host.cc",
- ],
- },
- },
- host_supported: true,
- cflags: [
- "-DBUILDCFG",
- ],
-}
-
-// Bluetooth Audio client interface library unit tests for target and host
-cc_test {
- name: "bluetooth-test-audio-hal-interface",
- defaults: ["fluoride_defaults"],
- include_dirs: [
- "system/bt",
- "system/bt/gd",
- "system/bt/stack/include",
- ],
- srcs: [
- "client_interface_unittest.cc",
- ],
- shared_libs: [
- "android.hardware.bluetooth.audio@2.0",
- "android.hardware.bluetooth.audio@2.1",
- "libcutils",
- "libfmq",
- "libhidlbase",
- "liblog",
- "libutils",
- ],
- static_libs: [
- "libbt-audio-hal-interface",
- "libbt-common",
- ],
- cflags: [
- "-DBUILDCFG",
- ],
-}
diff --git a/audio_hal_interface/BUILD.gn b/audio_hal_interface/BUILD.gn
deleted file mode 100644
index 31e3856..0000000
--- a/audio_hal_interface/BUILD.gn
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Copyright 2021 Google, Inc.
-#
-# 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.
-#
-
-static_library("audio_hal_interface") {
- sources = [
- "a2dp_encoding_host.cc",
- "hearing_aid_software_encoding_host.cc",
- ]
-
- include_dirs = [
- "//bt/bta/include",
- "//bt/btif/include",
- "//bt/internal_include",
- "//bt/stack/include",
- "//bt/gd/rust/shim",
- ]
-
- configs += [ "//bt:target_defaults" ]
-
- deps = [
- "//bt/common",
- "//bt/osi:osi",
- ]
-}
diff --git a/audio_hal_interface/a2dp_encoding.cc b/audio_hal_interface/a2dp_encoding.cc
deleted file mode 100644
index abfa943..0000000
--- a/audio_hal_interface/a2dp_encoding.cc
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * Copyright 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.
- */
-#define LOG_TAG "a2dp_encoding"
-
-#include "a2dp_encoding.h"
-
-#include "a2dp_sbc_constants.h"
-#include "btif_a2dp_source.h"
-#include "btif_av.h"
-#include "btif_av_co.h"
-#include "btif_hf.h"
-#include "client_interface.h"
-#include "codec_status.h"
-#include "osi/include/log.h"
-#include "osi/include/properties.h"
-#include "types/raw_address.h"
-
-namespace {
-
-using ::bluetooth::audio::AudioCapabilities;
-using ::bluetooth::audio::AudioConfiguration;
-using ::bluetooth::audio::BitsPerSample;
-using ::bluetooth::audio::BluetoothAudioCtrlAck;
-using ::bluetooth::audio::ChannelMode;
-using ::bluetooth::audio::PcmParameters;
-using ::bluetooth::audio::SampleRate;
-using ::bluetooth::audio::SessionType;
-
-using ::bluetooth::audio::BluetoothAudioSinkClientInterface;
-using ::bluetooth::audio::codec::A2dpAacToHalConfig;
-using ::bluetooth::audio::codec::A2dpAptxToHalConfig;
-using ::bluetooth::audio::codec::A2dpCodecToHalBitsPerSample;
-using ::bluetooth::audio::codec::A2dpCodecToHalChannelMode;
-using ::bluetooth::audio::codec::A2dpCodecToHalSampleRate;
-using ::bluetooth::audio::codec::A2dpLdacToHalConfig;
-using ::bluetooth::audio::codec::A2dpSbcToHalConfig;
-using ::bluetooth::audio::codec::CodecConfiguration;
-
-BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(tA2DP_CTRL_ACK ack);
-
-// Provide call-in APIs for the Bluetooth Audio HAL
-class A2dpTransport
- : public ::bluetooth::audio::IBluetoothSinkTransportInstance {
- public:
- A2dpTransport(SessionType sessionType)
- : IBluetoothSinkTransportInstance(sessionType, {}),
- total_bytes_read_(0),
- data_position_({}) {
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
- remote_delay_report_ = 0;
- }
-
- BluetoothAudioCtrlAck StartRequest() override {
- // Check if a previous request is not finished
- if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_START) {
- LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_START in progress";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_PENDING);
- } else if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
- LOG(WARNING) << __func__ << ": busy in pending_cmd=" << a2dp_pending_cmd_;
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
- }
-
- // Don't send START request to stack while we are in a call
- if (!bluetooth::headset::IsCallIdle()) {
- LOG(ERROR) << __func__ << ": call state is busy";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_INCALL_FAILURE);
- }
-
- if (btif_av_stream_started_ready()) {
- // Already started, ACK back immediately.
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
- }
- if (btif_av_stream_ready()) {
- /*
- * Post start event and wait for audio path to open.
- * If we are the source, the ACK will be sent after the start
- * procedure is completed, othewise send it now.
- */
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_START;
- btif_av_stream_start();
- if (btif_av_get_peer_sep() != AVDT_TSEP_SRC) {
- LOG(INFO) << __func__ << ": accepted";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_PENDING);
- }
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
- }
- LOG(ERROR) << __func__ << ": AV stream is not ready to start";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
- }
-
- BluetoothAudioCtrlAck SuspendRequest() override {
- // Previous request is not finished
- if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_SUSPEND) {
- LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_SUSPEND in progress";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_PENDING);
- } else if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
- LOG(WARNING) << __func__ << ": busy in pending_cmd=" << a2dp_pending_cmd_;
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
- }
- // Local suspend
- if (btif_av_stream_started_ready()) {
- LOG(INFO) << __func__ << ": accepted";
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_SUSPEND;
- btif_av_stream_suspend();
- return BluetoothAudioCtrlAck::PENDING;
- }
- /* If we are not in started state, just ack back ok and let
- * audioflinger close the channel. This can happen if we are
- * remotely suspended, clear REMOTE SUSPEND flag.
- */
- btif_av_clear_remote_suspend_flag();
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
- }
-
- void StopRequest() override {
- if (btif_av_get_peer_sep() == AVDT_TSEP_SNK &&
- !btif_av_stream_started_ready()) {
- btif_av_clear_remote_suspend_flag();
- return;
- }
- LOG(INFO) << __func__ << ": handling";
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_STOP;
- btif_av_stream_stop(RawAddress::kEmpty);
- }
-
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_read,
- timespec* data_position) override {
- *remote_delay_report_ns = remote_delay_report_ * 100000u;
- *total_bytes_read = total_bytes_read_;
- *data_position = data_position_;
- VLOG(2) << __func__ << ": delay=" << remote_delay_report_
- << "/10ms, data=" << total_bytes_read_
- << " byte(s), timestamp=" << data_position_.tv_sec << "."
- << data_position_.tv_nsec << "s";
- return true;
- }
-
- void MetadataChanged(const source_metadata_t& source_metadata) override {
- auto track_count = source_metadata.track_count;
- auto tracks = source_metadata.tracks;
- VLOG(1) << __func__ << ": " << track_count << " track(s) received";
- while (track_count) {
- VLOG(2) << __func__ << ": usage=" << tracks->usage
- << ", content_type=" << tracks->content_type
- << ", gain=" << tracks->gain;
- --track_count;
- ++tracks;
- }
- }
-
- tA2DP_CTRL_CMD GetPendingCmd() const { return a2dp_pending_cmd_; }
-
- void ResetPendingCmd() { a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE; }
-
- void ResetPresentationPosition() override {
- remote_delay_report_ = 0;
- total_bytes_read_ = 0;
- data_position_ = {};
- }
-
- void LogBytesRead(size_t bytes_read) override {
- if (bytes_read != 0) {
- total_bytes_read_ += bytes_read;
- clock_gettime(CLOCK_MONOTONIC, &data_position_);
- }
- }
-
- // delay reports from AVDTP is based on 1/10 ms (100us)
- void SetRemoteDelay(uint16_t delay_report) {
- remote_delay_report_ = delay_report;
- }
-
- private:
- static tA2DP_CTRL_CMD a2dp_pending_cmd_;
- static uint16_t remote_delay_report_;
- uint64_t total_bytes_read_;
- timespec data_position_;
-};
-
-tA2DP_CTRL_CMD A2dpTransport::a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
-uint16_t A2dpTransport::remote_delay_report_ = 0;
-
-// Common interface to call-out into Bluetooth Audio HAL
-BluetoothAudioSinkClientInterface* software_hal_interface = nullptr;
-BluetoothAudioSinkClientInterface* offloading_hal_interface = nullptr;
-BluetoothAudioSinkClientInterface* active_hal_interface = nullptr;
-
-// Save the value if the remote reports its delay before this interface is
-// initialized
-uint16_t remote_delay = 0;
-
-bool btaudio_a2dp_disabled = false;
-bool is_configured = false;
-
-BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(tA2DP_CTRL_ACK ack) {
- switch (ack) {
- case A2DP_CTRL_ACK_SUCCESS:
- return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- case A2DP_CTRL_ACK_PENDING:
- return BluetoothAudioCtrlAck::PENDING;
- case A2DP_CTRL_ACK_INCALL_FAILURE:
- return BluetoothAudioCtrlAck::FAILURE_BUSY;
- case A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS:
- return BluetoothAudioCtrlAck::FAILURE_DISCONNECTING;
- case A2DP_CTRL_ACK_UNSUPPORTED: /* Offloading but resource failure */
- return BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED;
- case A2DP_CTRL_ACK_FAILURE:
- return BluetoothAudioCtrlAck::FAILURE;
- default:
- return BluetoothAudioCtrlAck::FAILURE;
- }
-}
-
-bool a2dp_get_selected_hal_codec_config(CodecConfiguration* codec_config) {
- A2dpCodecConfig* a2dp_config = bta_av_get_a2dp_current_codec();
- if (a2dp_config == nullptr) {
- LOG(WARNING) << __func__ << ": failure to get A2DP codec config";
- *codec_config = ::bluetooth::audio::codec::kInvalidCodecConfiguration;
- return false;
- }
- btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
- switch (current_codec.codec_type) {
- case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
- [[fallthrough]];
- case BTAV_A2DP_CODEC_INDEX_SINK_SBC: {
- if (!A2dpSbcToHalConfig(codec_config, a2dp_config)) {
- return false;
- }
- break;
- }
- case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
- [[fallthrough]];
- case BTAV_A2DP_CODEC_INDEX_SINK_AAC: {
- if (!A2dpAacToHalConfig(codec_config, a2dp_config)) {
- return false;
- }
- break;
- }
- case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
- [[fallthrough]];
- case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD: {
- if (!A2dpAptxToHalConfig(codec_config, a2dp_config)) {
- return false;
- }
- break;
- }
- case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC: {
- if (!A2dpLdacToHalConfig(codec_config, a2dp_config)) {
- return false;
- }
- break;
- }
- case BTAV_A2DP_CODEC_INDEX_MAX:
- [[fallthrough]];
- default:
- LOG(ERROR) << __func__
- << ": Unknown codec_type=" << current_codec.codec_type;
- *codec_config = ::bluetooth::audio::codec::kInvalidCodecConfiguration;
- return false;
- }
- codec_config->encodedAudioBitrate = a2dp_config->getTrackBitRate();
- // Obtain the MTU
- RawAddress peer_addr = btif_av_source_active_peer();
- tA2DP_ENCODER_INIT_PEER_PARAMS peer_param;
- bta_av_co_get_peer_params(peer_addr, &peer_param);
- int effectiveMtu = bta_av_co_get_encoder_effective_frame_size();
- if (effectiveMtu > 0 && effectiveMtu < peer_param.peer_mtu) {
- codec_config->peerMtu = effectiveMtu;
- } else {
- codec_config->peerMtu = peer_param.peer_mtu;
- }
- if (current_codec.codec_type == BTAV_A2DP_CODEC_INDEX_SOURCE_SBC &&
- codec_config->config.sbcConfig().maxBitpool <=
- A2DP_SBC_BITPOOL_MIDDLE_QUALITY) {
- codec_config->peerMtu = MAX_2MBPS_AVDTP_MTU;
- } else if (codec_config->peerMtu > MAX_3MBPS_AVDTP_MTU) {
- codec_config->peerMtu = MAX_3MBPS_AVDTP_MTU;
- }
- LOG(INFO) << __func__ << ": CodecConfiguration=" << toString(*codec_config);
- return true;
-}
-
-bool a2dp_get_selected_hal_pcm_config(PcmParameters* pcm_config) {
- if (pcm_config == nullptr) return false;
- A2dpCodecConfig* a2dp_codec_configs = bta_av_get_a2dp_current_codec();
- if (a2dp_codec_configs == nullptr) {
- LOG(WARNING) << __func__ << ": failure to get A2DP codec config";
- *pcm_config = BluetoothAudioSinkClientInterface::kInvalidPcmConfiguration;
- return false;
- }
-
- btav_a2dp_codec_config_t current_codec = a2dp_codec_configs->getCodecConfig();
- pcm_config->sampleRate = A2dpCodecToHalSampleRate(current_codec);
- pcm_config->bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
- pcm_config->channelMode = A2dpCodecToHalChannelMode(current_codec);
- return (pcm_config->sampleRate != SampleRate::RATE_UNKNOWN &&
- pcm_config->bitsPerSample != BitsPerSample::BITS_UNKNOWN &&
- pcm_config->channelMode != ChannelMode::UNKNOWN);
-}
-
-// Checking if new bluetooth_audio is supported
-bool is_hal_2_0_force_disabled() {
- if (!is_configured) {
- btaudio_a2dp_disabled = osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false);
- is_configured = true;
- }
- return btaudio_a2dp_disabled;
-}
-} // namespace
-
-namespace bluetooth {
-namespace audio {
-namespace a2dp {
-
-bool update_codec_offloading_capabilities(
- const std::vector<btav_a2dp_codec_config_t>& framework_preference) {
- return ::bluetooth::audio::codec::UpdateOffloadingCapabilities(
- framework_preference);
-}
-
-// Checking if new bluetooth_audio is enabled
-bool is_hal_2_0_enabled() { return active_hal_interface != nullptr; }
-
-// Check if new bluetooth_audio is running with offloading encoders
-bool is_hal_2_0_offloading() {
- if (!is_hal_2_0_enabled()) {
- return false;
- }
- return active_hal_interface->GetTransportInstance()->GetSessionType() ==
- SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH;
-}
-
-// Initialize BluetoothAudio HAL: openProvider
-bool init(bluetooth::common::MessageLoopThread* message_loop) {
- LOG(INFO) << __func__;
-
- if (is_hal_2_0_force_disabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is disabled";
- return false;
- }
-
- auto a2dp_sink =
- new A2dpTransport(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
- software_hal_interface =
- new BluetoothAudioSinkClientInterface(a2dp_sink, message_loop);
- if (!software_hal_interface->IsValid()) {
- LOG(WARNING) << __func__ << ": BluetoothAudio HAL for A2DP is invalid?!";
- delete software_hal_interface;
- software_hal_interface = nullptr;
- delete a2dp_sink;
- return false;
- }
-
- if (btif_av_is_a2dp_offload_enabled()) {
- a2dp_sink = new A2dpTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- offloading_hal_interface =
- new BluetoothAudioSinkClientInterface(a2dp_sink, message_loop);
- if (!offloading_hal_interface->IsValid()) {
- LOG(FATAL) << __func__
- << ": BluetoothAudio HAL for A2DP offloading is invalid?!";
- delete offloading_hal_interface;
- offloading_hal_interface = nullptr;
- delete a2dp_sink;
- a2dp_sink = static_cast<A2dpTransport*>(
- software_hal_interface->GetTransportInstance());
- delete software_hal_interface;
- software_hal_interface = nullptr;
- delete a2dp_sink;
- return false;
- }
- }
-
- active_hal_interface =
- (offloading_hal_interface != nullptr ? offloading_hal_interface
- : software_hal_interface);
-
- if (remote_delay != 0) {
- LOG(INFO) << __func__ << ": restore DELAY "
- << static_cast<float>(remote_delay / 10.0) << " ms";
- static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance())
- ->SetRemoteDelay(remote_delay);
- remote_delay = 0;
- }
- return true;
-}
-
-// Clean up BluetoothAudio HAL
-void cleanup() {
- if (!is_hal_2_0_enabled()) return;
- end_session();
-
- auto a2dp_sink = active_hal_interface->GetTransportInstance();
- static_cast<A2dpTransport*>(a2dp_sink)->ResetPendingCmd();
- static_cast<A2dpTransport*>(a2dp_sink)->ResetPresentationPosition();
- active_hal_interface = nullptr;
-
- a2dp_sink = software_hal_interface->GetTransportInstance();
- delete software_hal_interface;
- software_hal_interface = nullptr;
- delete a2dp_sink;
- if (offloading_hal_interface != nullptr) {
- a2dp_sink = offloading_hal_interface->GetTransportInstance();
- delete offloading_hal_interface;
- offloading_hal_interface = nullptr;
- delete a2dp_sink;
- }
-
- remote_delay = 0;
-}
-
-// Set up the codec into BluetoothAudio HAL
-bool setup_codec() {
- if (!is_hal_2_0_enabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
- return false;
- }
- CodecConfiguration codec_config{};
- if (!a2dp_get_selected_hal_codec_config(&codec_config)) {
- LOG(ERROR) << __func__ << ": Failed to get CodecConfiguration";
- return false;
- }
- bool should_codec_offloading =
- bluetooth::audio::codec::IsCodecOffloadingEnabled(codec_config);
- if (should_codec_offloading && !is_hal_2_0_offloading()) {
- LOG(WARNING) << __func__ << ": Switching BluetoothAudio HAL to Hardware";
- end_session();
- active_hal_interface = offloading_hal_interface;
- } else if (!should_codec_offloading && is_hal_2_0_offloading()) {
- LOG(WARNING) << __func__ << ": Switching BluetoothAudio HAL to Software";
- end_session();
- active_hal_interface = software_hal_interface;
- }
-
- AudioConfiguration audio_config{};
- if (active_hal_interface->GetTransportInstance()->GetSessionType() ==
- SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
- audio_config.codecConfig(codec_config);
- } else {
- PcmParameters pcm_config{};
- if (!a2dp_get_selected_hal_pcm_config(&pcm_config)) {
- LOG(ERROR) << __func__ << ": Failed to get PcmConfiguration";
- return false;
- }
- audio_config.pcmConfig(pcm_config);
- }
- return active_hal_interface->UpdateAudioConfig(audio_config);
-}
-
-void start_session() {
- if (!is_hal_2_0_enabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
- return;
- }
- active_hal_interface->StartSession();
-}
-
-void end_session() {
- if (!is_hal_2_0_enabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
- return;
- }
- active_hal_interface->EndSession();
- static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance())
- ->ResetPendingCmd();
- static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance())
- ->ResetPresentationPosition();
-}
-
-void ack_stream_started(const tA2DP_CTRL_ACK& ack) {
- auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack);
- LOG(INFO) << __func__ << ": result=" << ctrl_ack;
- auto a2dp_sink =
- static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance());
- auto pending_cmd = a2dp_sink->GetPendingCmd();
- if (pending_cmd == A2DP_CTRL_CMD_START) {
- active_hal_interface->StreamStarted(ctrl_ack);
- } else {
- LOG(WARNING) << __func__ << ": pending=" << pending_cmd
- << " ignore result=" << ctrl_ack;
- return;
- }
- if (ctrl_ack != bluetooth::audio::BluetoothAudioCtrlAck::PENDING) {
- a2dp_sink->ResetPendingCmd();
- }
-}
-
-void ack_stream_suspended(const tA2DP_CTRL_ACK& ack) {
- auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack);
- LOG(INFO) << __func__ << ": result=" << ctrl_ack;
- auto a2dp_sink =
- static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance());
- auto pending_cmd = a2dp_sink->GetPendingCmd();
- if (pending_cmd == A2DP_CTRL_CMD_SUSPEND) {
- active_hal_interface->StreamSuspended(ctrl_ack);
- } else if (pending_cmd == A2DP_CTRL_CMD_STOP) {
- LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_STOP result=" << ctrl_ack;
- } else {
- LOG(WARNING) << __func__ << ": pending=" << pending_cmd
- << " ignore result=" << ctrl_ack;
- return;
- }
- if (ctrl_ack != bluetooth::audio::BluetoothAudioCtrlAck::PENDING) {
- a2dp_sink->ResetPendingCmd();
- }
-}
-
-// Read from the FMQ of BluetoothAudio HAL
-size_t read(uint8_t* p_buf, uint32_t len) {
- if (!is_hal_2_0_enabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
- return 0;
- } else if (is_hal_2_0_offloading()) {
- LOG(ERROR) << __func__ << ": session_type="
- << toString(active_hal_interface->GetTransportInstance()
- ->GetSessionType())
- << " is not A2DP_SOFTWARE_ENCODING_DATAPATH";
- return 0;
- }
- return active_hal_interface->ReadAudioData(p_buf, len);
-}
-
-// Update A2DP delay report to BluetoothAudio HAL
-void set_remote_delay(uint16_t delay_report) {
- if (!is_hal_2_0_enabled()) {
- LOG(INFO) << __func__ << ": not ready for DelayReport "
- << static_cast<float>(delay_report / 10.0) << " ms";
- remote_delay = delay_report;
- return;
- }
- VLOG(1) << __func__ << ": DELAY " << static_cast<float>(delay_report / 10.0)
- << " ms";
- static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance())
- ->SetRemoteDelay(delay_report);
-}
-
-} // namespace a2dp
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/a2dp_encoding.h b/audio_hal_interface/a2dp_encoding.h
deleted file mode 100644
index fbecde7..0000000
--- a/audio_hal_interface/a2dp_encoding.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#pragma once
-
-#include <vector>
-
-#include "audio_a2dp_hw/include/audio_a2dp_hw.h"
-#include "common/message_loop_thread.h"
-
-namespace bluetooth {
-namespace audio {
-namespace a2dp {
-
-bool update_codec_offloading_capabilities(
- const std::vector<btav_a2dp_codec_config_t>& framework_preference);
-
-// Check if new bluetooth_audio is enabled
-bool is_hal_2_0_enabled();
-
-// Check if new bluetooth_audio is running with offloading encoders
-bool is_hal_2_0_offloading();
-
-// Initialize BluetoothAudio HAL: openProvider
-bool init(bluetooth::common::MessageLoopThread* message_loop);
-
-// Clean up BluetoothAudio HAL
-void cleanup();
-
-// Set up the codec into BluetoothAudio HAL
-bool setup_codec();
-
-// Send command to the BluetoothAudio HAL: StartSession, EndSession,
-// StreamStarted, StreamSuspended
-void start_session();
-void end_session();
-void ack_stream_started(const tA2DP_CTRL_ACK& status);
-void ack_stream_suspended(const tA2DP_CTRL_ACK& status);
-
-// Read from the FMQ of BluetoothAudio HAL
-size_t read(uint8_t* p_buf, uint32_t len);
-
-// Update A2DP delay report to BluetoothAudio HAL
-void set_remote_delay(uint16_t delay_report);
-
-} // namespace a2dp
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/a2dp_encoding_host.cc b/audio_hal_interface/a2dp_encoding_host.cc
deleted file mode 100644
index 6ce7fd4..0000000
--- a/audio_hal_interface/a2dp_encoding_host.cc
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#include "a2dp_encoding_host.h"
-
-#include <errno.h>
-#include <grp.h>
-#include <sys/stat.h>
-
-#include <memory>
-
-#include "a2dp_encoding.h"
-#include "a2dp_sbc_constants.h"
-#include "btif_a2dp_source.h"
-#include "btif_av.h"
-#include "btif_av_co.h"
-#include "btif_hf.h"
-#include "osi/include/log.h"
-#include "osi/include/properties.h"
-#include "types/raw_address.h"
-#include "udrv/include/uipc.h"
-
-#include <base/logging.h>
-
-#define A2DP_DATA_READ_POLL_MS 10
-#define A2DP_HOST_DATA_PATH "/var/run/bluetooth/audio/.a2dp_data"
-// TODO(b/198260375): Make A2DP data owner group configurable.
-#define A2DP_HOST_DATA_GROUP "bluetooth-audio"
-
-namespace {
-
-std::unique_ptr<tUIPC_STATE> a2dp_uipc = nullptr;
-
-static void btif_a2dp_data_cb([[maybe_unused]] tUIPC_CH_ID ch_id,
- tUIPC_EVENT event) {
- APPL_TRACE_WARNING("%s: BTIF MEDIA (A2DP-DATA) EVENT %s", __func__,
- dump_uipc_event(event));
-
- switch (event) {
- case UIPC_OPEN_EVT:
- /*
- * Read directly from media task from here on (keep callback for
- * connection events.
- */
- UIPC_Ioctl(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO,
- UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
- UIPC_Ioctl(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
- reinterpret_cast<void*>(A2DP_DATA_READ_POLL_MS));
-
- // Will start audio on btif_a2dp_on_started
-
- /* ACK back when media task is fully started */
- break;
-
- case UIPC_CLOSE_EVT:
- /*
- * Send stop request only if we are actively streaming and haven't
- * received a stop request. Potentially, the audioflinger detached
- * abnormally.
- */
- if (btif_a2dp_source_is_streaming()) {
- /* Post stop event and wait for audio path to stop */
- btif_av_stream_stop(RawAddress::kEmpty);
- }
- break;
-
- default:
- APPL_TRACE_ERROR("%s: ### A2DP-DATA EVENT %d NOT HANDLED ###", __func__,
- event);
- break;
- }
-}
-
-// If A2DP_HOST_DATA_GROUP exists we expect audio server and BT both are
-// in this group therefore have access to A2DP socket. Otherwise audio
-// server should be in the same group that BT stack runs with to access
-// A2DP socket.
-static void a2dp_data_path_open() {
- UIPC_Open(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb,
- A2DP_HOST_DATA_PATH);
- struct group* grp = getgrnam(A2DP_HOST_DATA_GROUP);
- chmod(A2DP_HOST_DATA_PATH, 0770);
- if (grp) {
- int res = chown(A2DP_HOST_DATA_PATH, -1, grp->gr_gid);
- if (res == -1) {
- LOG(ERROR) << __func__ << " failed: " << strerror(errno);
- }
- }
-}
-
-tA2DP_CTRL_CMD a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
-uint64_t total_bytes_read_;
-timespec data_position_;
-uint16_t remote_delay_report_;
-
-} // namespace
-
-namespace bluetooth {
-namespace audio {
-namespace a2dp {
-
-// Invoked by audio server to set audio config (PCM for now)
-bool SetAudioConfig(AudioConfig config) {
- btav_a2dp_codec_config_t codec_config;
- codec_config.sample_rate = config.sample_rate;
- codec_config.bits_per_sample = config.bits_per_sample;
- codec_config.channel_mode = config.channel_mode;
- btif_a2dp_source_feeding_update_req(codec_config);
- return true;
-}
-
-// Invoked by audio server when it has audio data to stream.
-bool StartRequest() {
- // Check if a previous request is not finished
- if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_START) {
- LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_START in progress";
- return false;
- } else if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
- LOG(WARNING) << __func__ << ": busy in pending_cmd=" << a2dp_pending_cmd_;
- return false;
- }
-
- // Don't send START request to stack while we are in a call
- if (!bluetooth::headset::IsCallIdle()) {
- LOG(ERROR) << __func__ << ": call state is busy";
- return false;
- }
-
- if (btif_av_stream_started_ready()) {
- // Already started, ACK back immediately.
- a2dp_data_path_open();
- return true;
- }
- if (btif_av_stream_ready()) {
- a2dp_data_path_open();
- /*
- * Post start event and wait for audio path to open.
- * If we are the source, the ACK will be sent after the start
- * procedure is completed, othewise send it now.
- */
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_START;
- btif_av_stream_start();
- if (btif_av_get_peer_sep() != AVDT_TSEP_SRC) {
- LOG(INFO) << __func__ << ": accepted";
- return false; // TODO: should be pending
- }
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
- return true;
- }
- LOG(ERROR) << __func__ << ": AV stream is not ready to start";
- return false;
-}
-
-// Invoked by audio server when audio streaming is done.
-bool StopRequest() {
- if (btif_av_get_peer_sep() == AVDT_TSEP_SNK &&
- !btif_av_stream_started_ready()) {
- btif_av_clear_remote_suspend_flag();
- return true;
- }
- LOG(INFO) << __func__ << ": handling";
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_STOP;
- btif_av_stream_stop(RawAddress::kEmpty);
- return true;
-}
-
-// Invoked by audio server to check audio presentation position periodically.
-PresentationPosition GetPresentationPosition() {
- PresentationPosition presentation_position{
- .remote_delay_report_ns = remote_delay_report_ * 100000u,
- .total_bytes_read = total_bytes_read_,
- .data_position = data_position_,
- };
- return presentation_position;
-}
-
-// delay reports from AVDTP is based on 1/10 ms (100us)
-void set_remote_delay(uint16_t delay_report) {
- remote_delay_report_ = delay_report;
-}
-
-// Inform audio server about offloading codec; not used for now
-bool update_codec_offloading_capabilities(
- const std::vector<btav_a2dp_codec_config_t>& framework_preference) {
- return false;
-}
-
-// Checking if new bluetooth_audio is enabled
-bool is_hal_2_0_enabled() { return true; }
-
-// Check if new bluetooth_audio is running with offloading encoders
-bool is_hal_2_0_offloading() { return false; }
-
-// Initialize BluetoothAudio HAL: openProvider
-bool init(bluetooth::common::MessageLoopThread* message_loop) {
- a2dp_uipc = UIPC_Init();
- total_bytes_read_ = 0;
- data_position_ = {};
- remote_delay_report_ = 0;
-
- return true;
-}
-
-// Clean up BluetoothAudio HAL
-void cleanup() {
- end_session();
-
- if (a2dp_uipc != nullptr) {
- UIPC_Close(*a2dp_uipc, UIPC_CH_ID_ALL);
- }
-}
-
-// Set up the codec into BluetoothAudio HAL
-bool setup_codec() {
- // TODO: setup codec
- return true;
-}
-
-void start_session() {
- // TODO: Notify server; or do we handle it during connected?
-}
-
-void end_session() {
- // TODO: Notify server; or do we handle it during disconnected?
-}
-
-void ack_stream_started(const tA2DP_CTRL_ACK& ack) {
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
- // TODO: Notify server
-}
-
-void ack_stream_suspended(const tA2DP_CTRL_ACK& ack) {
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
- // TODO: Notify server
-}
-
-// Read from the FMQ of BluetoothAudio HAL
-size_t read(uint8_t* p_buf, uint32_t len) {
- if (a2dp_uipc == nullptr) {
- return 0;
- }
- return UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, p_buf, len);
-}
-
-} // namespace a2dp
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/a2dp_encoding_host.h b/audio_hal_interface/a2dp_encoding_host.h
deleted file mode 100644
index 3a03ebb..0000000
--- a/audio_hal_interface/a2dp_encoding_host.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <time.h>
-
-#include "include/hardware/bt_av.h"
-
-namespace bluetooth {
-namespace audio {
-namespace a2dp {
-
-// Audio config from audio server; PCM format for now
-struct AudioConfig {
- btav_a2dp_codec_sample_rate_t sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_48000;
- btav_a2dp_codec_bits_per_sample_t bits_per_sample =
- BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24;
- btav_a2dp_codec_channel_mode_t channel_mode =
- BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
-};
-
-// Invoked by audio server to set audio config (PCM for now)
-bool SetAudioConfig(AudioConfig);
-
-// Invoked by audio server when it has audio data to stream.
-bool StartRequest();
-
-// Invoked by audio server when audio streaming is done.
-bool StopRequest();
-
-struct PresentationPosition {
- uint64_t remote_delay_report_ns;
- uint64_t total_bytes_read;
- timespec data_position;
-};
-
-// Invoked by audio server to check audio presentation position periodically.
-PresentationPosition GetPresentationPosition();
-
-} // namespace a2dp
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/client_interface.cc b/audio_hal_interface/client_interface.cc
deleted file mode 100644
index febf43f..0000000
--- a/audio_hal_interface/client_interface.cc
+++ /dev/null
@@ -1,885 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#define LOG_TAG "BTAudioClientIf"
-
-#include "client_interface.h"
-#include "hal_version_manager.h"
-
-#include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioPort.h>
-#include <base/logging.h>
-#include <hidl/MQDescriptor.h>
-#include <future>
-
-#include "common/stop_watch_legacy.h"
-#include "osi/include/log.h"
-
-namespace bluetooth {
-namespace audio {
-
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::audio::common::V5_0::SourceMetadata;
-using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
-using ::bluetooth::common::StopWatchLegacy;
-
-using DataMQ = ::android::hardware::MessageQueue<
- uint8_t, ::android::hardware::kSynchronizedReadWrite>;
-
-static constexpr int kDefaultDataReadTimeoutMs = 10; // 10 ms
-static constexpr int kDefaultDataWriteTimeoutMs = 10; // 10 ms
-static constexpr int kDefaultDataReadPollIntervalMs = 1; // non-blocking poll
-static constexpr int kDefaultDataWritePollIntervalMs = 1; // non-blocking poll
-
-std::unique_ptr<HalVersionManager> HalVersionManager::instance_ptr =
- std::unique_ptr<HalVersionManager>(new HalVersionManager());
-
-std::ostream& operator<<(std::ostream& os, const BluetoothAudioCtrlAck& ack) {
- switch (ack) {
- case BluetoothAudioCtrlAck::SUCCESS_FINISHED:
- return os << "SUCCESS_FINISHED";
- case BluetoothAudioCtrlAck::PENDING:
- return os << "PENDING";
- case BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED:
- return os << "FAILURE_UNSUPPORTED";
- case BluetoothAudioCtrlAck::FAILURE_BUSY:
- return os << "FAILURE_BUSY";
- case BluetoothAudioCtrlAck::FAILURE_DISCONNECTING:
- return os << "FAILURE_DISCONNECTING";
- case BluetoothAudioCtrlAck::FAILURE:
- return os << "FAILURE";
- default:
- return os << "UNDEFINED " << static_cast<int8_t>(ack);
- }
-}
-
-class BluetoothAudioPortImpl : public IBluetoothAudioPort {
- public:
- BluetoothAudioPortImpl(IBluetoothTransportInstance* transport_instance,
- const android::sp<IBluetoothAudioProvider>& provider)
- : transport_instance_(transport_instance), provider_(provider) {}
-
- Return<void> startStream() override {
- StopWatchLegacy(__func__);
- BluetoothAudioCtrlAck ack = transport_instance_->StartRequest();
- if (ack != BluetoothAudioCtrlAck::PENDING) {
- auto hidl_retval =
- provider_->streamStarted(BluetoothAudioCtrlAckToHalStatus(ack));
- if (!hidl_retval.isOk()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
- << hidl_retval.description();
- }
- }
- return Void();
- }
-
- Return<void> suspendStream() override {
- StopWatchLegacy(__func__);
- BluetoothAudioCtrlAck ack = transport_instance_->SuspendRequest();
- if (ack != BluetoothAudioCtrlAck::PENDING) {
- auto hidl_retval =
- provider_->streamSuspended(BluetoothAudioCtrlAckToHalStatus(ack));
- if (!hidl_retval.isOk()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
- << hidl_retval.description();
- }
- }
- return Void();
- }
-
- Return<void> stopStream() override {
- StopWatchLegacy(__func__);
- transport_instance_->StopRequest();
- return Void();
- }
-
- Return<void> getPresentationPosition(
- getPresentationPosition_cb _hidl_cb) override {
- StopWatchLegacy(__func__);
- uint64_t remote_delay_report_ns;
- uint64_t total_bytes_read;
- timespec data_position;
- bool retval = transport_instance_->GetPresentationPosition(
- &remote_delay_report_ns, &total_bytes_read, &data_position);
-
- TimeSpec transmittedOctetsTimeStamp;
- if (retval) {
- transmittedOctetsTimeStamp = timespec_convert_to_hal(data_position);
- } else {
- remote_delay_report_ns = 0;
- total_bytes_read = 0;
- transmittedOctetsTimeStamp = {};
- }
- VLOG(2) << __func__ << ": result=" << retval
- << ", delay=" << remote_delay_report_ns
- << ", data=" << total_bytes_read
- << " byte(s), timestamp=" << toString(transmittedOctetsTimeStamp);
- _hidl_cb((retval ? BluetoothAudioStatus::SUCCESS
- : BluetoothAudioStatus::FAILURE),
- remote_delay_report_ns, total_bytes_read,
- transmittedOctetsTimeStamp);
- return Void();
- }
-
- Return<void> updateMetadata(const SourceMetadata& sourceMetadata) override {
- StopWatchLegacy(__func__);
- LOG(INFO) << __func__ << ": " << sourceMetadata.tracks.size()
- << " track(s)";
- // refer to StreamOut.impl.h within Audio HAL (AUDIO_HAL_VERSION_5_0)
- std::vector<playback_track_metadata> metadata_vec;
- metadata_vec.reserve(sourceMetadata.tracks.size());
- for (const auto& metadata : sourceMetadata.tracks) {
- metadata_vec.push_back({
- .usage = static_cast<audio_usage_t>(metadata.usage),
- .content_type =
- static_cast<audio_content_type_t>(metadata.contentType),
- .gain = metadata.gain,
- });
- }
- const source_metadata_t source_metadata = {
- .track_count = metadata_vec.size(), .tracks = metadata_vec.data()};
- transport_instance_->MetadataChanged(source_metadata);
- return Void();
- }
-
- private:
- IBluetoothTransportInstance* transport_instance_;
- const android::sp<IBluetoothAudioProvider> provider_;
- TimeSpec timespec_convert_to_hal(const timespec& ts) {
- return {.tvSec = static_cast<uint64_t>(ts.tv_sec),
- .tvNSec = static_cast<uint64_t>(ts.tv_nsec)};
- }
-};
-
-class BluetoothAudioDeathRecipient
- : public ::android::hardware::hidl_death_recipient {
- public:
- BluetoothAudioDeathRecipient(
- BluetoothAudioClientInterface* clientif,
- bluetooth::common::MessageLoopThread* message_loop)
- : bluetooth_audio_clientif_(clientif), message_loop_(message_loop) {}
- void serviceDied(
- uint64_t /*cookie*/,
- const ::android::wp<::android::hidl::base::V1_0::IBase>& /*who*/)
- override {
- LOG(WARNING) << __func__ << ": restarting connection with new Audio Hal";
- if (bluetooth_audio_clientif_ != nullptr && message_loop_ != nullptr) {
- // restart the session on the correct thread
- message_loop_->DoInThread(
- FROM_HERE,
- base::BindOnce(
- &BluetoothAudioClientInterface::RenewAudioProviderAndSession,
- base::Unretained(bluetooth_audio_clientif_)));
- } else {
- LOG(ERROR) << __func__ << ": BluetoothAudioClientInterface corrupted";
- }
- }
-
- private:
- BluetoothAudioClientInterface* bluetooth_audio_clientif_;
- bluetooth::common::MessageLoopThread* message_loop_;
-};
-
-// Constructs an BluetoothAudioClientInterface to communicate to
-// BluetoothAudio HAL. |message_loop| is the thread where callbacks are
-// invoked.
-BluetoothAudioClientInterface::BluetoothAudioClientInterface(
- android::sp<BluetoothAudioDeathRecipient> death_recipient,
- IBluetoothTransportInstance* instance)
- : provider_(nullptr),
- provider_2_1_(nullptr),
- session_started_(false),
- mDataMQ(nullptr),
- transport_(instance) {
- death_recipient_ = death_recipient;
-}
-
-std::vector<AudioCapabilities>
-BluetoothAudioClientInterface::GetAudioCapabilities() const {
- return capabilities_;
-}
-
-std::vector<AudioCapabilities_2_1>
-BluetoothAudioClientInterface::GetAudioCapabilities_2_1() const {
- return capabilities_2_1_;
-}
-
-std::vector<AudioCapabilities>
-BluetoothAudioClientInterface::GetAudioCapabilities(SessionType session_type) {
- std::vector<AudioCapabilities> capabilities(0);
-
- if (HalVersionManager::GetHalVersion() ==
- BluetoothAudioHalVersion::VERSION_UNAVAILABLE) {
- LOG(ERROR) << __func__ << ", can't get capability from unknown factory";
- return capabilities;
- }
-
- android::sp<IBluetoothAudioProvidersFactory_2_0> providersFactory =
- HalVersionManager::GetProvidersFactory_2_0();
- CHECK(providersFactory != nullptr)
- << "IBluetoothAudioProvidersFactory::getService() failed";
-
- auto getProviderCapabilities_cb =
- [&capabilities](const hidl_vec<AudioCapabilities>& audioCapabilities) {
- for (auto capability : audioCapabilities) {
- capabilities.push_back(capability);
- }
- };
- auto hidl_retval = providersFactory->getProviderCapabilities(
- session_type, getProviderCapabilities_cb);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__
- << ": BluetoothAudioHal::getProviderCapabilities failure: "
- << hidl_retval.description();
- }
- return capabilities;
-}
-
-std::vector<AudioCapabilities_2_1>
-BluetoothAudioClientInterface::GetAudioCapabilities_2_1(
- SessionType_2_1 session_type_2_1) {
- std::vector<AudioCapabilities_2_1> capabilities_2_1(0);
-
- if (HalVersionManager::GetHalVersion() !=
- BluetoothAudioHalVersion::VERSION_2_1) {
- LOG(ERROR) << __func__ << ", can't get capability for HAL 2.1";
- return capabilities_2_1;
- }
-
- android::sp<IBluetoothAudioProvidersFactory_2_1> providersFactory =
- HalVersionManager::GetProvidersFactory_2_1();
- CHECK(providersFactory != nullptr)
- << "IBluetoothAudioProvidersFactory::getService() failed";
-
- auto getProviderCapabilities_cb =
- [&capabilities_2_1](
- const hidl_vec<AudioCapabilities_2_1>& audioCapabilities_2_1) {
- for (auto capability_2_1 : audioCapabilities_2_1) {
- capabilities_2_1.push_back(capability_2_1);
- }
- };
- auto hidl_retval = providersFactory->getProviderCapabilities_2_1(
- session_type_2_1, getProviderCapabilities_cb);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__
- << ": BluetoothAudioHal::getProviderCapabilities failure: "
- << hidl_retval.description();
- }
- return capabilities_2_1;
-}
-
-void BluetoothAudioClientInterface::FetchAudioProvider() {
- if (provider_ != nullptr) {
- LOG(WARNING) << __func__ << ": reflash";
- }
-
- android::sp<IBluetoothAudioProvidersFactory_2_0> providersFactory =
- HalVersionManager::GetProvidersFactory_2_0();
- CHECK(providersFactory != nullptr)
- << "IBluetoothAudioProvidersFactory::getService() failed";
-
- auto getProviderCapabilities_cb =
- [&capabilities = this->capabilities_](
- const hidl_vec<AudioCapabilities>& audioCapabilities) {
- capabilities.clear();
- for (auto capability : audioCapabilities) {
- capabilities.push_back(capability);
- }
- };
- auto hidl_retval = providersFactory->getProviderCapabilities(
- transport_->GetSessionType(), getProviderCapabilities_cb);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__
- << ": BluetoothAudioHal::getProviderCapabilities failure: "
- << hidl_retval.description();
- return;
- }
- if (capabilities_.empty()) {
- LOG(WARNING) << __func__
- << ": SessionType=" << toString(transport_->GetSessionType())
- << " Not supported by BluetoothAudioHal";
- return;
- }
- LOG(INFO) << __func__ << ": BluetoothAudioHal SessionType="
- << toString(transport_->GetSessionType()) << " has "
- << capabilities_.size() << " AudioCapabilities";
-
- std::promise<void> openProvider_promise;
- auto openProvider_future = openProvider_promise.get_future();
- auto openProvider_cb =
- [&provider_ = this->provider_, &openProvider_promise](
- BluetoothAudioStatus status,
- const android::sp<IBluetoothAudioProvider>& provider) {
- LOG(INFO) << "openProvider_cb(" << toString(status) << ")";
- if (status == BluetoothAudioStatus::SUCCESS) {
- provider_ = provider;
- }
- ALOGE_IF(!provider_, "Failed to open BluetoothAudio provider");
- openProvider_promise.set_value();
- };
- hidl_retval = providersFactory->openProvider(transport_->GetSessionType(),
- openProvider_cb);
- openProvider_future.get();
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioHal::openProvider failure: "
- << hidl_retval.description();
- }
- CHECK(provider_ != nullptr);
-
- if (!provider_->linkToDeath(death_recipient_, 0).isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
- << hidl_retval.description();
- }
-
- LOG(INFO) << "IBluetoothAudioProvidersFactory::openProvider() returned "
- << provider_.get()
- << (provider_->isRemote() ? " (remote)" : " (local)");
-}
-
-void BluetoothAudioClientInterface::FetchAudioProvider_2_1() {
- if (provider_2_1_ != nullptr) {
- LOG(WARNING) << __func__ << ": reflash";
- }
-
- android::sp<IBluetoothAudioProvidersFactory_2_1> providersFactory =
- HalVersionManager::GetProvidersFactory_2_1();
- CHECK(providersFactory != nullptr)
- << "IBluetoothAudioProvidersFactory_2_1::getService() failed";
-
- auto getProviderCapabilities_cb =
- [&capabilities_2_1 = this->capabilities_2_1_](
- const hidl_vec<AudioCapabilities_2_1>& audioCapabilities_2_1) {
- capabilities_2_1.clear();
- for (auto capability_2_1 : audioCapabilities_2_1) {
- capabilities_2_1.push_back(capability_2_1);
- }
- };
- auto hidl_retval = providersFactory->getProviderCapabilities_2_1(
- transport_->GetSessionType_2_1(), getProviderCapabilities_cb);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__
- << ": BluetoothAudioHal::getProviderCapabilities failure: "
- << hidl_retval.description();
- return;
- }
- if (capabilities_2_1_.empty()) {
- LOG(WARNING) << __func__ << ": SessionType="
- << toString(transport_->GetSessionType_2_1())
- << " Not supported by BluetoothAudioHal";
- return;
- }
- LOG(INFO) << __func__ << ": BluetoothAudioHal SessionType="
- << toString(transport_->GetSessionType_2_1()) << " has "
- << capabilities_2_1_.size() << " AudioCapabilities";
-
- std::promise<void> openProvider_promise;
- auto openProvider_future = openProvider_promise.get_future();
- auto openProvider_cb =
- [&provider_2_1_ = this->provider_2_1_, &openProvider_promise](
- BluetoothAudioStatus status,
- const android::sp<IBluetoothAudioProvider_2_1>& provider_2_1) {
- LOG(INFO) << "openProvider_cb(" << toString(status) << ")";
- if (status == BluetoothAudioStatus::SUCCESS) {
- provider_2_1_ = provider_2_1;
- }
- ALOGE_IF(!provider_2_1_, "Failed to open BluetoothAudio provider_2_1");
- openProvider_promise.set_value();
- };
- hidl_retval = providersFactory->openProvider_2_1(
- transport_->GetSessionType_2_1(), openProvider_cb);
- openProvider_future.get();
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioHal::openProvider failure: "
- << hidl_retval.description();
- }
- CHECK(provider_2_1_ != nullptr);
-
- if (!provider_2_1_->linkToDeath(death_recipient_, 0).isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
- << hidl_retval.description();
- }
-
- LOG(INFO) << "IBluetoothAudioProvidersFactory::openProvider() returned "
- << provider_2_1_.get()
- << (provider_2_1_->isRemote() ? " (remote)" : " (local)");
-}
-
-BluetoothAudioSinkClientInterface::BluetoothAudioSinkClientInterface(
- IBluetoothSinkTransportInstance* sink,
- bluetooth::common::MessageLoopThread* message_loop)
- : BluetoothAudioClientInterface{new BluetoothAudioDeathRecipient(
- this, message_loop),
- sink},
- sink_(sink) {
- if (HalVersionManager::GetHalVersion() ==
- BluetoothAudioHalVersion::VERSION_UNAVAILABLE) {
- return;
- }
-
- if ((HalVersionManager::GetHalVersion() ==
- BluetoothAudioHalVersion::VERSION_2_1) &&
- (sink_->GetSessionType_2_1() != SessionType_2_1::UNKNOWN)) {
- FetchAudioProvider_2_1();
- return;
- }
- FetchAudioProvider();
-}
-
-BluetoothAudioSinkClientInterface::~BluetoothAudioSinkClientInterface() {
- if (provider_ != nullptr) {
- auto hidl_retval = provider_->unlinkToDeath(death_recipient_);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
- << hidl_retval.description();
- }
- }
- if (provider_2_1_ != nullptr) {
- auto hidl_retval = provider_2_1_->unlinkToDeath(death_recipient_);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
- << hidl_retval.description();
- }
- }
-}
-
-BluetoothAudioSourceClientInterface::BluetoothAudioSourceClientInterface(
- IBluetoothSourceTransportInstance* source,
- bluetooth::common::MessageLoopThread* message_loop)
- : BluetoothAudioClientInterface{new BluetoothAudioDeathRecipient(
- this, message_loop),
- source},
- source_(source) {
- if (HalVersionManager::GetHalVersion() ==
- BluetoothAudioHalVersion::VERSION_UNAVAILABLE) {
- return;
- }
-
- if ((HalVersionManager::GetHalVersion() ==
- BluetoothAudioHalVersion::VERSION_2_1) &&
- (source_->GetSessionType_2_1() != SessionType_2_1::UNKNOWN)) {
- FetchAudioProvider_2_1();
- return;
- }
- FetchAudioProvider();
-}
-
-BluetoothAudioSourceClientInterface::~BluetoothAudioSourceClientInterface() {
- if (provider_ != nullptr) {
- auto hidl_retval = provider_->unlinkToDeath(death_recipient_);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
- << hidl_retval.description();
- }
- }
- if (provider_2_1_ != nullptr) {
- auto hidl_retval = provider_2_1_->unlinkToDeath(death_recipient_);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
- << hidl_retval.description();
- }
- }
-}
-
-bool BluetoothAudioClientInterface::UpdateAudioConfig(
- const AudioConfiguration& audio_config) {
- bool is_software_session =
- (transport_->GetSessionType() ==
- SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
- transport_->GetSessionType() ==
- SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
- bool is_offload_session = (transport_->GetSessionType() ==
- SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- auto audio_config_discriminator = audio_config.getDiscriminator();
- bool is_software_audio_config =
- (is_software_session &&
- audio_config_discriminator ==
- AudioConfiguration::hidl_discriminator::pcmConfig);
- bool is_offload_audio_config =
- (is_offload_session &&
- audio_config_discriminator ==
- AudioConfiguration::hidl_discriminator::codecConfig);
- if (!is_software_audio_config && !is_offload_audio_config) {
- return false;
- }
- transport_->UpdateAudioConfiguration(audio_config);
- return true;
-}
-
-bool BluetoothAudioClientInterface::UpdateAudioConfig_2_1(
- const AudioConfiguration_2_1& audio_config_2_1) {
- bool is_software_session =
- (transport_->GetSessionType_2_1() ==
- SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
- transport_->GetSessionType_2_1() ==
- SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
- transport_->GetSessionType_2_1() ==
- SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
- transport_->GetSessionType_2_1() ==
- SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
- bool is_offload_session = (transport_->GetSessionType_2_1() ==
- SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- auto audio_config_discriminator = audio_config_2_1.getDiscriminator();
- bool is_software_audio_config =
- (is_software_session &&
- audio_config_discriminator ==
- AudioConfiguration_2_1::hidl_discriminator::pcmConfig);
- bool is_offload_audio_config =
- (is_offload_session &&
- audio_config_discriminator ==
- AudioConfiguration_2_1::hidl_discriminator::codecConfig);
- if (!is_software_audio_config && !is_offload_audio_config) {
- return false;
- }
- transport_->UpdateAudioConfiguration_2_1(audio_config_2_1);
- return true;
-}
-
-int BluetoothAudioClientInterface::StartSession() {
- std::lock_guard<std::mutex> guard(internal_mutex_);
- if (provider_ == nullptr) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
- session_started_ = false;
- return -EINVAL;
- }
- if (session_started_) {
- LOG(ERROR) << __func__ << ": session started already";
- return -EBUSY;
- }
-
- android::sp<IBluetoothAudioPort> stack_if =
- new BluetoothAudioPortImpl(transport_, provider_);
-
- std::unique_ptr<DataMQ> tempDataMQ;
- BluetoothAudioStatus session_status;
-
- std::promise<void> hidl_startSession_promise;
- auto hidl_startSession_future = hidl_startSession_promise.get_future();
- auto hidl_cb = [&session_status, &tempDataMQ, &hidl_startSession_promise](
- BluetoothAudioStatus status,
- const DataMQ::Descriptor& dataMQ) {
- LOG(INFO) << "startSession_cb(" << toString(status) << ")";
- session_status = status;
- if (status == BluetoothAudioStatus::SUCCESS && dataMQ.isHandleValid()) {
- tempDataMQ.reset(new DataMQ(dataMQ));
- }
- hidl_startSession_promise.set_value();
- };
- auto hidl_retval = provider_->startSession(
- stack_if, transport_->GetAudioConfiguration(), hidl_cb);
- hidl_startSession_future.get();
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__
- << ": BluetoothAudioHal failure: " << hidl_retval.description();
- return -EPROTO;
- }
-
- if (tempDataMQ && tempDataMQ->isValid()) {
- mDataMQ = std::move(tempDataMQ);
- } else if (transport_->GetSessionType() ==
- SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH &&
- session_status == BluetoothAudioStatus::SUCCESS) {
- transport_->ResetPresentationPosition();
- session_started_ = true;
- return 0;
- }
- if (mDataMQ && mDataMQ->isValid()) {
- transport_->ResetPresentationPosition();
- session_started_ = true;
- return 0;
- } else {
- ALOGE_IF(!mDataMQ, "Failed to obtain audio data path");
- ALOGE_IF(mDataMQ && !mDataMQ->isValid(), "Audio data path is invalid");
- session_started_ = false;
- return -EIO;
- }
-}
-
-int BluetoothAudioClientInterface::StartSession_2_1() {
- std::lock_guard<std::mutex> guard(internal_mutex_);
- if (provider_2_1_ == nullptr) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
- session_started_ = false;
- return -EINVAL;
- }
- if (session_started_) {
- LOG(ERROR) << __func__ << ": session started already";
- return -EBUSY;
- }
-
- android::sp<IBluetoothAudioPort> stack_if =
- new BluetoothAudioPortImpl(transport_, provider_2_1_);
-
- std::unique_ptr<DataMQ> tempDataMQ;
- BluetoothAudioStatus session_status;
-
- std::promise<void> hidl_startSession_promise;
- auto hidl_startSession_future = hidl_startSession_promise.get_future();
- auto hidl_cb = [&session_status, &tempDataMQ, &hidl_startSession_promise](
- BluetoothAudioStatus status,
- const DataMQ::Descriptor& dataMQ) {
- LOG(INFO) << "startSession_cb(" << toString(status) << ")";
- session_status = status;
- if (status == BluetoothAudioStatus::SUCCESS && dataMQ.isHandleValid()) {
- tempDataMQ.reset(new DataMQ(dataMQ));
- }
- hidl_startSession_promise.set_value();
- };
- auto hidl_retval = provider_2_1_->startSession_2_1(
- stack_if, transport_->GetAudioConfiguration_2_1(), hidl_cb);
- hidl_startSession_future.get();
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__
- << ": BluetoothAudioHal failure: " << hidl_retval.description();
- return -EPROTO;
- }
-
- if (tempDataMQ && tempDataMQ->isValid()) {
- mDataMQ = std::move(tempDataMQ);
- } else if (transport_->GetSessionType_2_1() ==
- SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH &&
- session_status == BluetoothAudioStatus::SUCCESS) {
- transport_->ResetPresentationPosition();
- session_started_ = true;
- return 0;
- }
- if (mDataMQ && mDataMQ->isValid()) {
- transport_->ResetPresentationPosition();
- session_started_ = true;
- return 0;
- } else {
- ALOGE_IF(!mDataMQ, "Failed to obtain audio data path");
- ALOGE_IF(mDataMQ && !mDataMQ->isValid(), "Audio data path is invalid");
- session_started_ = false;
- return -EIO;
- }
-}
-
-void BluetoothAudioClientInterface::StreamStarted(
- const BluetoothAudioCtrlAck& ack) {
- if (provider_ == nullptr && provider_2_1_ == nullptr) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
- return;
- }
- if (ack == BluetoothAudioCtrlAck::PENDING) {
- LOG(INFO) << __func__ << ": " << ack << " ignored";
- return;
- }
- BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
-
- ::android::hardware::Return<void> hidl_retval;
- if (provider_2_1_ != nullptr)
- hidl_retval = provider_2_1_->streamStarted(status);
- else
- hidl_retval = provider_->streamStarted(status);
-
- if (!hidl_retval.isOk()) {
- LOG(ERROR) << __func__
- << ": BluetoothAudioHal failure: " << hidl_retval.description();
- }
-}
-
-void BluetoothAudioClientInterface::StreamSuspended(
- const BluetoothAudioCtrlAck& ack) {
- if (provider_ == nullptr) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
- return;
- }
- if (ack == BluetoothAudioCtrlAck::PENDING) {
- LOG(INFO) << __func__ << ": " << ack << " ignored";
- return;
- }
- BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
-
- ::android::hardware::Return<void> hidl_retval;
- if (provider_2_1_ != nullptr)
- hidl_retval = provider_2_1_->streamSuspended(status);
- else
- hidl_retval = provider_->streamSuspended(status);
-
- if (!hidl_retval.isOk()) {
- LOG(ERROR) << __func__
- << ": BluetoothAudioHal failure: " << hidl_retval.description();
- }
-}
-
-int BluetoothAudioClientInterface::EndSession() {
- std::lock_guard<std::mutex> guard(internal_mutex_);
- if (!session_started_) {
- LOG(INFO) << __func__ << ": session ended already";
- return 0;
- }
-
- session_started_ = false;
- if (provider_2_1_ == nullptr && provider_ == nullptr) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
- return -EINVAL;
- }
- mDataMQ = nullptr;
-
- ::android::hardware::Return<void> hidl_retval;
- if (provider_2_1_ != nullptr)
- hidl_retval = provider_2_1_->endSession();
- else
- hidl_retval = provider_->endSession();
-
- if (!hidl_retval.isOk()) {
- LOG(ERROR) << __func__
- << ": BluetoothAudioHal failure: " << hidl_retval.description();
- return -EPROTO;
- }
- return 0;
-}
-
-void BluetoothAudioClientInterface::FlushAudioData() {
- size_t size = mDataMQ->availableToRead();
- uint8_t p_buf[size];
-
- if (mDataMQ->read(p_buf, size) != size)
- LOG(WARNING) << __func__ << ", failed to flush data queue!";
-}
-
-size_t BluetoothAudioSinkClientInterface::ReadAudioData(uint8_t* p_buf,
- uint32_t len) {
- if (!IsValid()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal is not valid";
- return 0;
- }
- if (p_buf == nullptr || len == 0) return 0;
-
- std::lock_guard<std::mutex> guard(internal_mutex_);
-
- size_t total_read = 0;
- int timeout_ms = kDefaultDataReadTimeoutMs;
- do {
- if (mDataMQ == nullptr || !mDataMQ->isValid()) break;
-
- size_t avail_to_read = mDataMQ->availableToRead();
- if (avail_to_read) {
- if (avail_to_read > len - total_read) {
- avail_to_read = len - total_read;
- }
- if (mDataMQ->read(p_buf + total_read, avail_to_read) == 0) {
- LOG(WARNING) << __func__ << ": len=" << len
- << " total_read=" << total_read << " failed";
- break;
- }
- total_read += avail_to_read;
- } else if (timeout_ms >= kDefaultDataReadPollIntervalMs) {
- std::this_thread::sleep_for(
- std::chrono::milliseconds(kDefaultDataReadPollIntervalMs));
- timeout_ms -= kDefaultDataReadPollIntervalMs;
- continue;
- } else {
- LOG(WARNING) << __func__ << ": " << (len - total_read) << "/" << len
- << " no data " << (kDefaultDataReadTimeoutMs - timeout_ms)
- << " ms";
- break;
- }
- } while (total_read < len);
-
- if (timeout_ms <
- (kDefaultDataReadTimeoutMs - kDefaultDataReadPollIntervalMs) &&
- timeout_ms >= kDefaultDataReadPollIntervalMs) {
- VLOG(1) << __func__ << ": underflow " << len << " -> " << total_read
- << " read " << (kDefaultDataReadTimeoutMs - timeout_ms) << " ms";
- } else {
- VLOG(2) << __func__ << ": " << len << " -> " << total_read << " read";
- }
-
- sink_->LogBytesRead(total_read);
- return total_read;
-}
-
-void BluetoothAudioClientInterface::RenewAudioProviderAndSession() {
- // NOTE: must be invoked on the same thread where this
- // BluetoothAudioClientInterface is running
- if ((HalVersionManager::GetHalVersion() ==
- BluetoothAudioHalVersion::VERSION_2_1) &&
- (transport_->GetSessionType_2_1() != SessionType_2_1::UNKNOWN)) {
- FetchAudioProvider_2_1();
- } else if (transport_->GetSessionType() != SessionType::UNKNOWN) {
- FetchAudioProvider();
- } else {
- LOG(FATAL) << __func__ << ", cannot renew audio provider";
- return;
- }
-
- if (session_started_) {
- LOG(INFO) << __func__ << ": Restart the session while audio HAL recovering";
- session_started_ = false;
-
- if (provider_2_1_ != nullptr)
- StartSession_2_1();
- else
- StartSession();
- }
-}
-
-size_t BluetoothAudioSourceClientInterface::WriteAudioData(const uint8_t* p_buf,
- uint32_t len) {
- if (provider_ == nullptr) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
- return 0;
- }
- if (p_buf == nullptr || len == 0) return 0;
-
- std::lock_guard<std::mutex> guard(internal_mutex_);
-
- size_t total_written = 0;
- int timeout_ms = kDefaultDataWriteTimeoutMs;
- do {
- if (mDataMQ == nullptr || !mDataMQ->isValid()) break;
-
- size_t avail_to_write = mDataMQ->availableToWrite();
- if (avail_to_write) {
- if (avail_to_write > len - total_written) {
- avail_to_write = len - total_written;
- }
- if (mDataMQ->write(p_buf + total_written, avail_to_write) == 0) {
- LOG(WARNING) << __func__ << ": len=" << len
- << " total_written=" << total_written << " failed";
- break;
- }
- total_written += avail_to_write;
- } else if (timeout_ms >= kDefaultDataWritePollIntervalMs) {
- std::this_thread::sleep_for(
- std::chrono::milliseconds(kDefaultDataWritePollIntervalMs));
- timeout_ms -= kDefaultDataWritePollIntervalMs;
- continue;
- } else {
- LOG(WARNING) << __func__ << ": " << (len - total_written) << "/" << len
- << " no data " << (kDefaultDataWriteTimeoutMs - timeout_ms)
- << " ms";
- break;
- }
- } while (total_written < len);
-
- if (timeout_ms <
- (kDefaultDataWriteTimeoutMs - kDefaultDataWritePollIntervalMs) &&
- timeout_ms >= kDefaultDataWritePollIntervalMs) {
- VLOG(1) << __func__ << ": underflow " << len << " -> " << total_written
- << " read " << (kDefaultDataWriteTimeoutMs - timeout_ms) << " ms";
- } else {
- VLOG(2) << __func__ << ": " << len << " -> " << total_written << " written";
- }
-
- source_->LogBytesWritten(total_written);
- return total_written;
-}
-
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/client_interface.h b/audio_hal_interface/client_interface.h
deleted file mode 100644
index b9f18b9..0000000
--- a/audio_hal_interface/client_interface.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#pragma once
-
-#include <time.h>
-#include <mutex>
-#include <vector>
-
-#include <android/hardware/bluetooth/audio/2.1/IBluetoothAudioProvider.h>
-#include <android/hardware/bluetooth/audio/2.1/types.h>
-#include <fmq/MessageQueue.h>
-#include <hardware/audio.h>
-
-#include "common/message_loop_thread.h"
-
-#define BLUETOOTH_AUDIO_HAL_PROP_DISABLED "persist.bluetooth.bluetooth_audio_hal.disabled"
-
-namespace bluetooth {
-namespace audio {
-
-using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
-using AudioCapabilities =
- ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
-using AudioCapabilities_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::AudioCapabilities;
-using AudioConfiguration =
- ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
-using AudioConfiguration_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
-using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
-using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
-using IBluetoothAudioProvider =
- ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioProvider;
-using IBluetoothAudioProvider_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::IBluetoothAudioProvider;
-using PcmParameters =
- ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
-using PcmParameters_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
-using SampleRate = ::android::hardware::bluetooth::audio::V2_0::SampleRate;
-using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate;
-using SessionType = ::android::hardware::bluetooth::audio::V2_0::SessionType;
-using SessionType_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::SessionType;
-using ::android::hardware::bluetooth::audio::V2_0::TimeSpec;
-using BluetoothAudioStatus =
- ::android::hardware::bluetooth::audio::V2_0::Status;
-
-enum class BluetoothAudioCtrlAck : uint8_t {
- SUCCESS_FINISHED = 0,
- PENDING,
- FAILURE_UNSUPPORTED,
- FAILURE_BUSY,
- FAILURE_DISCONNECTING,
- FAILURE
-};
-
-std::ostream& operator<<(std::ostream& os, const BluetoothAudioCtrlAck& ack);
-
-inline BluetoothAudioStatus BluetoothAudioCtrlAckToHalStatus(
- const BluetoothAudioCtrlAck& ack) {
- switch (ack) {
- case BluetoothAudioCtrlAck::SUCCESS_FINISHED:
- return BluetoothAudioStatus::SUCCESS;
- case BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED:
- return BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION;
- case BluetoothAudioCtrlAck::PENDING:
- return BluetoothAudioStatus::FAILURE;
- case BluetoothAudioCtrlAck::FAILURE_BUSY:
- return BluetoothAudioStatus::FAILURE;
- case BluetoothAudioCtrlAck::FAILURE_DISCONNECTING:
- return BluetoothAudioStatus::FAILURE;
- default:
- return BluetoothAudioStatus::FAILURE;
- }
-}
-
-// An IBluetoothTransportInstance needs to be implemented by a Bluetooth
-// audio transport, such as A2DP or Hearing Aid, to handle callbacks from Audio
-// HAL.
-class IBluetoothTransportInstance {
- public:
- IBluetoothTransportInstance(SessionType sessionType,
- AudioConfiguration audioConfig)
- : session_type_(sessionType),
- session_type_2_1_(SessionType_2_1::UNKNOWN),
- audio_config_(std::move(audioConfig)),
- audio_config_2_1_({}){};
- IBluetoothTransportInstance(SessionType_2_1 sessionType_2_1,
- AudioConfiguration_2_1 audioConfig_2_1)
- : session_type_(SessionType::UNKNOWN),
- session_type_2_1_(sessionType_2_1),
- audio_config_({}),
- audio_config_2_1_(std::move(audioConfig_2_1)){};
- virtual ~IBluetoothTransportInstance() = default;
-
- SessionType GetSessionType() const { return session_type_; }
- SessionType_2_1 GetSessionType_2_1() const { return session_type_2_1_; }
-
- AudioConfiguration GetAudioConfiguration() const { return audio_config_; }
- AudioConfiguration_2_1 GetAudioConfiguration_2_1() const {
- return audio_config_2_1_;
- }
-
- void UpdateAudioConfiguration(const AudioConfiguration& audio_config) {
- audio_config_ = audio_config;
- }
- void UpdateAudioConfiguration_2_1(
- const AudioConfiguration_2_1& audio_config_2_1) {
- audio_config_2_1_ = audio_config_2_1;
- }
-
- virtual BluetoothAudioCtrlAck StartRequest() = 0;
-
- virtual BluetoothAudioCtrlAck SuspendRequest() = 0;
-
- virtual void StopRequest() = 0;
-
- virtual bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_readed,
- timespec* data_position) = 0;
-
- virtual void MetadataChanged(const source_metadata_t& source_metadata) = 0;
-
- // Invoked when the transport is requested to reset presentation position
- virtual void ResetPresentationPosition() = 0;
-
- private:
- const SessionType session_type_;
- const SessionType_2_1 session_type_2_1_;
- AudioConfiguration audio_config_;
- AudioConfiguration_2_1 audio_config_2_1_;
-};
-
-// An IBluetoothSinkTransportInstance needs to be implemented by a Bluetooth
-// audio transport, such as A2DP, Hearing Aid or LeAudio, to handle callbacks
-// from Audio HAL.
-class IBluetoothSinkTransportInstance : public IBluetoothTransportInstance {
- public:
- IBluetoothSinkTransportInstance(SessionType_2_1 sessionType_2_1,
- AudioConfiguration_2_1 audioConfig_2_1)
- : IBluetoothTransportInstance{sessionType_2_1, audioConfig_2_1} {}
- IBluetoothSinkTransportInstance(SessionType sessionType,
- AudioConfiguration audioConfig)
- : IBluetoothTransportInstance{sessionType, audioConfig} {}
- virtual ~IBluetoothSinkTransportInstance() = default;
-
- // Invoked when the transport is requested to log bytes read
- virtual void LogBytesRead(size_t bytes_readed) = 0;
-};
-
-class IBluetoothSourceTransportInstance : public IBluetoothTransportInstance {
- public:
- IBluetoothSourceTransportInstance(SessionType sessionType,
- AudioConfiguration audioConfig)
- : IBluetoothTransportInstance{sessionType, audioConfig} {}
- IBluetoothSourceTransportInstance(SessionType_2_1 sessionType_2_1,
- AudioConfiguration_2_1 audioConfig_2_1)
- : IBluetoothTransportInstance{sessionType_2_1, audioConfig_2_1} {}
- virtual ~IBluetoothSourceTransportInstance() = default;
-
- // Invoked when the transport is requested to log bytes written
- virtual void LogBytesWritten(size_t bytes_written) = 0;
-};
-
-// common object is shared between different kind of SessionType
-class BluetoothAudioDeathRecipient;
-
-// The client interface connects an IBluetoothTransportInstance to
-// IBluetoothAudioProvider and helps to route callbacks to
-// IBluetoothTransportInstance
-class BluetoothAudioClientInterface {
- public:
- BluetoothAudioClientInterface(
- android::sp<BluetoothAudioDeathRecipient> death_recipient,
- IBluetoothTransportInstance* instance);
- virtual ~BluetoothAudioClientInterface() = default;
-
- bool IsValid() const {
- return provider_ != nullptr || provider_2_1_ != nullptr;
- }
-
- std::vector<AudioCapabilities> GetAudioCapabilities() const;
- std::vector<AudioCapabilities_2_1> GetAudioCapabilities_2_1() const;
- static std::vector<AudioCapabilities> GetAudioCapabilities(
- SessionType session_type);
- static std::vector<AudioCapabilities_2_1> GetAudioCapabilities_2_1(
- SessionType_2_1 session_type_2_1);
-
- void StreamStarted(const BluetoothAudioCtrlAck& ack);
-
- void StreamSuspended(const BluetoothAudioCtrlAck& ack);
-
- int StartSession();
- int StartSession_2_1();
-
- // Renew the connection and usually is used when HIDL restarted
- void RenewAudioProviderAndSession();
-
- int EndSession();
-
- bool UpdateAudioConfig(const AudioConfiguration& audioConfig);
- bool UpdateAudioConfig_2_1(const AudioConfiguration_2_1& audioConfig_2_1);
-
- void FlushAudioData();
-
- static constexpr PcmParameters kInvalidPcmConfiguration = {
- .sampleRate = SampleRate::RATE_UNKNOWN,
- .channelMode = ChannelMode::UNKNOWN,
- .bitsPerSample = BitsPerSample::BITS_UNKNOWN};
-
- protected:
- mutable std::mutex internal_mutex_;
- // Helper function to connect to an IBluetoothAudioProvider
- void FetchAudioProvider();
- // Helper function to connect to an IBluetoothAudioProvider 2.1
- void FetchAudioProvider_2_1();
-
- android::sp<IBluetoothAudioProvider> provider_;
- android::sp<IBluetoothAudioProvider_2_1> provider_2_1_;
- bool session_started_;
- std::unique_ptr<::android::hardware::MessageQueue<
- uint8_t, ::android::hardware::kSynchronizedReadWrite>>
- mDataMQ;
- android::sp<BluetoothAudioDeathRecipient> death_recipient_;
-
- private:
- IBluetoothTransportInstance* transport_;
- std::vector<AudioCapabilities> capabilities_;
- std::vector<AudioCapabilities_2_1> capabilities_2_1_;
-};
-
-// The client interface connects an IBluetoothTransportInstance to
-// IBluetoothAudioProvider and helps to route callbacks to
-// IBluetoothTransportInstance
-class BluetoothAudioSinkClientInterface : public BluetoothAudioClientInterface {
- public:
- // Constructs an BluetoothAudioSinkClientInterface to communicate to
- // BluetoothAudio HAL. |sink| is the implementation for the transport, and
- // |message_loop| is the thread where callbacks are invoked.
- BluetoothAudioSinkClientInterface(
- IBluetoothSinkTransportInstance* sink,
- bluetooth::common::MessageLoopThread* message_loop);
- virtual ~BluetoothAudioSinkClientInterface();
-
- IBluetoothSinkTransportInstance* GetTransportInstance() const {
- return sink_;
- }
-
- // Read data from audio HAL through fmq
- size_t ReadAudioData(uint8_t* p_buf, uint32_t len);
-
- private:
- IBluetoothSinkTransportInstance* sink_;
-};
-
-class BluetoothAudioSourceClientInterface
- : public BluetoothAudioClientInterface {
- public:
- // Constructs an BluetoothAudioSourceClientInterface to communicate to
- // BluetoothAudio HAL. |source| is the implementation for the transport, and
- // |message_loop| is the thread where callbacks are invoked.
- BluetoothAudioSourceClientInterface(
- IBluetoothSourceTransportInstance* source,
- bluetooth::common::MessageLoopThread* message_loop);
- virtual ~BluetoothAudioSourceClientInterface();
-
- // Write data to audio HAL through fmq
- size_t WriteAudioData(const uint8_t* p_buf, uint32_t len);
-
- private:
- IBluetoothSourceTransportInstance* source_;
-};
-
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/client_interface_unittest.cc b/audio_hal_interface/client_interface_unittest.cc
deleted file mode 100644
index 33954c7..0000000
--- a/audio_hal_interface/client_interface_unittest.cc
+++ /dev/null
@@ -1,871 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#define LOG_TAG "bluetooth"
-
-#include <gtest/gtest.h>
-
-#include "client_interface.h"
-#include "codec_status.h"
-
-namespace {
-
-using ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
-using ::android::hardware::bluetooth::audio::V2_0::AacParameters;
-using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
-using ::android::hardware::bluetooth::audio::V2_0::AptxParameters;
-using ::android::hardware::bluetooth::audio::V2_0::CodecCapabilities;
-using ::android::hardware::bluetooth::audio::V2_0::CodecType;
-using ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode;
-using ::android::hardware::bluetooth::audio::V2_0::LdacParameters;
-using ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex;
-using ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod;
-using ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength;
-using ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode;
-using ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands;
-using ::android::hardware::bluetooth::audio::V2_0::SbcParameters;
-
-using ::bluetooth::audio::AudioCapabilities;
-using ::bluetooth::audio::AudioCapabilities_2_1;
-using ::bluetooth::audio::AudioConfiguration;
-using ::bluetooth::audio::AudioConfiguration_2_1;
-using ::bluetooth::audio::BluetoothAudioClientInterface;
-using ::bluetooth::audio::BluetoothAudioSinkClientInterface;
-using ::bluetooth::audio::BluetoothAudioSourceClientInterface;
-using ::bluetooth::audio::BluetoothAudioStatus;
-using ::bluetooth::audio::PcmParameters;
-using ::bluetooth::audio::PcmParameters_2_1;
-using ::bluetooth::audio::SampleRate;
-using ::bluetooth::audio::SampleRate_2_1;
-using ::bluetooth::audio::SessionType;
-using ::bluetooth::audio::SessionType_2_1;
-using ::bluetooth::audio::codec::A2dpCodecToHalBitsPerSample;
-using ::bluetooth::audio::codec::A2dpCodecToHalChannelMode;
-using ::bluetooth::audio::codec::A2dpCodecToHalSampleRate;
-using ::bluetooth::audio::codec::BitsPerSample;
-using ::bluetooth::audio::codec::ChannelMode;
-using ::bluetooth::audio::codec::CodecConfiguration;
-using ::bluetooth::audio::codec::IsCodecOffloadingEnabled;
-using ::bluetooth::audio::codec::UpdateOffloadingCapabilities;
-using ::testing::Test;
-
-struct SampleRatePair {
- SampleRate hal_sample_rate_;
- btav_a2dp_codec_sample_rate_t btav_sample_rate_;
-};
-constexpr SampleRatePair kSampleRatePairs[9] = {
- {.hal_sample_rate_ = SampleRate::RATE_UNKNOWN,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE},
- {.hal_sample_rate_ = SampleRate::RATE_44100,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_44100},
- {.hal_sample_rate_ = SampleRate::RATE_48000,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_48000},
- {.hal_sample_rate_ = SampleRate::RATE_88200,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_88200},
- {.hal_sample_rate_ = SampleRate::RATE_96000,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_96000},
- {.hal_sample_rate_ = SampleRate::RATE_176400,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_176400},
- {.hal_sample_rate_ = SampleRate::RATE_192000,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_192000},
- {.hal_sample_rate_ = SampleRate::RATE_16000,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_16000},
- {.hal_sample_rate_ = SampleRate::RATE_24000,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_24000}};
-
-constexpr SampleRate_2_1 kSampleRates_2_1[] = {
- SampleRate_2_1::RATE_UNKNOWN, SampleRate_2_1::RATE_8000,
- SampleRate_2_1::RATE_16000, SampleRate_2_1::RATE_24000,
- SampleRate_2_1::RATE_32000, SampleRate_2_1::RATE_44100,
- SampleRate_2_1::RATE_48000};
-
-constexpr uint32_t kDataIntervalUs[] = {0 /* Invalid */,
- 10000 /* Valid 10ms */};
-
-struct BitsPerSamplePair {
- BitsPerSample hal_bits_per_sample_;
- btav_a2dp_codec_bits_per_sample_t btav_bits_per_sample_;
-};
-constexpr BitsPerSamplePair kBitsPerSamplePairs[4] = {
- {.hal_bits_per_sample_ = BitsPerSample::BITS_UNKNOWN,
- .btav_bits_per_sample_ = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE},
- {.hal_bits_per_sample_ = BitsPerSample::BITS_16,
- .btav_bits_per_sample_ = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16},
- {.hal_bits_per_sample_ = BitsPerSample::BITS_24,
- .btav_bits_per_sample_ = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24},
- {.hal_bits_per_sample_ = BitsPerSample::BITS_32,
- .btav_bits_per_sample_ = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32}};
-
-struct ChannelModePair {
- ChannelMode hal_channel_mode_;
- btav_a2dp_codec_channel_mode_t btav_channel_mode_;
-};
-constexpr ChannelModePair kChannelModePairs[3] = {
- {.hal_channel_mode_ = ChannelMode::UNKNOWN,
- .btav_channel_mode_ = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE},
- {.hal_channel_mode_ = ChannelMode::MONO,
- .btav_channel_mode_ = BTAV_A2DP_CODEC_CHANNEL_MODE_MONO},
- {.hal_channel_mode_ = ChannelMode::STEREO,
- .btav_channel_mode_ = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO}};
-
-constexpr btav_a2dp_codec_index_t codec_indexes[] = {
- BTAV_A2DP_CODEC_INDEX_SOURCE_SBC, BTAV_A2DP_CODEC_INDEX_SOURCE_AAC,
- BTAV_A2DP_CODEC_INDEX_SOURCE_APTX, BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD,
- BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC, BTAV_A2DP_CODEC_INDEX_SINK_SBC,
- BTAV_A2DP_CODEC_INDEX_SINK_AAC, BTAV_A2DP_CODEC_INDEX_SINK_LDAC};
-constexpr uint16_t kPeerMtus[5] = {660, 663, 883, 1005, 1500};
-
-class TestSinkTransport
- : public bluetooth::audio::IBluetoothSinkTransportInstance {
- private:
- static constexpr uint64_t kRemoteDelayReportMs = 200;
-
- public:
- TestSinkTransport(SessionType session_type)
- : bluetooth::audio::IBluetoothSinkTransportInstance(session_type, {}){};
- TestSinkTransport(SessionType_2_1 session_type_2_1)
- : bluetooth::audio::IBluetoothSinkTransportInstance(session_type_2_1,
- {}){};
- bluetooth::audio::BluetoothAudioCtrlAck StartRequest() override {
- return bluetooth::audio::BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- }
- bluetooth::audio::BluetoothAudioCtrlAck SuspendRequest() override {
- return bluetooth::audio::BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- }
- void StopRequest() override {}
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_readed,
- timespec* data_position) override {
- if (remote_delay_report_ns) {
- *remote_delay_report_ns = kRemoteDelayReportMs * 1000000;
- }
- if (total_bytes_readed) {
- *total_bytes_readed = 0;
- }
- if (data_position) {
- clock_gettime(CLOCK_MONOTONIC, data_position);
- }
- return true;
- }
- void MetadataChanged(
- const source_metadata_t& source_metadata __unused) override {}
- void ResetPresentationPosition() override{};
- void LogBytesRead(size_t bytes_readed __unused) override{};
-};
-
-class TestSourceTransport
- : public bluetooth::audio::IBluetoothSourceTransportInstance {
- private:
- static constexpr uint64_t kRemoteDelayReportMs = 200;
-
- public:
- TestSourceTransport(SessionType session_type)
- : bluetooth::audio::IBluetoothSourceTransportInstance(session_type, {}){};
- TestSourceTransport(SessionType_2_1 session_type_2_1)
- : bluetooth::audio::IBluetoothSourceTransportInstance(session_type_2_1,
- {}){};
- bluetooth::audio::BluetoothAudioCtrlAck StartRequest() override {
- return bluetooth::audio::BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- }
- bluetooth::audio::BluetoothAudioCtrlAck SuspendRequest() override {
- return bluetooth::audio::BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- }
- void StopRequest() override {}
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_written,
- timespec* data_position) override {
- if (remote_delay_report_ns) {
- *remote_delay_report_ns = kRemoteDelayReportMs * 1000000;
- }
- if (total_bytes_written) {
- *total_bytes_written = 0;
- }
- if (data_position) {
- clock_gettime(CLOCK_MONOTONIC, data_position);
- }
- return true;
- }
- void MetadataChanged(
- const source_metadata_t& source_metadata __unused) override {}
- void ResetPresentationPosition() override{};
- void LogBytesWritten(size_t bytes_written __unused) override{};
-};
-
-class BluetoothAudioClientInterfaceTest : public Test {
- protected:
- TestSinkTransport* test_sink_transport_ = nullptr;
- TestSourceTransport* test_source_transport_ = nullptr;
- BluetoothAudioSinkClientInterface* clientif_sink_ = nullptr;
- BluetoothAudioSourceClientInterface* clientif_source_ = nullptr;
-
- static constexpr int kClientIfReturnSuccess = 0;
-
- void SetUp() override {}
-
- void TearDown() override {
- if (clientif_sink_ != nullptr) delete clientif_sink_;
- clientif_sink_ = nullptr;
- if (test_sink_transport_ != nullptr) delete test_sink_transport_;
- test_sink_transport_ = nullptr;
-
- if (clientif_source_ != nullptr) delete clientif_source_;
- clientif_source_ = nullptr;
- if (test_source_transport_ != nullptr) delete test_source_transport_;
- test_source_transport_ = nullptr;
- }
-
- bool IsSoftwarePcmParametersSupported(const PcmParameters& pcm_config) {
- const std::vector<AudioCapabilities>& capabilities =
- clientif_sink_->GetAudioCapabilities();
- PcmParameters pcm_capabilities = capabilities[0].pcmCapabilities();
- bool is_pcm_config_valid =
- (pcm_config.sampleRate != SampleRate::RATE_UNKNOWN &&
- pcm_config.bitsPerSample != BitsPerSample::BITS_UNKNOWN &&
- pcm_config.channelMode != ChannelMode::UNKNOWN);
- bool is_pcm_config_supported =
- (pcm_config.sampleRate & pcm_capabilities.sampleRate &&
- pcm_config.bitsPerSample & pcm_capabilities.bitsPerSample &&
- pcm_config.channelMode & pcm_capabilities.channelMode);
- return (is_pcm_config_valid && is_pcm_config_supported);
- }
-
- bool IsSinkSoftwarePcmParameters_2_1_Supported(
- const PcmParameters_2_1& pcm_config) {
- return IsSoftwarePcmParameters_2_1_Supported(pcm_config, clientif_sink_);
- }
-
- bool IsSourceSoftwarePcmParameters_2_1_Supported(
- const PcmParameters_2_1& pcm_config) {
- return IsSoftwarePcmParameters_2_1_Supported(pcm_config, clientif_source_);
- }
-
- bool IsCodecOffloadingSupported(const CodecConfiguration& codec_config) {
- CodecCapabilities codec_capability = {};
- for (auto audio_capability : clientif_sink_->GetAudioCapabilities()) {
- if (audio_capability.codecCapabilities().codecType ==
- codec_config.codecType) {
- codec_capability = audio_capability.codecCapabilities();
- }
- }
- if (codec_capability.codecType != codec_config.codecType) {
- // codec is unsupported
- return false;
- }
- bool is_codec_config_supported = false;
- switch (codec_config.codecType) {
- case CodecType::SBC: {
- SbcParameters sbc_config = codec_config.config.sbcConfig();
- SbcParameters sbc_capability =
- codec_capability.capabilities.sbcCapabilities();
- is_codec_config_supported =
- (sbc_config.sampleRate & sbc_capability.sampleRate &&
- sbc_config.channelMode & sbc_capability.channelMode &&
- sbc_config.blockLength & sbc_capability.blockLength &&
- sbc_config.numSubbands & sbc_capability.numSubbands &&
- sbc_config.allocMethod & sbc_capability.allocMethod &&
- sbc_config.bitsPerSample & sbc_capability.bitsPerSample &&
- (sbc_capability.minBitpool <= sbc_config.minBitpool &&
- sbc_config.minBitpool <= sbc_config.maxBitpool &&
- sbc_config.maxBitpool <= sbc_capability.maxBitpool));
- return is_codec_config_supported;
- }
- case CodecType::AAC: {
- AacParameters aac_config = codec_config.config.aacConfig();
- AacParameters aac_capability =
- codec_capability.capabilities.aacCapabilities();
- is_codec_config_supported =
- (aac_config.objectType & aac_capability.objectType &&
- aac_config.sampleRate & aac_capability.sampleRate &&
- aac_config.channelMode & aac_capability.channelMode &&
- (aac_config.variableBitRateEnabled ==
- AacVariableBitRate::DISABLED ||
- aac_capability.variableBitRateEnabled ==
- AacVariableBitRate::ENABLED) &&
- aac_config.bitsPerSample & aac_capability.bitsPerSample);
- return is_codec_config_supported;
- }
- case CodecType::LDAC: {
- LdacParameters ldac_config = codec_config.config.ldacConfig();
- LdacParameters ldac_capability =
- codec_capability.capabilities.ldacCapabilities();
- is_codec_config_supported =
- (ldac_config.sampleRate & ldac_capability.sampleRate &&
- ldac_config.channelMode & ldac_capability.channelMode &&
- ldac_config.bitsPerSample & ldac_capability.bitsPerSample);
- return is_codec_config_supported;
- }
- case CodecType::APTX:
- [[fallthrough]];
- case CodecType::APTX_HD: {
- AptxParameters aptx_config = codec_config.config.aptxConfig();
- AptxParameters aptx_capability =
- codec_capability.capabilities.aptxCapabilities();
- is_codec_config_supported =
- (aptx_config.sampleRate & aptx_capability.sampleRate &&
- aptx_config.channelMode & aptx_capability.channelMode &&
- aptx_config.bitsPerSample & aptx_capability.bitsPerSample);
- return is_codec_config_supported;
- }
- case CodecType::UNKNOWN:
- return false;
- }
- }
-
- private:
- bool IsSoftwarePcmParameters_2_1_Supported(
- const PcmParameters_2_1& pcm_config,
- const BluetoothAudioClientInterface* clientif_) {
- const std::vector<AudioCapabilities_2_1>& capabilities =
- clientif_->GetAudioCapabilities_2_1();
- PcmParameters_2_1 pcm_capabilities = capabilities[0].pcmCapabilities();
- bool is_pcm_config_valid =
- (pcm_config.sampleRate != SampleRate_2_1::RATE_UNKNOWN &&
- pcm_config.bitsPerSample != BitsPerSample::BITS_UNKNOWN &&
- pcm_config.channelMode != ChannelMode::UNKNOWN &&
- pcm_config.dataIntervalUs != 0);
- bool is_pcm_config_supported =
- (pcm_config.sampleRate & pcm_capabilities.sampleRate &&
- pcm_config.bitsPerSample & pcm_capabilities.bitsPerSample &&
- pcm_config.channelMode & pcm_capabilities.channelMode);
- return (is_pcm_config_valid && is_pcm_config_supported);
- }
-};
-
-} // namespace
-
-TEST_F(BluetoothAudioClientInterfaceTest, A2dpCodecToHalPcmConfig) {
- btav_a2dp_codec_config_t a2dp_codec_config = {};
- for (auto sample_rate_pair : kSampleRatePairs) {
- a2dp_codec_config.sample_rate = sample_rate_pair.btav_sample_rate_;
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- a2dp_codec_config.bits_per_sample =
- bits_per_sample_pair.btav_bits_per_sample_;
- for (auto channel_mode_pair : kChannelModePairs) {
- a2dp_codec_config.channel_mode = channel_mode_pair.btav_channel_mode_;
- ASSERT_EQ(A2dpCodecToHalSampleRate(a2dp_codec_config),
- sample_rate_pair.hal_sample_rate_);
- ASSERT_EQ(A2dpCodecToHalBitsPerSample(a2dp_codec_config),
- bits_per_sample_pair.hal_bits_per_sample_);
- ASSERT_EQ(A2dpCodecToHalChannelMode(a2dp_codec_config),
- channel_mode_pair.hal_channel_mode_);
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpSoftwareSession) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration audio_config = {};
- PcmParameters pcm_config = {};
- for (auto sample_rate_pair : kSampleRatePairs) {
- pcm_config.sampleRate = sample_rate_pair.hal_sample_rate_;
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- pcm_config.bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_;
- for (auto channel_mode_pair : kChannelModePairs) {
- pcm_config.channelMode = channel_mode_pair.hal_channel_mode_;
- audio_config.pcmConfig(pcm_config);
- clientif_sink_->UpdateAudioConfig(audio_config);
- if (IsSoftwarePcmParametersSupported(pcm_config)) {
- ASSERT_EQ(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
-}
-
-struct CodecOffloadingPreference {
- bool is_target_codec_included_;
- std::vector<btav_a2dp_codec_config_t> preference_;
-};
-
-std::vector<CodecOffloadingPreference> CodecOffloadingPreferenceGenerator(
- btav_a2dp_codec_index_t target_codec_index) {
- std::vector<CodecOffloadingPreference> codec_offloading_preferences = {
- {.is_target_codec_included_ = false,
- .preference_ = std::vector<btav_a2dp_codec_config_t>(0)}};
- btav_a2dp_codec_config_t a2dp_codec_config = {};
- for (auto codec_index : codec_indexes) {
- a2dp_codec_config.codec_type = codec_index;
- auto duplicated_preferences = codec_offloading_preferences;
- for (auto iter = duplicated_preferences.begin();
- iter != duplicated_preferences.end(); ++iter) {
- if (codec_index == target_codec_index) {
- iter->is_target_codec_included_ = true;
- }
- iter->preference_.push_back(a2dp_codec_config);
- }
- codec_offloading_preferences.insert(codec_offloading_preferences.end(),
- duplicated_preferences.begin(),
- duplicated_preferences.end());
- }
- return codec_offloading_preferences;
-}
-
-std::vector<CodecConfiguration> SbcCodecConfigurationsGenerator() {
- std::vector<CodecConfiguration> sbc_codec_configs;
- CodecConfiguration codec_config = {};
- SbcBlockLength block_lengths[4] = {
- SbcBlockLength::BLOCKS_4, SbcBlockLength::BLOCKS_8,
- SbcBlockLength::BLOCKS_12, SbcBlockLength::BLOCKS_16};
- SbcNumSubbands num_subbands[2] = {SbcNumSubbands::SUBBAND_4,
- SbcNumSubbands::SUBBAND_8};
- SbcAllocMethod alloc_methods[2] = {SbcAllocMethod::ALLOC_MD_S,
- SbcAllocMethod::ALLOC_MD_L};
- for (auto sample_rate_pair : kSampleRatePairs) {
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- for (auto channel_mode_pair : kChannelModePairs) {
- for (auto peer_mtu : kPeerMtus) {
- for (auto block_length : block_lengths) {
- for (auto num_subband : num_subbands) {
- for (auto alloc_method : alloc_methods) {
- codec_config.codecType = CodecType::SBC;
- codec_config.peerMtu = peer_mtu;
- codec_config.isScmstEnabled = false;
- // A2DP_SBC_DEFAULT_BITRATE
- codec_config.encodedAudioBitrate = 328000;
- SbcParameters sbc = {
- .sampleRate = sample_rate_pair.hal_sample_rate_,
- .channelMode = (channel_mode_pair.hal_channel_mode_ ==
- ChannelMode::MONO
- ? SbcChannelMode::MONO
- : SbcChannelMode::JOINT_STEREO),
- .blockLength = block_length,
- .numSubbands = num_subband,
- .allocMethod = alloc_method,
- .bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_,
- .minBitpool = 2,
- .maxBitpool = 53};
- codec_config.config.sbcConfig(sbc);
- sbc_codec_configs.push_back(codec_config);
- } // SbcAllocMethod
- } // SbcNumSubbands
- } // SbcBlockLength
- } // peerMtu
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
- return sbc_codec_configs;
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, A2dpSbcCodecOffloadingState) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- auto sbc_codec_configs = SbcCodecConfigurationsGenerator();
- for (auto codec_offloading_preference :
- CodecOffloadingPreferenceGenerator(BTAV_A2DP_CODEC_INDEX_SOURCE_SBC)) {
- UpdateOffloadingCapabilities(codec_offloading_preference.preference_);
- for (CodecConfiguration codec_config : sbc_codec_configs) {
- if (IsCodecOffloadingSupported(codec_config) &&
- codec_offloading_preference.is_target_codec_included_) {
- ASSERT_TRUE(IsCodecOffloadingEnabled(codec_config));
- } else {
- ASSERT_FALSE(IsCodecOffloadingEnabled(codec_config));
- }
- }
- }
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadSbcSession) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration audio_config = {};
- for (CodecConfiguration codec_config : SbcCodecConfigurationsGenerator()) {
- audio_config.codecConfig(codec_config);
- clientif_sink_->UpdateAudioConfig(audio_config);
- if (IsCodecOffloadingSupported(codec_config)) {
- ASSERT_EQ(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
- }
-}
-
-std::vector<CodecConfiguration> AacCodecConfigurationsGenerator() {
- std::vector<CodecConfiguration> aac_codec_configs;
- CodecConfiguration codec_config = {};
- AacObjectType object_types[4] = {
- AacObjectType::MPEG2_LC, AacObjectType::MPEG4_LC,
- AacObjectType::MPEG4_LTP, AacObjectType::MPEG4_SCALABLE};
- AacVariableBitRate variable_bitrates[2] = {AacVariableBitRate::DISABLED,
- AacVariableBitRate::ENABLED};
- for (auto sample_rate_pair : kSampleRatePairs) {
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- for (auto channel_mode_pair : kChannelModePairs) {
- for (auto peer_mtu : kPeerMtus) {
- for (auto object_type : object_types) {
- for (auto variable_bitrate : variable_bitrates) {
- codec_config.codecType = CodecType::AAC;
- codec_config.peerMtu = peer_mtu;
- codec_config.isScmstEnabled = false;
- // A2DP_AAC_DEFAULT_BITRATE
- codec_config.encodedAudioBitrate = 320000;
- AacParameters aac = {
- .objectType = object_type,
- .sampleRate = sample_rate_pair.hal_sample_rate_,
- .channelMode = channel_mode_pair.hal_channel_mode_,
- .variableBitRateEnabled = variable_bitrate,
- .bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_};
- codec_config.config.aacConfig(aac);
- aac_codec_configs.push_back(codec_config);
- } // AacVariableBitRate
- } // AacObjectType
- } // peerMtu
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
- return aac_codec_configs;
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, A2dpAacCodecOffloadingState) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- auto aac_codec_configs = AacCodecConfigurationsGenerator();
- for (auto codec_offloading_preference :
- CodecOffloadingPreferenceGenerator(BTAV_A2DP_CODEC_INDEX_SOURCE_AAC)) {
- UpdateOffloadingCapabilities(codec_offloading_preference.preference_);
- for (CodecConfiguration codec_config : aac_codec_configs) {
- if (IsCodecOffloadingSupported(codec_config) &&
- codec_offloading_preference.is_target_codec_included_) {
- ASSERT_TRUE(IsCodecOffloadingEnabled(codec_config));
- } else {
- ASSERT_FALSE(IsCodecOffloadingEnabled(codec_config));
- }
- }
- }
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAacSession) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration audio_config = {};
- for (CodecConfiguration codec_config : AacCodecConfigurationsGenerator()) {
- audio_config.codecConfig(codec_config);
- clientif_sink_->UpdateAudioConfig(audio_config);
- if (IsCodecOffloadingSupported(codec_config)) {
- ASSERT_EQ(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
- }
-}
-
-std::vector<CodecConfiguration> LdacCodecConfigurationsGenerator() {
- std::vector<CodecConfiguration> ldac_codec_configs;
- CodecConfiguration codec_config = {};
- LdacQualityIndex quality_indexes[4] = {
- LdacQualityIndex::QUALITY_HIGH, LdacQualityIndex::QUALITY_MID,
- LdacQualityIndex::QUALITY_LOW, LdacQualityIndex::QUALITY_ABR};
- for (auto sample_rate_pair : kSampleRatePairs) {
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- for (auto channel_mode_pair : kChannelModePairs) {
- for (auto peer_mtu : kPeerMtus) {
- for (auto quality_index : quality_indexes) {
- codec_config.codecType = CodecType::LDAC;
- codec_config.peerMtu = peer_mtu;
- codec_config.isScmstEnabled = false;
- codec_config.encodedAudioBitrate = 990000;
- LdacParameters ldac = {
- .sampleRate = sample_rate_pair.hal_sample_rate_,
- .channelMode =
- (channel_mode_pair.hal_channel_mode_ == ChannelMode::MONO
- ? LdacChannelMode::MONO
- : LdacChannelMode::STEREO),
- .qualityIndex = quality_index,
- .bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_};
- codec_config.config.ldacConfig(ldac);
- ldac_codec_configs.push_back(codec_config);
- } // LdacQualityIndex
- } // peerMtu
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
- return ldac_codec_configs;
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, A2dpLdacCodecOffloadingState) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- auto ldac_codec_configs = LdacCodecConfigurationsGenerator();
- for (auto codec_offloading_preference :
- CodecOffloadingPreferenceGenerator(BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC)) {
- UpdateOffloadingCapabilities(codec_offloading_preference.preference_);
- for (CodecConfiguration codec_config : ldac_codec_configs) {
- if (IsCodecOffloadingSupported(codec_config) &&
- codec_offloading_preference.is_target_codec_included_) {
- ASSERT_TRUE(IsCodecOffloadingEnabled(codec_config));
- } else {
- ASSERT_FALSE(IsCodecOffloadingEnabled(codec_config));
- }
- }
- }
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadLdacSession) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration audio_config = {};
- for (CodecConfiguration codec_config : LdacCodecConfigurationsGenerator()) {
- audio_config.codecConfig(codec_config);
- clientif_sink_->UpdateAudioConfig(audio_config);
- if (IsCodecOffloadingSupported(codec_config)) {
- ASSERT_EQ(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
- }
-}
-
-std::vector<CodecConfiguration> AptxCodecConfigurationsGenerator(
- CodecType codec_type) {
- std::vector<CodecConfiguration> aptx_codec_configs;
- if (codec_type != CodecType::APTX && codec_type != CodecType::APTX_HD)
- return aptx_codec_configs;
- CodecConfiguration codec_config = {};
- for (auto sample_rate_pair : kSampleRatePairs) {
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- for (auto channel_mode_pair : kChannelModePairs) {
- for (auto peer_mtu : kPeerMtus) {
- codec_config.codecType = codec_type;
- codec_config.peerMtu = peer_mtu;
- codec_config.isScmstEnabled = false;
- codec_config.encodedAudioBitrate =
- (codec_type == CodecType::APTX ? 352000 : 576000);
- AptxParameters aptx = {
- .sampleRate = sample_rate_pair.hal_sample_rate_,
- .channelMode = channel_mode_pair.hal_channel_mode_,
- .bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_};
- codec_config.config.aptxConfig(aptx);
- aptx_codec_configs.push_back(codec_config);
- } // peerMtu
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
- return aptx_codec_configs;
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, A2dpAptxCodecOffloadingState) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- auto aptx_codec_configs = AptxCodecConfigurationsGenerator(CodecType::APTX);
- for (auto codec_offloading_preference :
- CodecOffloadingPreferenceGenerator(BTAV_A2DP_CODEC_INDEX_SOURCE_APTX)) {
- UpdateOffloadingCapabilities(codec_offloading_preference.preference_);
- for (CodecConfiguration codec_config : aptx_codec_configs) {
- if (IsCodecOffloadingSupported(codec_config) &&
- codec_offloading_preference.is_target_codec_included_) {
- ASSERT_TRUE(IsCodecOffloadingEnabled(codec_config));
- } else {
- ASSERT_FALSE(IsCodecOffloadingEnabled(codec_config));
- }
- }
- }
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAptxSession) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration audio_config = {};
- for (CodecConfiguration codec_config :
- AptxCodecConfigurationsGenerator(CodecType::APTX)) {
- audio_config.codecConfig(codec_config);
- clientif_sink_->UpdateAudioConfig(audio_config);
- if (IsCodecOffloadingSupported(codec_config)) {
- ASSERT_EQ(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
- }
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, A2dpAptxHdCodecOffloadingState) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- auto aptx_hd_codec_configs =
- AptxCodecConfigurationsGenerator(CodecType::APTX_HD);
- for (auto codec_offloading_preference : CodecOffloadingPreferenceGenerator(
- BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD)) {
- UpdateOffloadingCapabilities(codec_offloading_preference.preference_);
- for (CodecConfiguration codec_config : aptx_hd_codec_configs) {
- if (IsCodecOffloadingSupported(codec_config) &&
- codec_offloading_preference.is_target_codec_included_) {
- ASSERT_TRUE(IsCodecOffloadingEnabled(codec_config));
- } else {
- ASSERT_FALSE(IsCodecOffloadingEnabled(codec_config));
- }
- }
- }
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAptxHdSession) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration audio_config = {};
- for (CodecConfiguration codec_config :
- AptxCodecConfigurationsGenerator(CodecType::APTX_HD)) {
- audio_config.codecConfig(codec_config);
- clientif_sink_->UpdateAudioConfig(audio_config);
- if (IsCodecOffloadingSupported(codec_config)) {
- ASSERT_EQ(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
- }
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest,
- StartAndEndA2dpOffloadUnknownSession) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration audio_config = {};
- CodecConfiguration codec_config = {};
- codec_config.codecType = CodecType::UNKNOWN;
- codec_config.peerMtu = 1005;
- codec_config.isScmstEnabled = false;
- codec_config.encodedAudioBitrate = 328000;
- codec_config.config = {};
- audio_config.codecConfig(codec_config);
- clientif_sink_->UpdateAudioConfig(audio_config);
- if (IsCodecOffloadingSupported(codec_config)) {
- ASSERT_EQ(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest,
- StartAndEndHearingAidSoftwareSession) {
- test_sink_transport_ = new TestSinkTransport(
- SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration audio_config = {};
- PcmParameters pcm_config = {};
- for (auto sample_rate_pair : kSampleRatePairs) {
- pcm_config.sampleRate = sample_rate_pair.hal_sample_rate_;
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- pcm_config.bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_;
- for (auto channel_mode_pair : kChannelModePairs) {
- pcm_config.channelMode = channel_mode_pair.hal_channel_mode_;
- audio_config.pcmConfig(pcm_config);
- clientif_sink_->UpdateAudioConfig(audio_config);
- if (IsSoftwarePcmParametersSupported(pcm_config)) {
- ASSERT_EQ(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest,
- StartAndEndLeAudioEncodingSoftwareSession) {
- test_sink_transport_ = new TestSinkTransport(
- SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration_2_1 audio_config = {};
- PcmParameters_2_1 pcm_config = {};
- for (auto sample_rate : kSampleRates_2_1) {
- pcm_config.sampleRate = sample_rate;
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- pcm_config.bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_;
- for (auto channel_mode_pair : kChannelModePairs) {
- pcm_config.channelMode = channel_mode_pair.hal_channel_mode_;
- for (auto data_interval_us : kDataIntervalUs) {
- pcm_config.dataIntervalUs = data_interval_us;
- audio_config.pcmConfig(pcm_config);
- clientif_sink_->UpdateAudioConfig_2_1(audio_config);
- if (IsSinkSoftwarePcmParameters_2_1_Supported(pcm_config)) {
- ASSERT_EQ(clientif_sink_->StartSession_2_1(),
- kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession_2_1(),
- kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
- } // dataIntervalUs
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest,
- StartAndEndLeAudioDecodedSoftwareSession) {
- test_source_transport_ = new TestSourceTransport(
- SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
- clientif_source_ =
- new BluetoothAudioSourceClientInterface(test_source_transport_, nullptr);
- AudioConfiguration_2_1 audio_config = {};
- PcmParameters_2_1 pcm_config = {};
- for (auto sample_rate : kSampleRates_2_1) {
- pcm_config.sampleRate = sample_rate;
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- pcm_config.bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_;
- for (auto channel_mode_pair : kChannelModePairs) {
- pcm_config.channelMode = channel_mode_pair.hal_channel_mode_;
- for (auto data_interval_us : kDataIntervalUs) {
- pcm_config.dataIntervalUs = data_interval_us;
- audio_config.pcmConfig(pcm_config);
- clientif_source_->UpdateAudioConfig_2_1(audio_config);
- if (IsSourceSoftwarePcmParameters_2_1_Supported(pcm_config)) {
- ASSERT_EQ(clientif_source_->StartSession_2_1(),
- kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_source_->StartSession_2_1(),
- kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_source_->EndSession(), kClientIfReturnSuccess);
- } // dataIntervalUs
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
-}
diff --git a/audio_hal_interface/codec_status.cc b/audio_hal_interface/codec_status.cc
deleted file mode 100644
index 1287066..0000000
--- a/audio_hal_interface/codec_status.cc
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#define LOG_TAG "bluetooth"
-
-#include "codec_status.h"
-#include "client_interface.h"
-
-#include "a2dp_aac_constants.h"
-#include "a2dp_sbc_constants.h"
-#include "a2dp_vendor_aptx_constants.h"
-#include "a2dp_vendor_aptx_hd_constants.h"
-#include "a2dp_vendor_ldac_constants.h"
-#include "bta/av/bta_av_int.h"
-
-namespace {
-
-using ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
-using ::android::hardware::bluetooth::audio::V2_0::AacParameters;
-using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
-using ::android::hardware::bluetooth::audio::V2_0::AptxParameters;
-using ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
-using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
-using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
-using ::android::hardware::bluetooth::audio::V2_0::CodecType;
-using ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode;
-using ::android::hardware::bluetooth::audio::V2_0::LdacParameters;
-using ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex;
-using ::android::hardware::bluetooth::audio::V2_0::SampleRate;
-using ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod;
-using ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength;
-using ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode;
-using ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands;
-using ::android::hardware::bluetooth::audio::V2_0::SbcParameters;
-
-// capabilities from BluetoothAudioSinkClientInterface::GetAudioCapabilities()
-std::vector<AudioCapabilities> audio_hal_capabilities(0);
-// capabilities that audio HAL supports and frameworks / Bluetooth SoC / runtime
-// preference would like to use.
-std::vector<AudioCapabilities> offloading_preference(0);
-
-bool sbc_offloading_capability_match(const SbcParameters& sbc_capability,
- const SbcParameters& sbc_config) {
- if ((static_cast<SampleRate>(sbc_capability.sampleRate &
- sbc_config.sampleRate) ==
- SampleRate::RATE_UNKNOWN) ||
- (static_cast<SbcChannelMode>(sbc_capability.channelMode &
- sbc_config.channelMode) ==
- SbcChannelMode::UNKNOWN) ||
- (static_cast<SbcBlockLength>(sbc_capability.blockLength &
- sbc_config.blockLength) ==
- static_cast<SbcBlockLength>(0)) ||
- (static_cast<SbcNumSubbands>(sbc_capability.numSubbands &
- sbc_config.numSubbands) ==
- static_cast<SbcNumSubbands>(0)) ||
- (static_cast<SbcAllocMethod>(sbc_capability.allocMethod &
- sbc_config.allocMethod) ==
- static_cast<SbcAllocMethod>(0)) ||
- (static_cast<BitsPerSample>(sbc_capability.bitsPerSample &
- sbc_config.bitsPerSample) ==
- BitsPerSample::BITS_UNKNOWN) ||
- (sbc_config.minBitpool < sbc_capability.minBitpool ||
- sbc_config.maxBitpool < sbc_config.minBitpool ||
- sbc_capability.maxBitpool < sbc_config.maxBitpool)) {
- LOG(WARNING) << __func__ << ": software codec=" << toString(sbc_config)
- << " capability=" << toString(sbc_capability);
- return false;
- }
- VLOG(1) << __func__ << ": offloading codec=" << toString(sbc_config)
- << " capability=" << toString(sbc_capability);
- return true;
-}
-
-bool aac_offloading_capability_match(const AacParameters& aac_capability,
- const AacParameters& aac_config) {
- if ((static_cast<AacObjectType>(aac_capability.objectType &
- aac_config.objectType) ==
- static_cast<AacObjectType>(0)) ||
- (static_cast<SampleRate>(aac_capability.sampleRate &
- aac_config.sampleRate) ==
- SampleRate::RATE_UNKNOWN) ||
- (static_cast<ChannelMode>(aac_capability.channelMode &
- aac_config.channelMode) ==
- ChannelMode::UNKNOWN) ||
- (aac_capability.variableBitRateEnabled != AacVariableBitRate::ENABLED &&
- aac_config.variableBitRateEnabled != AacVariableBitRate::DISABLED) ||
- (static_cast<BitsPerSample>(aac_capability.bitsPerSample &
- aac_config.bitsPerSample) ==
- BitsPerSample::BITS_UNKNOWN)) {
- LOG(WARNING) << __func__ << ": software codec=" << toString(aac_config)
- << " capability=" << toString(aac_capability);
- return false;
- }
- VLOG(1) << __func__ << ": offloading codec=" << toString(aac_config)
- << " capability=" << toString(aac_capability);
- return true;
-}
-
-bool aptx_offloading_capability_match(const AptxParameters& aptx_capability,
- const AptxParameters& aptx_config) {
- if ((static_cast<SampleRate>(aptx_capability.sampleRate &
- aptx_config.sampleRate) ==
- SampleRate::RATE_UNKNOWN) ||
- (static_cast<ChannelMode>(aptx_capability.channelMode &
- aptx_config.channelMode) ==
- ChannelMode::UNKNOWN) ||
- (static_cast<BitsPerSample>(aptx_capability.bitsPerSample &
- aptx_config.bitsPerSample) ==
- BitsPerSample::BITS_UNKNOWN)) {
- LOG(WARNING) << __func__ << ": software codec=" << toString(aptx_config)
- << " capability=" << toString(aptx_capability);
- return false;
- }
- VLOG(1) << __func__ << ": offloading codec=" << toString(aptx_config)
- << " capability=" << toString(aptx_capability);
- return true;
-}
-
-bool ldac_offloading_capability_match(const LdacParameters& ldac_capability,
- const LdacParameters& ldac_config) {
- if ((static_cast<SampleRate>(ldac_capability.sampleRate &
- ldac_config.sampleRate) ==
- SampleRate::RATE_UNKNOWN) ||
- (static_cast<LdacChannelMode>(ldac_capability.channelMode &
- ldac_config.channelMode) ==
- LdacChannelMode::UNKNOWN) ||
- (static_cast<BitsPerSample>(ldac_capability.bitsPerSample &
- ldac_config.bitsPerSample) ==
- BitsPerSample::BITS_UNKNOWN)) {
- LOG(WARNING) << __func__ << ": software codec=" << toString(ldac_config)
- << " capability=" << toString(ldac_capability);
- return false;
- }
- VLOG(1) << __func__ << ": offloading codec=" << toString(ldac_config)
- << " capability=" << toString(ldac_capability);
- return true;
-}
-} // namespace
-
-namespace bluetooth {
-namespace audio {
-namespace codec {
-
-const CodecConfiguration kInvalidCodecConfiguration = {
- .codecType = CodecType::UNKNOWN,
- .encodedAudioBitrate = 0x00000000,
- .peerMtu = 0xffff,
- .isScmstEnabled = false,
- .config = {}};
-
-SampleRate A2dpCodecToHalSampleRate(
- const btav_a2dp_codec_config_t& a2dp_codec_config) {
- switch (a2dp_codec_config.sample_rate) {
- case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
- return SampleRate::RATE_44100;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
- return SampleRate::RATE_48000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
- return SampleRate::RATE_88200;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
- return SampleRate::RATE_96000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
- return SampleRate::RATE_176400;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
- return SampleRate::RATE_192000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
- return SampleRate::RATE_16000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
- return SampleRate::RATE_24000;
- default:
- return SampleRate::RATE_UNKNOWN;
- }
-}
-
-BitsPerSample A2dpCodecToHalBitsPerSample(
- const btav_a2dp_codec_config_t& a2dp_codec_config) {
- switch (a2dp_codec_config.bits_per_sample) {
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
- return BitsPerSample::BITS_16;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
- return BitsPerSample::BITS_24;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
- return BitsPerSample::BITS_32;
- default:
- return BitsPerSample::BITS_UNKNOWN;
- }
-}
-
-ChannelMode A2dpCodecToHalChannelMode(
- const btav_a2dp_codec_config_t& a2dp_codec_config) {
- switch (a2dp_codec_config.channel_mode) {
- case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
- return ChannelMode::MONO;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
- return ChannelMode::STEREO;
- default:
- return ChannelMode::UNKNOWN;
- }
-}
-
-bool A2dpSbcToHalConfig(CodecConfiguration* codec_config,
- A2dpCodecConfig* a2dp_config) {
- btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
- if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_SBC &&
- current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SINK_SBC) {
- *codec_config = {};
- return false;
- }
- tBT_A2DP_OFFLOAD a2dp_offload;
- a2dp_config->getCodecSpecificConfig(&a2dp_offload);
- codec_config->codecType = CodecType::SBC;
- codec_config->config.sbcConfig({});
- auto sbc_config = codec_config->config.sbcConfig();
- sbc_config.sampleRate = A2dpCodecToHalSampleRate(current_codec);
- if (sbc_config.sampleRate == SampleRate::RATE_UNKNOWN) {
- LOG(ERROR) << __func__
- << ": Unknown SBC sample_rate=" << current_codec.sample_rate;
- return false;
- }
- uint8_t channel_mode = a2dp_offload.codec_info[3] & A2DP_SBC_IE_CH_MD_MSK;
- switch (channel_mode) {
- case A2DP_SBC_IE_CH_MD_JOINT:
- sbc_config.channelMode = SbcChannelMode::JOINT_STEREO;
- break;
- case A2DP_SBC_IE_CH_MD_STEREO:
- sbc_config.channelMode = SbcChannelMode::STEREO;
- break;
- case A2DP_SBC_IE_CH_MD_DUAL:
- sbc_config.channelMode = SbcChannelMode::DUAL;
- break;
- case A2DP_SBC_IE_CH_MD_MONO:
- sbc_config.channelMode = SbcChannelMode::MONO;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown SBC channel_mode=" << channel_mode;
- sbc_config.channelMode = SbcChannelMode::UNKNOWN;
- return false;
- }
- uint8_t block_length = a2dp_offload.codec_info[0] & A2DP_SBC_IE_BLOCKS_MSK;
- switch (block_length) {
- case A2DP_SBC_IE_BLOCKS_4:
- sbc_config.blockLength = SbcBlockLength::BLOCKS_4;
- break;
- case A2DP_SBC_IE_BLOCKS_8:
- sbc_config.blockLength = SbcBlockLength::BLOCKS_8;
- break;
- case A2DP_SBC_IE_BLOCKS_12:
- sbc_config.blockLength = SbcBlockLength::BLOCKS_12;
- break;
- case A2DP_SBC_IE_BLOCKS_16:
- sbc_config.blockLength = SbcBlockLength::BLOCKS_16;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown SBC block_length=" << block_length;
- return false;
- }
- uint8_t sub_bands = a2dp_offload.codec_info[0] & A2DP_SBC_IE_SUBBAND_MSK;
- switch (sub_bands) {
- case A2DP_SBC_IE_SUBBAND_4:
- sbc_config.numSubbands = SbcNumSubbands::SUBBAND_4;
- break;
- case A2DP_SBC_IE_SUBBAND_8:
- sbc_config.numSubbands = SbcNumSubbands::SUBBAND_8;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown SBC Subbands=" << sub_bands;
- return false;
- }
- uint8_t alloc_method = a2dp_offload.codec_info[0] & A2DP_SBC_IE_ALLOC_MD_MSK;
- switch (alloc_method) {
- case A2DP_SBC_IE_ALLOC_MD_S:
- sbc_config.allocMethod = SbcAllocMethod::ALLOC_MD_S;
- break;
- case A2DP_SBC_IE_ALLOC_MD_L:
- sbc_config.allocMethod = SbcAllocMethod::ALLOC_MD_L;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown SBC alloc_method=" << alloc_method;
- return false;
- }
- sbc_config.minBitpool = a2dp_offload.codec_info[1];
- sbc_config.maxBitpool = a2dp_offload.codec_info[2];
- sbc_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
- if (sbc_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
- LOG(ERROR) << __func__ << ": Unknown SBC bits_per_sample="
- << current_codec.bits_per_sample;
- return false;
- }
- codec_config->config.sbcConfig(sbc_config);
- return true;
-}
-
-bool A2dpAacToHalConfig(CodecConfiguration* codec_config,
- A2dpCodecConfig* a2dp_config) {
- btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
- if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_AAC &&
- current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SINK_AAC) {
- *codec_config = {};
- return false;
- }
- tBT_A2DP_OFFLOAD a2dp_offload;
- a2dp_config->getCodecSpecificConfig(&a2dp_offload);
- codec_config->codecType = CodecType::AAC;
- codec_config->config.aacConfig({});
- auto aac_config = codec_config->config.aacConfig();
- uint8_t object_type = a2dp_offload.codec_info[0];
- switch (object_type) {
- case A2DP_AAC_OBJECT_TYPE_MPEG2_LC:
- aac_config.objectType = AacObjectType::MPEG2_LC;
- break;
- case A2DP_AAC_OBJECT_TYPE_MPEG4_LC:
- aac_config.objectType = AacObjectType::MPEG4_LC;
- break;
- case A2DP_AAC_OBJECT_TYPE_MPEG4_LTP:
- aac_config.objectType = AacObjectType::MPEG4_LTP;
- break;
- case A2DP_AAC_OBJECT_TYPE_MPEG4_SCALABLE:
- aac_config.objectType = AacObjectType::MPEG4_SCALABLE;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown AAC object_type=" << +object_type;
- return false;
- }
- aac_config.sampleRate = A2dpCodecToHalSampleRate(current_codec);
- if (aac_config.sampleRate == SampleRate::RATE_UNKNOWN) {
- LOG(ERROR) << __func__
- << ": Unknown AAC sample_rate=" << current_codec.sample_rate;
- return false;
- }
- aac_config.channelMode = A2dpCodecToHalChannelMode(current_codec);
- if (aac_config.channelMode == ChannelMode::UNKNOWN) {
- LOG(ERROR) << __func__
- << ": Unknown AAC channel_mode=" << current_codec.channel_mode;
- return false;
- }
- uint8_t vbr_enabled =
- a2dp_offload.codec_info[1] & A2DP_AAC_VARIABLE_BIT_RATE_MASK;
- switch (vbr_enabled) {
- case A2DP_AAC_VARIABLE_BIT_RATE_ENABLED:
- aac_config.variableBitRateEnabled = AacVariableBitRate::ENABLED;
- break;
- case A2DP_AAC_VARIABLE_BIT_RATE_DISABLED:
- aac_config.variableBitRateEnabled = AacVariableBitRate::DISABLED;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown AAC VBR=" << +vbr_enabled;
- return false;
- }
- aac_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
- if (aac_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
- LOG(ERROR) << __func__ << ": Unknown AAC bits_per_sample="
- << current_codec.bits_per_sample;
- return false;
- }
- codec_config->config.aacConfig(aac_config);
- return true;
-}
-
-bool A2dpAptxToHalConfig(CodecConfiguration* codec_config,
- A2dpCodecConfig* a2dp_config) {
- btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
- if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_APTX &&
- current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD) {
- *codec_config = {};
- return false;
- }
- tBT_A2DP_OFFLOAD a2dp_offload;
- a2dp_config->getCodecSpecificConfig(&a2dp_offload);
- if (current_codec.codec_type == BTAV_A2DP_CODEC_INDEX_SOURCE_APTX) {
- codec_config->codecType = CodecType::APTX;
- } else {
- codec_config->codecType = CodecType::APTX_HD;
- }
- codec_config->config.aptxConfig({});
- auto aptx_config = codec_config->config.aptxConfig();
- aptx_config.sampleRate = A2dpCodecToHalSampleRate(current_codec);
- if (aptx_config.sampleRate == SampleRate::RATE_UNKNOWN) {
- LOG(ERROR) << __func__
- << ": Unknown aptX sample_rate=" << current_codec.sample_rate;
- return false;
- }
- aptx_config.channelMode = A2dpCodecToHalChannelMode(current_codec);
- if (aptx_config.channelMode == ChannelMode::UNKNOWN) {
- LOG(ERROR) << __func__
- << ": Unknown aptX channel_mode=" << current_codec.channel_mode;
- return false;
- }
- aptx_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
- if (aptx_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
- LOG(ERROR) << __func__ << ": Unknown aptX bits_per_sample="
- << current_codec.bits_per_sample;
- return false;
- }
- codec_config->config.aptxConfig(aptx_config);
- return true;
-}
-
-bool A2dpLdacToHalConfig(CodecConfiguration* codec_config,
- A2dpCodecConfig* a2dp_config) {
- btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
- if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC) {
- codec_config = {};
- return false;
- }
- tBT_A2DP_OFFLOAD a2dp_offload;
- a2dp_config->getCodecSpecificConfig(&a2dp_offload);
- codec_config->codecType = CodecType::LDAC;
- codec_config->config.ldacConfig({});
- auto ldac_config = codec_config->config.ldacConfig();
- ldac_config.sampleRate = A2dpCodecToHalSampleRate(current_codec);
- if (ldac_config.sampleRate == SampleRate::RATE_UNKNOWN) {
- LOG(ERROR) << __func__
- << ": Unknown LDAC sample_rate=" << current_codec.sample_rate;
- return false;
- }
- switch (a2dp_offload.codec_info[7]) {
- case A2DP_LDAC_CHANNEL_MODE_STEREO:
- ldac_config.channelMode = LdacChannelMode::STEREO;
- break;
- case A2DP_LDAC_CHANNEL_MODE_DUAL:
- ldac_config.channelMode = LdacChannelMode::DUAL;
- break;
- case A2DP_LDAC_CHANNEL_MODE_MONO:
- ldac_config.channelMode = LdacChannelMode::MONO;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown LDAC channel_mode="
- << a2dp_offload.codec_info[7];
- ldac_config.channelMode = LdacChannelMode::UNKNOWN;
- return false;
- }
- switch (a2dp_offload.codec_info[6]) {
- case A2DP_LDAC_QUALITY_HIGH:
- ldac_config.qualityIndex = LdacQualityIndex::QUALITY_HIGH;
- break;
- case A2DP_LDAC_QUALITY_MID:
- ldac_config.qualityIndex = LdacQualityIndex::QUALITY_MID;
- break;
- case A2DP_LDAC_QUALITY_LOW:
- ldac_config.qualityIndex = LdacQualityIndex::QUALITY_LOW;
- break;
- case A2DP_LDAC_QUALITY_ABR_OFFLOAD:
- ldac_config.qualityIndex = LdacQualityIndex::QUALITY_ABR;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown LDAC QualityIndex="
- << a2dp_offload.codec_info[6];
- return false;
- }
- ldac_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
- if (ldac_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
- LOG(ERROR) << __func__ << ": Unknown LDAC bits_per_sample="
- << current_codec.bits_per_sample;
- return false;
- }
- codec_config->config.ldacConfig(ldac_config);
- return true;
-}
-
-bool UpdateOffloadingCapabilities(
- const std::vector<btav_a2dp_codec_config_t>& framework_preference) {
- audio_hal_capabilities =
- BluetoothAudioSinkClientInterface::GetAudioCapabilities(
- SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- uint32_t codec_type_masks = static_cast<uint32_t>(CodecType::UNKNOWN);
- for (auto preference : framework_preference) {
- switch (preference.codec_type) {
- case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
- codec_type_masks |= CodecType::SBC;
- break;
- case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
- codec_type_masks |= CodecType::AAC;
- break;
- case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
- codec_type_masks |= CodecType::APTX;
- break;
- case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
- codec_type_masks |= CodecType::APTX_HD;
- break;
- case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
- codec_type_masks |= CodecType::LDAC;
- break;
- case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
- [[fallthrough]];
- case BTAV_A2DP_CODEC_INDEX_SINK_AAC:
- [[fallthrough]];
- case BTAV_A2DP_CODEC_INDEX_SINK_LDAC:
- LOG(WARNING) << __func__
- << ": Ignore sink codec_type=" << preference.codec_type;
- break;
- case BTAV_A2DP_CODEC_INDEX_MAX:
- [[fallthrough]];
- default:
- LOG(ERROR) << __func__
- << ": Unknown codec_type=" << preference.codec_type;
- return false;
- }
- }
- offloading_preference.clear();
- for (auto capability : audio_hal_capabilities) {
- if (static_cast<CodecType>(capability.codecCapabilities().codecType &
- codec_type_masks) != CodecType::UNKNOWN) {
- LOG(INFO) << __func__
- << ": enabled offloading capability=" << toString(capability);
- offloading_preference.push_back(capability);
- } else {
- LOG(INFO) << __func__
- << ": disabled offloading capability=" << toString(capability);
- }
- }
- // TODO: Bluetooth SoC and runtime property
- return true;
-}
-
-// Check whether this codec is supported by the audio HAL and is allowed to use
-// by prefernece of framework / Bluetooth SoC / runtime property.
-bool IsCodecOffloadingEnabled(const CodecConfiguration& codec_config) {
- for (auto preference : offloading_preference) {
- if (codec_config.codecType != preference.codecCapabilities().codecType)
- continue;
- auto codec_capability = preference.codecCapabilities();
- switch (codec_capability.codecType) {
- case CodecType::SBC: {
- auto sbc_capability = codec_capability.capabilities.sbcCapabilities();
- auto sbc_config = codec_config.config.sbcConfig();
- return sbc_offloading_capability_match(sbc_capability, sbc_config);
- }
- case CodecType::AAC: {
- auto aac_capability = codec_capability.capabilities.aacCapabilities();
- auto aac_config = codec_config.config.aacConfig();
- return aac_offloading_capability_match(aac_capability, aac_config);
- }
- case CodecType::APTX:
- [[fallthrough]];
- case CodecType::APTX_HD: {
- auto aptx_capability = codec_capability.capabilities.aptxCapabilities();
- auto aptx_config = codec_config.config.aptxConfig();
- return aptx_offloading_capability_match(aptx_capability, aptx_config);
- }
- case CodecType::LDAC: {
- auto ldac_capability = codec_capability.capabilities.ldacCapabilities();
- auto ldac_config = codec_config.config.ldacConfig();
- return ldac_offloading_capability_match(ldac_capability, ldac_config);
- }
- case CodecType::UNKNOWN:
- [[fallthrough]];
- default:
- LOG(ERROR) << __func__ << ": Unknown codecType="
- << toString(codec_capability.codecType);
- return false;
- }
- }
- LOG(INFO) << __func__ << ": software codec=" << toString(codec_config);
- return false;
-}
-
-} // namespace codec
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/codec_status.h b/audio_hal_interface/codec_status.h
deleted file mode 100644
index 7f2591b..0000000
--- a/audio_hal_interface/codec_status.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#pragma once
-
-#include <android/hardware/bluetooth/audio/2.1/types.h>
-
-#include <vector>
-
-#include "a2dp_codec_api.h"
-
-namespace bluetooth {
-namespace audio {
-namespace codec {
-
-using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
-using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
-using ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration;
-using ::android::hardware::bluetooth::audio::V2_0::SampleRate;
-
-extern const CodecConfiguration kInvalidCodecConfiguration;
-
-SampleRate A2dpCodecToHalSampleRate(
- const btav_a2dp_codec_config_t& a2dp_codec_config);
-BitsPerSample A2dpCodecToHalBitsPerSample(
- const btav_a2dp_codec_config_t& a2dp_codec_config);
-ChannelMode A2dpCodecToHalChannelMode(
- const btav_a2dp_codec_config_t& a2dp_codec_config);
-
-bool A2dpSbcToHalConfig(CodecConfiguration* codec_config,
- A2dpCodecConfig* a2dp_config);
-bool A2dpAacToHalConfig(CodecConfiguration* codec_config,
- A2dpCodecConfig* a2dp_config);
-bool A2dpAptxToHalConfig(CodecConfiguration* codec_config,
- A2dpCodecConfig* a2dp_config);
-bool A2dpLdacToHalConfig(CodecConfiguration* codec_config,
- A2dpCodecConfig* a2dp_config);
-
-bool UpdateOffloadingCapabilities(
- const std::vector<btav_a2dp_codec_config_t>& framework_preference);
-// Check whether this codec is supported by the audio HAL and is allowed to use
-// by prefernece of framework / Bluetooth SoC / runtime property.
-bool IsCodecOffloadingEnabled(const CodecConfiguration& codec_config);
-
-} // namespace codec
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/hal_version_manager.h b/audio_hal_interface/hal_version_manager.h
deleted file mode 100644
index 779ea3e..0000000
--- a/audio_hal_interface/hal_version_manager.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#pragma once
-
-#include <android/hardware/bluetooth/audio/2.1/IBluetoothAudioProvidersFactory.h>
-#include <android/hardware/bluetooth/audio/2.1/types.h>
-#include <android/hidl/manager/1.2/IServiceManager.h>
-#include <base/logging.h>
-#include <hidl/ServiceManagement.h>
-
-namespace bluetooth {
-namespace audio {
-
-using ::android::hardware::hidl_vec;
-
-using IBluetoothAudioProvidersFactory_2_0 = ::android::hardware::bluetooth::
- audio::V2_0::IBluetoothAudioProvidersFactory;
-using IBluetoothAudioProvidersFactory_2_1 = ::android::hardware::bluetooth::
- audio::V2_1::IBluetoothAudioProvidersFactory;
-
-constexpr char kFullyQualifiedInterfaceName_2_0[] =
- "android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvidersFactory";
-constexpr char kFullyQualifiedInterfaceName_2_1[] =
- "android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvidersFactory";
-
-enum class BluetoothAudioHalVersion : uint8_t {
- VERSION_2_0 = 0,
- VERSION_2_1,
- VERSION_UNAVAILABLE,
-};
-
-class HalVersionManager {
- public:
- static BluetoothAudioHalVersion GetHalVersion() {
- std::lock_guard<std::mutex> guard(instance_ptr->mutex_);
- return instance_ptr->hal_version_;
- }
-
- static android::sp<IBluetoothAudioProvidersFactory_2_1>
- GetProvidersFactory_2_1() {
- std::lock_guard<std::mutex> guard(instance_ptr->mutex_);
- if (instance_ptr->hal_version_ != BluetoothAudioHalVersion::VERSION_2_1) {
- return nullptr;
- }
- android::sp<IBluetoothAudioProvidersFactory_2_1> providers_factory =
- IBluetoothAudioProvidersFactory_2_1::getService();
- CHECK(providers_factory)
- << "V2_1::IBluetoothAudioProvidersFactory::getService() failed";
-
- LOG(INFO) << "V2_1::IBluetoothAudioProvidersFactory::getService() returned "
- << providers_factory.get()
- << (providers_factory->isRemote() ? " (remote)" : " (local)");
- return providers_factory;
- }
-
- static android::sp<IBluetoothAudioProvidersFactory_2_0>
- GetProvidersFactory_2_0() {
- std::unique_lock<std::mutex> guard(instance_ptr->mutex_);
- if (instance_ptr->hal_version_ == BluetoothAudioHalVersion::VERSION_2_1) {
- guard.unlock();
- return instance_ptr->GetProvidersFactory_2_1();
- }
- android::sp<IBluetoothAudioProvidersFactory_2_0> providers_factory =
- IBluetoothAudioProvidersFactory_2_0::getService();
- CHECK(providers_factory)
- << "V2_0::IBluetoothAudioProvidersFactory::getService() failed";
-
- LOG(INFO) << "V2_0::IBluetoothAudioProvidersFactory::getService() returned "
- << providers_factory.get()
- << (providers_factory->isRemote() ? " (remote)" : " (local)");
- guard.unlock();
- return providers_factory;
- }
-
- HalVersionManager() {
- auto service_manager = android::hardware::defaultServiceManager1_2();
- CHECK(service_manager != nullptr);
- size_t instance_count = 0;
- auto listManifestByInterface_cb =
- [&instance_count](
- const hidl_vec<android::hardware::hidl_string>& instanceNames) {
- instance_count = instanceNames.size();
- };
- auto hidl_retval = service_manager->listManifestByInterface(
- kFullyQualifiedInterfaceName_2_1, listManifestByInterface_cb);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": IServiceManager::listByInterface failure: "
- << hidl_retval.description();
- return;
- }
-
- if (instance_count > 0) {
- hal_version_ = BluetoothAudioHalVersion::VERSION_2_1;
- return;
- }
-
- hidl_retval = service_manager->listManifestByInterface(
- kFullyQualifiedInterfaceName_2_0, listManifestByInterface_cb);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": IServiceManager::listByInterface failure: "
- << hidl_retval.description();
- return;
- }
-
- if (instance_count > 0) {
- hal_version_ = BluetoothAudioHalVersion::VERSION_2_0;
- return;
- }
-
- hal_version_ = BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
- LOG(ERROR) << __func__ << " No supported HAL version";
- }
-
- private:
- static std::unique_ptr<HalVersionManager> instance_ptr;
- std::mutex mutex_;
-
- BluetoothAudioHalVersion hal_version_;
-};
-
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/hearing_aid_software_encoding.cc b/audio_hal_interface/hearing_aid_software_encoding.cc
deleted file mode 100644
index 2482502..0000000
--- a/audio_hal_interface/hearing_aid_software_encoding.cc
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#define LOG_TAG "BTAudioClientHearingAid"
-
-#include "hearing_aid_software_encoding.h"
-#include "client_interface.h"
-
-#include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h"
-#include "osi/include/log.h"
-#include "osi/include/properties.h"
-
-namespace {
-
-using ::android::hardware::bluetooth::audio::V2_0::CodecType;
-using ::bluetooth::audio::AudioConfiguration;
-using ::bluetooth::audio::BitsPerSample;
-using ::bluetooth::audio::BluetoothAudioCtrlAck;
-using ::bluetooth::audio::ChannelMode;
-using ::bluetooth::audio::PcmParameters;
-using ::bluetooth::audio::SampleRate;
-using ::bluetooth::audio::SessionType;
-using ::bluetooth::audio::SessionType_2_1;
-using ::bluetooth::audio::hearing_aid::StreamCallbacks;
-
-// Transport implementation for Hearing Aids
-class HearingAidTransport
- : public bluetooth::audio::IBluetoothSinkTransportInstance {
- public:
- HearingAidTransport(StreamCallbacks stream_cb)
- : IBluetoothSinkTransportInstance(
- SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH, {}),
- stream_cb_(std::move(stream_cb)),
- remote_delay_report_ms_(0),
- total_bytes_read_(0),
- data_position_({}){};
-
- BluetoothAudioCtrlAck StartRequest() override {
- LOG(INFO) << __func__;
- if (stream_cb_.on_resume_(true)) {
- return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- }
- return BluetoothAudioCtrlAck::FAILURE;
- }
-
- BluetoothAudioCtrlAck SuspendRequest() override {
- LOG(INFO) << __func__;
- if (stream_cb_.on_suspend_()) {
- uint8_t p_buf[AUDIO_STREAM_OUTPUT_BUFFER_SZ * 2];
- ::bluetooth::audio::hearing_aid::read(p_buf, sizeof(p_buf));
- return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- } else {
- return BluetoothAudioCtrlAck::FAILURE;
- }
- }
-
- void StopRequest() override {
- LOG(INFO) << __func__;
- if (stream_cb_.on_suspend_()) {
- // flush
- uint8_t p_buf[AUDIO_STREAM_OUTPUT_BUFFER_SZ * 2];
- ::bluetooth::audio::hearing_aid::read(p_buf, sizeof(p_buf));
- }
- }
-
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_read,
- timespec* data_position) override {
- VLOG(2) << __func__ << ": data=" << total_bytes_read_
- << " byte(s), timestamp=" << data_position_.tv_sec << "."
- << data_position_.tv_nsec
- << "s, delay report=" << remote_delay_report_ms_ << " msec.";
- if (remote_delay_report_ns != nullptr) {
- *remote_delay_report_ns = remote_delay_report_ms_ * 1000000u;
- }
- if (total_bytes_read != nullptr) *total_bytes_read = total_bytes_read_;
- if (data_position != nullptr) *data_position = data_position_;
-
- return true;
- }
-
- void MetadataChanged(const source_metadata_t& source_metadata) override {
- auto track_count = source_metadata.track_count;
- auto tracks = source_metadata.tracks;
- LOG(INFO) << __func__ << ": " << track_count << " track(s) received";
- while (track_count) {
- VLOG(1) << __func__ << ": usage=" << tracks->usage
- << ", content_type=" << tracks->content_type
- << ", gain=" << tracks->gain;
- --track_count;
- ++tracks;
- }
- }
-
- void ResetPresentationPosition() override {
- VLOG(2) << __func__ << ": called.";
- remote_delay_report_ms_ = 0;
- total_bytes_read_ = 0;
- data_position_ = {};
- }
-
- void LogBytesRead(size_t bytes_read) override {
- if (bytes_read) {
- total_bytes_read_ += bytes_read;
- clock_gettime(CLOCK_MONOTONIC, &data_position_);
- }
- }
-
- void SetRemoteDelay(uint16_t delay_report_ms) {
- LOG(INFO) << __func__ << ": delay_report=" << delay_report_ms << " msec";
- remote_delay_report_ms_ = delay_report_ms;
- }
-
- private:
- StreamCallbacks stream_cb_;
- uint16_t remote_delay_report_ms_;
- uint64_t total_bytes_read_;
- timespec data_position_;
-};
-
-bool HearingAidGetSelectedHalPcmConfig(PcmParameters* hal_pcm_config) {
- if (hal_pcm_config == nullptr) return false;
- // TODO: we only support one config for now!
- hal_pcm_config->sampleRate = SampleRate::RATE_16000;
- hal_pcm_config->bitsPerSample = BitsPerSample::BITS_16;
- hal_pcm_config->channelMode = ChannelMode::STEREO;
- return true;
-}
-
-// Sink instance of Hearing Aids to provide call-in APIs for Bluetooth Audio Hal
-HearingAidTransport* hearing_aid_sink = nullptr;
-// Common interface to call-out into Bluetooth Audio Hal
-bluetooth::audio::BluetoothAudioSinkClientInterface*
- hearing_aid_hal_clientinterface = nullptr;
-bool btaudio_hearing_aid_disabled = false;
-bool is_configured = false;
-
-// Save the value if the remote reports its delay before hearing_aid_sink is
-// initialized
-uint16_t remote_delay_ms = 0;
-
-bool is_hal_2_0_force_disabled() {
- if (!is_configured) {
- btaudio_hearing_aid_disabled = osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false);
- is_configured = true;
- }
- return btaudio_hearing_aid_disabled;
-}
-
-} // namespace
-
-namespace bluetooth {
-namespace audio {
-namespace hearing_aid {
-
-bool is_hal_2_0_enabled() { return hearing_aid_hal_clientinterface != nullptr; }
-
-bool init(StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop) {
- LOG(INFO) << __func__;
-
- if (is_hal_2_0_force_disabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is disabled";
- return false;
- }
-
- hearing_aid_sink = new HearingAidTransport(std::move(stream_cb));
- hearing_aid_hal_clientinterface =
- new bluetooth::audio::BluetoothAudioSinkClientInterface(hearing_aid_sink,
- message_loop);
- if (!hearing_aid_hal_clientinterface->IsValid()) {
- LOG(WARNING) << __func__ << ": BluetoothAudio HAL for Hearing Aid is invalid?!";
- delete hearing_aid_hal_clientinterface;
- hearing_aid_hal_clientinterface = nullptr;
- delete hearing_aid_sink;
- hearing_aid_sink = nullptr;
- return false;
- }
-
- if (remote_delay_ms != 0) {
- LOG(INFO) << __func__ << ": restore DELAY " << remote_delay_ms << " ms";
- hearing_aid_sink->SetRemoteDelay(remote_delay_ms);
- remote_delay_ms = 0;
- }
-
- return true;
-}
-
-void cleanup() {
- LOG(INFO) << __func__;
- if (!is_hal_2_0_enabled()) return;
- end_session();
- delete hearing_aid_hal_clientinterface;
- hearing_aid_hal_clientinterface = nullptr;
- delete hearing_aid_sink;
- hearing_aid_sink = nullptr;
- remote_delay_ms = 0;
-}
-
-void start_session() {
- LOG(INFO) << __func__;
- if (!is_hal_2_0_enabled()) return;
- AudioConfiguration audio_config;
- PcmParameters pcm_config{};
- if (!HearingAidGetSelectedHalPcmConfig(&pcm_config)) {
- LOG(ERROR) << __func__ << ": cannot get PCM config";
- return;
- }
- audio_config.pcmConfig(pcm_config);
- if (!hearing_aid_hal_clientinterface->UpdateAudioConfig(audio_config)) {
- LOG(ERROR) << __func__ << ": cannot update audio config to HAL";
- return;
- }
- hearing_aid_hal_clientinterface->StartSession();
-}
-
-void end_session() {
- LOG(INFO) << __func__;
- if (!is_hal_2_0_enabled()) return;
- hearing_aid_hal_clientinterface->EndSession();
-}
-
-size_t read(uint8_t* p_buf, uint32_t len) {
- if (!is_hal_2_0_enabled()) return 0;
- return hearing_aid_hal_clientinterface->ReadAudioData(p_buf, len);
-}
-
-// Update Hearing Aids delay report to BluetoothAudio HAL
-void set_remote_delay(uint16_t delay_report_ms) {
- if (!is_hal_2_0_enabled()) {
- LOG(INFO) << __func__ << ": not ready for DelayReport " << delay_report_ms
- << " ms";
- remote_delay_ms = delay_report_ms;
- return;
- }
- LOG(INFO) << __func__ << ": delay_report_ms=" << delay_report_ms << " ms";
- hearing_aid_sink->SetRemoteDelay(delay_report_ms);
-}
-
-} // namespace hearing_aid
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/hearing_aid_software_encoding.h b/audio_hal_interface/hearing_aid_software_encoding.h
deleted file mode 100644
index 8a64fcd..0000000
--- a/audio_hal_interface/hearing_aid_software_encoding.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#pragma once
-
-#include <functional>
-#include "common/message_loop_thread.h"
-
-namespace bluetooth {
-namespace audio {
-namespace hearing_aid {
-
-struct StreamCallbacks {
- std::function<bool(bool start_media_task)> on_resume_;
- std::function<bool(void)> on_suspend_;
-};
-
-// Check if new bluetooth_audio is enabled
-bool is_hal_2_0_enabled();
-
-// Initialize BluetoothAudio HAL: openProvider
-bool init(StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop);
-
-// Clean up BluetoothAudio HAL
-void cleanup();
-
-// Send command to the BluetoothAudio HAL: StartSession, EndSession
-void start_session();
-void end_session();
-
-void set_remote_delay(uint16_t delay_report_ms);
-
-// Read from the FMQ of BluetoothAudio HAL
-size_t read(uint8_t* p_buf, uint32_t len);
-
-} // namespace hearing_aid
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/hearing_aid_software_encoding_host.cc b/audio_hal_interface/hearing_aid_software_encoding_host.cc
deleted file mode 100644
index 37d5bb2..0000000
--- a/audio_hal_interface/hearing_aid_software_encoding_host.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#include "audio_hal_interface/hearing_aid_software_encoding.h"
-
-namespace bluetooth {
-namespace audio {
-namespace hearing_aid {
-
-bool is_hal_2_0_enabled() { return false; }
-
-bool init(StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop) {
- return false;
-}
-
-void cleanup() {}
-
-void start_session() {}
-
-void end_session() {}
-
-size_t read(uint8_t* p_buf, uint32_t len) { return 0; }
-
-void set_remote_delay(uint16_t delay_report_ms) {}
-
-} // namespace hearing_aid
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/le_audio_software.cc b/audio_hal_interface/le_audio_software.cc
deleted file mode 100644
index 39e3a52..0000000
--- a/audio_hal_interface/le_audio_software.cc
+++ /dev/null
@@ -1,637 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
- * www.ehima.com
- *
- * 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.
- */
-
-#define LOG_TAG "BTAudioClientLeAudio"
-
-#include "le_audio_software.h"
-
-#include "client_interface.h"
-#include "osi/include/log.h"
-#include "osi/include/properties.h"
-
-namespace {
-
-using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
-using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
-using ::android::hardware::bluetooth::audio::V2_0::CodecType;
-using ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
-using ::bluetooth::audio::BluetoothAudioCtrlAck;
-using ::bluetooth::audio::SampleRate_2_1;
-using ::bluetooth::audio::SessionType;
-using ::bluetooth::audio::SessionType_2_1;
-using ::bluetooth::audio::le_audio::LeAudioClientInterface;
-using ::bluetooth::audio::le_audio::StreamCallbacks;
-
-bluetooth::audio::BluetoothAudioSinkClientInterface*
- le_audio_sink_hal_clientinterface = nullptr;
-bluetooth::audio::BluetoothAudioSourceClientInterface*
- le_audio_source_hal_clientinterface = nullptr;
-
-static bool is_source_hal_enabled() {
- return le_audio_source_hal_clientinterface != nullptr;
-}
-
-static bool is_sink_hal_enabled() {
- return le_audio_sink_hal_clientinterface != nullptr;
-}
-
-class LeAudioTransport {
- public:
- LeAudioTransport(void (*flush)(void), StreamCallbacks stream_cb,
- PcmParameters pcm_config)
- : flush_(std::move(flush)),
- stream_cb_(std::move(stream_cb)),
- remote_delay_report_ms_(0),
- total_bytes_processed_(0),
- data_position_({}),
- pcm_config_(std::move(pcm_config)),
- is_pending_start_request_(false){};
-
- BluetoothAudioCtrlAck StartRequest() {
- LOG(INFO) << __func__;
-
- /*
- * Set successful state as initial, it may be overwritten with cancelation
- * during on_resume handling
- */
- pending_start_request_state_ = BluetoothAudioCtrlAck::PENDING;
-
- if (stream_cb_.on_resume_(true)) {
- if (pending_start_request_state_ == BluetoothAudioCtrlAck::PENDING)
- is_pending_start_request_ = true;
-
- return pending_start_request_state_;
- }
-
- return BluetoothAudioCtrlAck::FAILURE;
- }
-
- BluetoothAudioCtrlAck SuspendRequest() {
- LOG(INFO) << __func__;
- if (stream_cb_.on_suspend_()) {
- flush_();
- return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- } else {
- return BluetoothAudioCtrlAck::FAILURE;
- }
- }
-
- void StopRequest() {
- LOG(INFO) << __func__;
- if (stream_cb_.on_suspend_()) {
- flush_();
- }
- }
-
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_processed,
- timespec* data_position) {
- VLOG(2) << __func__ << ": data=" << total_bytes_processed_
- << " byte(s), timestamp=" << data_position_.tv_sec << "."
- << data_position_.tv_nsec
- << "s, delay report=" << remote_delay_report_ms_ << " msec.";
- if (remote_delay_report_ns != nullptr) {
- *remote_delay_report_ns = remote_delay_report_ms_ * 1000000u;
- }
- if (total_bytes_processed != nullptr)
- *total_bytes_processed = total_bytes_processed_;
- if (data_position != nullptr) *data_position = data_position_;
-
- return true;
- }
-
- void MetadataChanged(const source_metadata_t& source_metadata) {
- auto track_count = source_metadata.track_count;
-
- if (track_count == 0) {
- LOG(WARNING) << ", invalid number of metadata changed tracks";
- return;
- }
-
- stream_cb_.on_metadata_update_(source_metadata);
- }
-
- void ResetPresentationPosition() {
- VLOG(2) << __func__ << ": called.";
- remote_delay_report_ms_ = 0;
- total_bytes_processed_ = 0;
- data_position_ = {};
- }
-
- void LogBytesProcessed(size_t bytes_processed) {
- if (bytes_processed) {
- total_bytes_processed_ += bytes_processed;
- clock_gettime(CLOCK_MONOTONIC, &data_position_);
- }
- }
-
- void SetRemoteDelay(uint16_t delay_report_ms) {
- LOG(INFO) << __func__ << ": delay_report=" << delay_report_ms << " msec";
- remote_delay_report_ms_ = delay_report_ms;
- }
-
- const PcmParameters& LeAudioGetSelectedHalPcmConfig() { return pcm_config_; }
-
- void LeAudioSetSelectedHalPcmConfig(SampleRate_2_1 sample_rate,
- BitsPerSample bit_rate,
- ChannelMode channel_mode,
- uint32_t data_interval) {
- pcm_config_.sampleRate = sample_rate;
- pcm_config_.bitsPerSample = bit_rate;
- pcm_config_.channelMode = channel_mode;
- pcm_config_.dataIntervalUs = data_interval;
- }
-
- bool SetAudioCtrlAckStateAndResetPendingStartStreamFlag(
- BluetoothAudioCtrlAck state) {
- bool ret = is_pending_start_request_;
- is_pending_start_request_ = false;
- pending_start_request_state_ = state;
-
- return ret;
- }
-
- private:
- void (*flush_)(void);
- StreamCallbacks stream_cb_;
- uint16_t remote_delay_report_ms_;
- uint64_t total_bytes_processed_;
- timespec data_position_;
- PcmParameters pcm_config_;
- bool is_pending_start_request_;
- BluetoothAudioCtrlAck pending_start_request_state_;
-};
-
-static void flush_sink() {
- if (!is_sink_hal_enabled()) return;
-
- le_audio_sink_hal_clientinterface->FlushAudioData();
-}
-
-// Sink transport implementation for Le Audio
-class LeAudioSinkTransport
- : public bluetooth::audio::IBluetoothSinkTransportInstance {
- public:
- LeAudioSinkTransport(StreamCallbacks stream_cb)
- : IBluetoothSinkTransportInstance(
- SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH, {}) {
- transport_ =
- new LeAudioTransport(flush_sink, std::move(stream_cb),
- {SampleRate_2_1::RATE_16000, ChannelMode::STEREO,
- BitsPerSample::BITS_16, 0});
- };
-
- ~LeAudioSinkTransport() { delete transport_; }
-
- BluetoothAudioCtrlAck StartRequest() override {
- return transport_->StartRequest();
- }
-
- BluetoothAudioCtrlAck SuspendRequest() override {
- return transport_->SuspendRequest();
- }
-
- void StopRequest() override { transport_->StopRequest(); }
-
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_read,
- timespec* data_position) override {
- return transport_->GetPresentationPosition(remote_delay_report_ns,
- total_bytes_read, data_position);
- }
-
- void MetadataChanged(const source_metadata_t& source_metadata) override {
- transport_->MetadataChanged(source_metadata);
- }
-
- void ResetPresentationPosition() override {
- transport_->ResetPresentationPosition();
- }
-
- void LogBytesRead(size_t bytes_read) override {
- transport_->LogBytesProcessed(bytes_read);
- }
-
- void SetRemoteDelay(uint16_t delay_report_ms) {
- transport_->SetRemoteDelay(delay_report_ms);
- }
-
- const PcmParameters& LeAudioGetSelectedHalPcmConfig() {
- return transport_->LeAudioGetSelectedHalPcmConfig();
- }
-
- void LeAudioSetSelectedHalPcmConfig(SampleRate_2_1 sample_rate,
- BitsPerSample bit_rate,
- ChannelMode channel_mode,
- uint32_t data_interval) {
- transport_->LeAudioSetSelectedHalPcmConfig(sample_rate, bit_rate,
- channel_mode, data_interval);
- }
-
- bool SetAudioCtrlAckStateAndResetPendingStartStreamFlag(
- BluetoothAudioCtrlAck state = BluetoothAudioCtrlAck::PENDING) {
- return transport_->SetAudioCtrlAckStateAndResetPendingStartStreamFlag(
- state);
- }
-
- private:
- LeAudioTransport* transport_;
-};
-
-static void flush_source() {
- if (le_audio_source_hal_clientinterface == nullptr) return;
-
- le_audio_source_hal_clientinterface->FlushAudioData();
-}
-
-class LeAudioSourceTransport
- : public bluetooth::audio::IBluetoothSourceTransportInstance {
- public:
- LeAudioSourceTransport(StreamCallbacks stream_cb)
- : IBluetoothSourceTransportInstance(
- SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH, {}) {
- transport_ =
- new LeAudioTransport(flush_source, std::move(stream_cb),
- {SampleRate_2_1::RATE_16000, ChannelMode::MONO,
- BitsPerSample::BITS_16, 0});
- };
-
- ~LeAudioSourceTransport() { delete transport_; }
-
- BluetoothAudioCtrlAck StartRequest() override {
- return transport_->StartRequest();
- }
-
- BluetoothAudioCtrlAck SuspendRequest() override {
- return transport_->SuspendRequest();
- }
-
- void StopRequest() override { transport_->StopRequest(); }
-
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_written,
- timespec* data_position) override {
- return transport_->GetPresentationPosition(
- remote_delay_report_ns, total_bytes_written, data_position);
- }
-
- void MetadataChanged(const source_metadata_t& source_metadata) override {
- transport_->MetadataChanged(source_metadata);
- }
-
- void ResetPresentationPosition() override {
- transport_->ResetPresentationPosition();
- }
-
- void LogBytesWritten(size_t bytes_written) override {
- transport_->LogBytesProcessed(bytes_written);
- }
-
- void SetRemoteDelay(uint16_t delay_report_ms) {
- transport_->SetRemoteDelay(delay_report_ms);
- }
-
- const PcmParameters& LeAudioGetSelectedHalPcmConfig() {
- return transport_->LeAudioGetSelectedHalPcmConfig();
- }
-
- void LeAudioSetSelectedHalPcmConfig(SampleRate_2_1 sample_rate,
- BitsPerSample bit_rate,
- ChannelMode channel_mode,
- uint32_t data_interval) {
- transport_->LeAudioSetSelectedHalPcmConfig(sample_rate, bit_rate,
- channel_mode, data_interval);
- }
-
- bool SetAudioCtrlAckStateAndResetPendingStartStreamFlag(
- BluetoothAudioCtrlAck state = BluetoothAudioCtrlAck::PENDING) {
- return transport_->SetAudioCtrlAckStateAndResetPendingStartStreamFlag(
- state);
- }
-
- private:
- LeAudioTransport* transport_;
-};
-
-// Instance of Le Audio to provide call-in APIs for Bluetooth Audio Hal
-LeAudioSinkTransport* le_audio_sink = nullptr;
-LeAudioSourceTransport* le_audio_source = nullptr;
-} // namespace
-
-namespace bluetooth {
-namespace audio {
-namespace le_audio {
-
-LeAudioClientInterface* LeAudioClientInterface::interface = nullptr;
-LeAudioClientInterface* LeAudioClientInterface::Get() {
- if (osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false)) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is disabled";
- return nullptr;
- }
-
- if (LeAudioClientInterface::interface == nullptr)
- LeAudioClientInterface::interface = new LeAudioClientInterface();
-
- return LeAudioClientInterface::interface;
-}
-
-static SampleRate_2_1 le_audio_sample_rate2audio_hal(uint32_t sample_rate_2_1) {
- switch (sample_rate_2_1) {
- case 8000:
- return SampleRate_2_1::RATE_8000;
- case 16000:
- return SampleRate_2_1::RATE_16000;
- case 24000:
- return SampleRate_2_1::RATE_24000;
- case 32000:
- return SampleRate_2_1::RATE_32000;
- case 44100:
- return SampleRate_2_1::RATE_44100;
- case 48000:
- return SampleRate_2_1::RATE_48000;
- case 88200:
- return SampleRate_2_1::RATE_88200;
- case 96000:
- return SampleRate_2_1::RATE_96000;
- case 176400:
- return SampleRate_2_1::RATE_176400;
- case 192000:
- return SampleRate_2_1::RATE_192000;
- };
- return SampleRate_2_1::RATE_UNKNOWN;
-}
-
-static BitsPerSample le_audio_bit_rate2audio_hal(uint8_t bits_per_sample) {
- switch (bits_per_sample) {
- case 16:
- return BitsPerSample::BITS_16;
- case 24:
- return BitsPerSample::BITS_24;
- case 32:
- return BitsPerSample::BITS_32;
- };
- return BitsPerSample::BITS_UNKNOWN;
-}
-
-static ChannelMode le_audio_channel_mode2audio_hal(uint8_t channels_count) {
- switch (channels_count) {
- case 1:
- return ChannelMode::MONO;
- case 2:
- return ChannelMode::STEREO;
- }
- return ChannelMode::UNKNOWN;
-}
-
-void LeAudioClientInterface::Sink::Cleanup() {
- LOG(INFO) << __func__ << " sink";
- StopSession();
- delete le_audio_sink_hal_clientinterface;
- le_audio_sink_hal_clientinterface = nullptr;
- delete le_audio_sink;
- le_audio_sink = nullptr;
-}
-
-void LeAudioClientInterface::Sink::SetPcmParameters(
- const PcmParameters& params) {
- le_audio_sink->LeAudioSetSelectedHalPcmConfig(
- le_audio_sample_rate2audio_hal(params.sample_rate),
- le_audio_bit_rate2audio_hal(params.bits_per_sample),
- le_audio_channel_mode2audio_hal(params.channels_count),
- params.data_interval_us);
-}
-
-// Update Le Audio delay report to BluetoothAudio HAL
-void LeAudioClientInterface::Sink::SetRemoteDelay(uint16_t delay_report_ms) {
- LOG(INFO) << __func__ << ": delay_report_ms=" << delay_report_ms << " ms";
- le_audio_sink->SetRemoteDelay(delay_report_ms);
-}
-
-void LeAudioClientInterface::Sink::StartSession() {
- LOG(INFO) << __func__;
- AudioConfiguration_2_1 audio_config;
- audio_config.pcmConfig(le_audio_sink->LeAudioGetSelectedHalPcmConfig());
- if (!le_audio_sink_hal_clientinterface->UpdateAudioConfig_2_1(audio_config)) {
- LOG(ERROR) << __func__ << ": cannot update audio config to HAL";
- return;
- }
- le_audio_sink_hal_clientinterface->StartSession_2_1();
-}
-
-void LeAudioClientInterface::Sink::ConfirmStreamingRequest() {
- LOG(INFO) << __func__;
- if (!le_audio_sink->SetAudioCtrlAckStateAndResetPendingStartStreamFlag()) {
- LOG(WARNING) << ", no pending start stream request";
- return;
- }
-
- le_audio_sink_hal_clientinterface->StreamStarted(
- BluetoothAudioCtrlAck::SUCCESS_FINISHED);
-}
-
-void LeAudioClientInterface::Sink::CancelStreamingRequest() {
- LOG(INFO) << __func__;
- if (!le_audio_sink->SetAudioCtrlAckStateAndResetPendingStartStreamFlag(
- BluetoothAudioCtrlAck::FAILURE)) {
- LOG(WARNING) << ", no pending start stream request";
- return;
- }
-
- le_audio_sink_hal_clientinterface->StreamStarted(
- BluetoothAudioCtrlAck::FAILURE);
-}
-
-void LeAudioClientInterface::Sink::StopSession() {
- LOG(INFO) << __func__ << " sink";
- le_audio_sink->SetAudioCtrlAckStateAndResetPendingStartStreamFlag();
- le_audio_sink_hal_clientinterface->EndSession();
-}
-
-size_t LeAudioClientInterface::Sink::Read(uint8_t* p_buf, uint32_t len) {
- return le_audio_sink_hal_clientinterface->ReadAudioData(p_buf, len);
-}
-
-void LeAudioClientInterface::Source::Cleanup() {
- LOG(INFO) << __func__ << " source";
- StopSession();
- delete le_audio_source_hal_clientinterface;
- le_audio_source_hal_clientinterface = nullptr;
- delete le_audio_source;
- le_audio_source = nullptr;
-}
-
-void LeAudioClientInterface::Source::SetPcmParameters(
- const PcmParameters& params) {
- le_audio_source->LeAudioSetSelectedHalPcmConfig(
- le_audio_sample_rate2audio_hal(params.sample_rate),
- le_audio_bit_rate2audio_hal(params.bits_per_sample),
- le_audio_channel_mode2audio_hal(params.channels_count),
- params.data_interval_us);
-}
-
-void LeAudioClientInterface::Source::SetRemoteDelay(uint16_t delay_report_ms) {
- LOG(INFO) << __func__ << ": delay_report_ms=" << delay_report_ms << " ms";
- le_audio_source->SetRemoteDelay(delay_report_ms);
-}
-
-void LeAudioClientInterface::Source::StartSession() {
- LOG(INFO) << __func__;
- if (!is_source_hal_enabled()) return;
- AudioConfiguration_2_1 audio_config;
- audio_config.pcmConfig(le_audio_source->LeAudioGetSelectedHalPcmConfig());
- if (!le_audio_source_hal_clientinterface->UpdateAudioConfig_2_1(
- audio_config)) {
- LOG(ERROR) << __func__ << ": cannot update audio config to HAL";
- return;
- }
- le_audio_source_hal_clientinterface->StartSession_2_1();
-}
-
-void LeAudioClientInterface::Source::ConfirmStreamingRequest() {
- LOG(INFO) << __func__;
- if (!le_audio_source->SetAudioCtrlAckStateAndResetPendingStartStreamFlag()) {
- LOG(WARNING) << ", no pending start stream request";
- return;
- }
-
- le_audio_source_hal_clientinterface->StreamStarted(
- BluetoothAudioCtrlAck::SUCCESS_FINISHED);
-}
-
-void LeAudioClientInterface::Source::CancelStreamingRequest() {
- LOG(INFO) << __func__;
- if (!le_audio_source->SetAudioCtrlAckStateAndResetPendingStartStreamFlag(
- BluetoothAudioCtrlAck::FAILURE)) {
- LOG(WARNING) << ", no pending start stream request";
- return;
- }
-
- le_audio_source_hal_clientinterface->StreamStarted(
- BluetoothAudioCtrlAck::FAILURE);
-}
-
-void LeAudioClientInterface::Source::StopSession() {
- LOG(INFO) << __func__ << " source";
- le_audio_source->SetAudioCtrlAckStateAndResetPendingStartStreamFlag();
- le_audio_source_hal_clientinterface->EndSession();
-}
-
-size_t LeAudioClientInterface::Source::Write(const uint8_t* p_buf,
- uint32_t len) {
- return le_audio_source_hal_clientinterface->WriteAudioData(p_buf, len);
-}
-
-LeAudioClientInterface::Sink* LeAudioClientInterface::GetSink(
- StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop) {
- if (sink_ == nullptr) {
- sink_ = new Sink();
- } else {
- LOG(WARNING) << __func__ << ", Sink is already acquired";
- return nullptr;
- }
-
- LOG(INFO) << __func__;
-
- le_audio_sink = new LeAudioSinkTransport(std::move(stream_cb));
- le_audio_sink_hal_clientinterface =
- new bluetooth::audio::BluetoothAudioSinkClientInterface(le_audio_sink,
- message_loop);
- if (!le_audio_sink_hal_clientinterface->IsValid()) {
- LOG(WARNING) << __func__
- << ": BluetoothAudio HAL for Le Audio is invalid?!";
- delete le_audio_sink_hal_clientinterface;
- le_audio_sink_hal_clientinterface = nullptr;
- delete le_audio_sink;
- le_audio_sink = nullptr;
- delete sink_;
- sink_ = nullptr;
-
- return nullptr;
- }
-
- return sink_;
-}
-
-bool LeAudioClientInterface::IsSinkAcquired() { return sink_ != nullptr; }
-
-bool LeAudioClientInterface::ReleaseSink(LeAudioClientInterface::Sink* sink) {
- if (sink != sink_) {
- LOG(WARNING) << __func__ << ", can't release not acquired sink";
- return false;
- }
-
- if (le_audio_sink_hal_clientinterface && le_audio_sink) sink->Cleanup();
-
- delete (sink_);
- sink_ = nullptr;
-
- return true;
-}
-
-LeAudioClientInterface::Source* LeAudioClientInterface::GetSource(
- StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop) {
- if (source_ == nullptr) {
- source_ = new Source();
- } else {
- LOG(WARNING) << __func__ << ", Source is already acquired";
- return nullptr;
- }
-
- LOG(INFO) << __func__;
-
- le_audio_source = new LeAudioSourceTransport(std::move(stream_cb));
- le_audio_source_hal_clientinterface =
- new bluetooth::audio::BluetoothAudioSourceClientInterface(le_audio_source,
- message_loop);
- if (!le_audio_source_hal_clientinterface->IsValid()) {
- LOG(WARNING) << __func__
- << ": BluetoothAudio HAL for Le Audio is invalid?!";
- delete le_audio_source_hal_clientinterface;
- le_audio_source_hal_clientinterface = nullptr;
- delete le_audio_source;
- le_audio_source = nullptr;
- delete source_;
- source_ = nullptr;
-
- return nullptr;
- }
-
- return source_;
-}
-
-bool LeAudioClientInterface::IsSourceAcquired() { return source_ != nullptr; }
-
-bool LeAudioClientInterface::ReleaseSource(
- LeAudioClientInterface::Source* source) {
- if (source != source_) {
- LOG(WARNING) << __func__ << ", can't release not acquired source";
- return false;
- }
-
- if (le_audio_source_hal_clientinterface && le_audio_source) source->Cleanup();
-
- delete (source_);
- source_ = nullptr;
-
- return true;
-}
-
-} // namespace le_audio
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/le_audio_software.h b/audio_hal_interface/le_audio_software.h
deleted file mode 100644
index d595e6d..0000000
--- a/audio_hal_interface/le_audio_software.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#pragma once
-
-#include <hardware/audio.h>
-
-#include <functional>
-
-#include "common/message_loop_thread.h"
-
-namespace bluetooth {
-namespace audio {
-namespace le_audio {
-
-constexpr uint8_t kChannelNumberMono = 1;
-constexpr uint8_t kChannelNumberStereo = 2;
-
-constexpr uint32_t kSampleRate48000 = 48000;
-constexpr uint32_t kSampleRate44100 = 44100;
-constexpr uint32_t kSampleRate32000 = 32000;
-constexpr uint32_t kSampleRate24000 = 24000;
-constexpr uint32_t kSampleRate16000 = 16000;
-constexpr uint32_t kSampleRate8000 = 8000;
-
-constexpr uint8_t kBitsPerSample16 = 16;
-constexpr uint8_t kBitsPerSample24 = 24;
-constexpr uint8_t kBitsPerSample32 = 32;
-
-struct StreamCallbacks {
- std::function<bool(bool start_media_task)> on_resume_;
- std::function<bool(void)> on_suspend_;
- std::function<bool(const source_metadata_t&)> on_metadata_update_;
-};
-
-class LeAudioClientInterface {
- public:
- struct PcmParameters {
- uint32_t data_interval_us;
- uint32_t sample_rate;
- uint8_t bits_per_sample;
- uint8_t channels_count;
- };
-
- private:
- class IClientInterfaceEndpoint {
- public:
- virtual ~IClientInterfaceEndpoint() = default;
- virtual void Cleanup() = 0;
- virtual void SetPcmParameters(const PcmParameters& params) = 0;
- virtual void SetRemoteDelay(uint16_t delay_report_ms) = 0;
- virtual void StartSession() = 0;
- virtual void StopSession() = 0;
- virtual void ConfirmStreamingRequest() = 0;
- virtual void CancelStreamingRequest() = 0;
- };
-
- public:
- class Sink : public IClientInterfaceEndpoint {
- public:
- virtual ~Sink() = default;
-
- void Cleanup() override;
- void SetPcmParameters(const PcmParameters& params) override;
- void SetRemoteDelay(uint16_t delay_report_ms) override;
- void StartSession() override;
- void StopSession() override;
- void ConfirmStreamingRequest() override;
- void CancelStreamingRequest() override;
-
- // Read the stream of bytes sinked to us by the upper layers
- size_t Read(uint8_t* p_buf, uint32_t len);
- };
- class Source : public IClientInterfaceEndpoint {
- public:
- virtual ~Source() = default;
-
- void Cleanup() override;
- void SetPcmParameters(const PcmParameters& params) override;
- void SetRemoteDelay(uint16_t delay_report_ms) override;
- void StartSession() override;
- void StopSession() override;
- void ConfirmStreamingRequest() override;
- void CancelStreamingRequest() override;
-
- // Source the given stream of bytes to be sinked into the upper layers
- size_t Write(const uint8_t* p_buf, uint32_t len);
- };
-
- // Get LE Audio sink client interface if it's not previously acquired and not
- // yet released.
- Sink* GetSink(StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop);
- // This should be called before trying to get sink interface
- bool IsSinkAcquired();
- // Release sink interface if belongs to LE audio client interface
- bool ReleaseSink(Sink* sink);
-
- // Get LE Audio source client interface if it's not previously acquired and
- // not yet released.
- Source* GetSource(StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop);
- // This should be called before trying to get source interface
- bool IsSourceAcquired();
- // Release source interface if belongs to LE audio client interface
- bool ReleaseSource(Source* source);
-
- // Get interface, if previously not initialized - it'll initialize singleton.
- static LeAudioClientInterface* Get();
-
- private:
- static LeAudioClientInterface* interface;
- Sink* sink_ = nullptr;
- Source* source_ = nullptr;
-};
-
-} // namespace le_audio
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/le_audio_software_host.cc b/audio_hal_interface/le_audio_software_host.cc
deleted file mode 100644
index 5ce552a..0000000
--- a/audio_hal_interface/le_audio_software_host.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
- * www.ehima.com
- *
- * 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 "audio_hal_interface/hal_version_manager.h"
-#include "audio_hal_interface/le_audio_software.h"
-
-namespace bluetooth {
-namespace audio {
-
-namespace le_audio {
-
-LeAudioClientInterface* LeAudioClientInterface::Get() { return nullptr; }
-
-bool LeAudioClientInterface::IsSinkAcquired() { return false; }
-
-bool LeAudioClientInterface::ReleaseSink(LeAudioClientInterface::Sink* sink) {
- return false;
-}
-
-LeAudioClientInterface::Sink* LeAudioClientInterface::GetSink(
- StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop) {
- return nullptr;
-}
-
-size_t LeAudioClientInterface::Sink::Read(uint8_t* p_buf, uint32_t len) {
- return 0;
-}
-
-LeAudioClientInterface::Source* LeAudioClientInterface::GetSource(
- StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop) {
- return nullptr;
-}
-
-size_t LeAudioClientInterface::Source::Write(const uint8_t* p_buf,
- uint32_t len) {
- return 0;
-}
-
-bool LeAudioClientInterface::IsSourceAcquired() { return false; }
-
-bool LeAudioClientInterface::ReleaseSource(
- LeAudioClientInterface::Source* source) {
- return false;
-}
-
-} // namespace le_audio
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hearing_aid_hw/Android.bp b/audio_hearing_aid_hw/Android.bp
deleted file mode 100644
index 07fa15f..0000000
--- a/audio_hearing_aid_hw/Android.bp
+++ /dev/null
@@ -1,51 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-cc_defaults {
- name: "audio_hearing_aid_hw_defaults",
- defaults: ["libchrome_support_defaults"],
- include_dirs: [
- "system/bt",
- "system/bt/gd",
- "system/bt/include",
- "system/bt/types",
- ],
-}
-
-// Audio A2DP shared library for target
-cc_library {
- name: "audio.hearing_aid.default",
- defaults: ["audio_hearing_aid_hw_defaults"],
- relative_install_path: "hw",
- srcs: [
- "src/audio_hearing_aid_hw.cc",
- "src/audio_hearing_aid_hw_utils.cc",
- ],
- shared_libs: [
- "liblog",
- ],
- static_libs: ["libosi"],
-}
-
-// Audio A2DP library unit tests for target and host
-cc_test {
- name: "net_test_audio_hearing_aid_hw",
- test_suites: ["device-tests"],
- defaults: ["audio_hearing_aid_hw_defaults"],
- srcs: [
- "test/audio_hearing_aid_hw_test.cc",
- ],
- shared_libs: [
- "liblog",
- ],
- static_libs: [
- "audio.hearing_aid.default",
- "libosi",
- ],
-}
diff --git a/audio_hearing_aid_hw/include/audio_hearing_aid_hw.h b/audio_hearing_aid_hw/include/audio_hearing_aid_hw.h
deleted file mode 100644
index 8e4f255..0000000
--- a/audio_hearing_aid_hw/include/audio_hearing_aid_hw.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/******************************************************************************
- *
- * Copyright 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.
- *
- ******************************************************************************/
-
-/*****************************************************************************
- *
- * Filename: audio_hearing_aid_hw.h
- *
- * Description:
- *
- *****************************************************************************/
-
-#ifndef AUDIO_HEARING_AID_HW_H
-#define AUDIO_HEARING_AID_HW_H
-
-#include <stdint.h>
-
-#include <hardware/bt_av.h>
-
-/*****************************************************************************
- * Constants & Macros
- *****************************************************************************/
-
-#define HEARING_AID_AUDIO_HARDWARE_INTERFACE "audio.hearing_aid"
-#define HEARING_AID_CTRL_PATH "/data/misc/bluedroid/.hearing_aid_ctrl"
-#define HEARING_AID_DATA_PATH "/data/misc/bluedroid/.hearing_aid_data"
-
-// AUDIO_STREAM_OUTPUT_BUFFER_SZ controls the size of the audio socket buffer.
-// If one assumes the write buffer is always full during normal BT playback,
-// then increasing this value increases our playback latency.
-//
-// FIXME: The BT HAL should consume data at a constant rate.
-// AudioFlinger assumes that the HAL draws data at a constant rate, which is
-// true for most audio devices; however, the BT engine reads data at a variable
-// rate (over the short term), which confuses both AudioFlinger as well as
-// applications which deliver data at a (generally) fixed rate.
-//
-// 20 * 512 is not sufficient to smooth the variability for some BT devices,
-// resulting in mixer sleep and throttling. We increase this to 28 * 512 to help
-// reduce the effect of variable data consumption.
-#define AUDIO_STREAM_OUTPUT_BUFFER_SZ (28 * 512)
-#define AUDIO_STREAM_CONTROL_OUTPUT_BUFFER_SZ 256
-
-// AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is divided
-// for AudioFlinger data delivery. The AudioFlinger mixer delivers data in
-// chunks of AUDIO_STREAM_OUTPUT_BUFFER_SZ / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS.
-// If the number of periods is 2, the socket buffer represents "double
-// buffering" of the AudioFlinger mixer buffer.
-//
-// In general, AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * 16 * 4 should be a divisor
-// of AUDIO_STREAM_OUTPUT_BUFFER_SZ.
-//
-// These values should be chosen such that
-//
-// AUDIO_STREAM_BUFFER_SIZE * 1000 / (AUDIO_STREAM_OUTPUT_BUFFER_PERIODS
-// * AUDIO_STREAM_DEFAULT_RATE * 4) > 20 (ms)
-//
-// to avoid introducing the FastMixer in AudioFlinger. Using the FastMixer
-// results in unnecessary latency and CPU overhead for Bluetooth.
-#define AUDIO_STREAM_OUTPUT_BUFFER_PERIODS 2
-
-#define AUDIO_SKT_DISCONNECTED (-1)
-
-typedef enum {
- HEARING_AID_CTRL_CMD_NONE,
- HEARING_AID_CTRL_CMD_CHECK_READY,
- HEARING_AID_CTRL_CMD_START,
- HEARING_AID_CTRL_CMD_STOP,
- HEARING_AID_CTRL_CMD_SUSPEND,
- HEARING_AID_CTRL_GET_INPUT_AUDIO_CONFIG,
- HEARING_AID_CTRL_GET_OUTPUT_AUDIO_CONFIG,
- HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG,
- HEARING_AID_CTRL_CMD_OFFLOAD_START,
-} tHEARING_AID_CTRL_CMD;
-
-typedef enum {
- HEARING_AID_CTRL_ACK_SUCCESS,
- HEARING_AID_CTRL_ACK_FAILURE,
- HEARING_AID_CTRL_ACK_INCALL_FAILURE, /* Failure when in Call*/
- HEARING_AID_CTRL_ACK_UNSUPPORTED
-} tHEARING_AID_CTRL_ACK;
-
-typedef uint32_t tHA_SAMPLE_RATE;
-typedef uint8_t tHA_CHANNEL_COUNT;
-
-/*****************************************************************************
- * Type definitions for callback functions
- *****************************************************************************/
-
-/*****************************************************************************
- * Type definitions and return values
- *****************************************************************************/
-
-/*****************************************************************************
- * Extern variables and functions
- *****************************************************************************/
-
-/*****************************************************************************
- * Functions
- *****************************************************************************/
-
-// Computes the Audio Hearing Aid HAL output buffer size.
-// |codec_sample_rate| is the sample rate of the output stream.
-// |codec_bits_per_sample| is the number of bits per sample of the output
-// stream.
-// |codec_channel_mode| is the channel mode of the output stream.
-//
-// The buffer size is computed by using the following formula:
-//
-// AUDIO_STREAM_OUTPUT_BUFFER_SIZE =
-// (TIME_PERIOD_MS * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS *
-// SAMPLE_RATE_HZ * NUMBER_OF_CHANNELS * (BITS_PER_SAMPLE / 8)) / 1000
-//
-// AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is
-// divided for AudioFlinger data delivery. The AudioFlinger mixer delivers
-// data in chunks of
-// (AUDIO_STREAM_OUTPUT_BUFFER_SIZE / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS) .
-// If the number of periods is 2, the socket buffer represents "double
-// buffering" of the AudioFlinger mixer buffer.
-//
-// Furthermore, the AudioFlinger expects the buffer size to be a multiple
-// of 16 frames.
-//
-// NOTE: Currently, the computation uses the conservative 20ms time period.
-//
-// Returns the computed buffer size. If any of the input parameters is
-// invalid, the return value is the default |AUDIO_STREAM_OUTPUT_BUFFER_SZ|.
-extern size_t audio_ha_hw_stream_compute_buffer_size(
- btav_a2dp_codec_sample_rate_t codec_sample_rate,
- btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample,
- btav_a2dp_codec_channel_mode_t codec_channel_mode);
-
-#endif /* AUDIO_HEARING_AID_HW_H */
diff --git a/audio_hearing_aid_hw/src/audio_hearing_aid_hw.cc b/audio_hearing_aid_hw/src/audio_hearing_aid_hw.cc
deleted file mode 100644
index 4a9191e..0000000
--- a/audio_hearing_aid_hw/src/audio_hearing_aid_hw.cc
+++ /dev/null
@@ -1,1921 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2018 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.
- *
- ******************************************************************************/
-
-/* Implements hal for bluedroid ha audio device */
-
-#define LOG_TAG "bt_hearing_aid_hw"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <sys/errno.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <mutex>
-
-#include <hardware/audio.h>
-#include <hardware/hardware.h>
-#include <log/log.h>
-#include <system/audio.h>
-
-#include "osi/include/hash_map_utils.h"
-#include "osi/include/osi.h"
-#include "osi/include/socket_utils/sockets.h"
-
-#include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h"
-
-/*****************************************************************************
- * Constants & Macros
- *****************************************************************************/
-
-#define CTRL_CHAN_RETRY_COUNT 3
-#define USEC_PER_SEC 1000000L
-#define SOCK_SEND_TIMEOUT_MS 2000 /* Timeout for sending */
-#define SOCK_RECV_TIMEOUT_MS 5000 /* Timeout for receiving */
-
-// set WRITE_POLL_MS to 0 for blocking sockets, nonzero for polled non-blocking
-// sockets
-#define WRITE_POLL_MS 20
-
-#define FNLOG() ALOGV("%s:%d %s: ", __FILE__, __LINE__, __func__)
-#define DEBUG(fmt, args...) \
- ALOGD("%s:%d %s: " fmt, __FILE__, __LINE__, __func__, ##args)
-#define INFO(fmt, args...) \
- ALOGI("%s:%d %s: " fmt, __FILE__, __LINE__, __func__, ##args)
-#define WARN(fmt, args...) \
- ALOGW("%s:%d %s: " fmt, __FILE__, __LINE__, __func__, ##args)
-#define ERROR(fmt, args...) \
- ALOGE("%s:%d %s: " fmt, __FILE__, __LINE__, __func__, ##args)
-
-#define ASSERTC(cond, msg, val) \
- if (!(cond)) { \
- ERROR("### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, \
- val); \
- }
-
-#define CASE_RETURN_STR(const) \
- case const: \
- return #const;
-
-static const char* audio_ha_hw_dump_ctrl_event(tHEARING_AID_CTRL_CMD event) {
- switch (event) {
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_NONE)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_CHECK_READY)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_START)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_STOP)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_SUSPEND)
- CASE_RETURN_STR(HEARING_AID_CTRL_GET_INPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(HEARING_AID_CTRL_GET_OUTPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_OFFLOAD_START)
- default:
- break;
- }
-
- return "UNKNOWN HEARING_AID_CTRL_CMD";
-}
-
-/*****************************************************************************
- * Local type definitions
- *****************************************************************************/
-
-typedef enum {
- AUDIO_HA_STATE_STARTING,
- AUDIO_HA_STATE_STARTED,
- AUDIO_HA_STATE_STOPPING,
- AUDIO_HA_STATE_STOPPED,
- /* need explicit set param call to resume (suspend=false) */
- AUDIO_HA_STATE_SUSPENDED,
- AUDIO_HA_STATE_STANDBY /* allows write to autoresume */
-} ha_state_t;
-
-struct ha_stream_in;
-struct ha_stream_out;
-
-struct ha_audio_device {
- // Important: device must be first as an audio_hw_device* may be cast to
- // ha_audio_device* when the type is implicitly known.
- struct audio_hw_device device;
- std::recursive_mutex* mutex; // See note below on mutex acquisition order.
- struct ha_stream_in* input;
- struct ha_stream_out* output;
-};
-
-struct ha_config {
- uint32_t rate;
- uint32_t channel_mask;
- bool is_stereo_to_mono; // True if fetching Stereo and mixing into Mono
- int format;
-};
-
-/* move ctrl_fd outside output stream and keep open until HAL unloaded ? */
-
-struct ha_stream_common {
- std::recursive_mutex* mutex; // See note below on mutex acquisition order.
- int ctrl_fd;
- int audio_fd;
- size_t buffer_sz;
- struct ha_config cfg;
- ha_state_t state;
-};
-
-struct ha_stream_out {
- struct audio_stream_out stream;
- struct ha_stream_common common;
- uint64_t frames_presented; // frames written, never reset
- uint64_t frames_rendered; // frames written, reset on standby
-};
-
-struct ha_stream_in {
- struct audio_stream_in stream;
- struct ha_stream_common common;
-};
-
-/*
- * Mutex acquisition order:
- *
- * The ha_audio_device (adev) mutex must be acquired before
- * the ha_stream_common (out or in) mutex.
- *
- * This may differ from other audio HALs.
- */
-
-/*****************************************************************************
- * Static variables
- *****************************************************************************/
-
-/*****************************************************************************
- * Static functions
- *****************************************************************************/
-static void hash_map_utils_dump_string_keys_string_values(
- std::unordered_map<std::string, std::string>& map) {
- for (const auto& ptr : map) {
- INFO("key: '%s' value: '%s'\n", ptr.first.c_str(), ptr.second.c_str());
- }
-}
-
-static size_t out_get_buffer_size(const struct audio_stream* stream);
-
-/*****************************************************************************
- * Externs
- *****************************************************************************/
-
-/*****************************************************************************
- * Functions
- *****************************************************************************/
-static void ha_open_ctrl_path(struct ha_stream_common* common);
-
-/*****************************************************************************
- * Miscellaneous helper functions
- *****************************************************************************/
-
-/* logs timestamp with microsec precision
- pprev is optional in case a dedicated diff is required */
-static void ts_log(UNUSED_ATTR const char* tag, UNUSED_ATTR int val,
- struct timespec* pprev_opt) {
- struct timespec now;
- static struct timespec prev = {0, 0};
- unsigned long long now_us;
- unsigned long long diff_us;
-
- clock_gettime(CLOCK_MONOTONIC, &now);
-
- now_us = now.tv_sec * USEC_PER_SEC + now.tv_nsec / 1000;
-
- if (pprev_opt) {
- diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC +
- (now.tv_nsec - prev.tv_nsec) / 1000;
- *pprev_opt = now;
- DEBUG("[%s] ts %08lld, *diff %08lld, val %d", tag, now_us, diff_us, val);
- } else {
- diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC +
- (now.tv_nsec - prev.tv_nsec) / 1000;
- prev = now;
- DEBUG("[%s] ts %08lld, diff %08lld, val %d", tag, now_us, diff_us, val);
- }
-}
-
-static int calc_audiotime_usec(struct ha_config cfg, int bytes) {
- int chan_count = audio_channel_count_from_out_mask(cfg.channel_mask);
- int bytes_per_sample;
-
- switch (cfg.format) {
- case AUDIO_FORMAT_PCM_8_BIT:
- bytes_per_sample = 1;
- break;
- case AUDIO_FORMAT_PCM_16_BIT:
- bytes_per_sample = 2;
- break;
- case AUDIO_FORMAT_PCM_24_BIT_PACKED:
- bytes_per_sample = 3;
- break;
- case AUDIO_FORMAT_PCM_8_24_BIT:
- bytes_per_sample = 4;
- break;
- case AUDIO_FORMAT_PCM_32_BIT:
- bytes_per_sample = 4;
- break;
- default:
- ASSERTC(false, "unsupported sample format", cfg.format);
- bytes_per_sample = 2;
- break;
- }
-
- return (
- int)(((int64_t)bytes * (USEC_PER_SEC / (chan_count * bytes_per_sample))) /
- cfg.rate);
-}
-
-/*****************************************************************************
- *
- * bluedroid stack adaptation
- *
- ****************************************************************************/
-
-static int skt_connect(const char* path, size_t buffer_sz) {
- int ret;
- int skt_fd;
- int len;
-
- INFO("connect to %s (sz %zu)", path, buffer_sz);
-
- skt_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
-
- if (osi_socket_local_client_connect(
- skt_fd, path, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0) {
- ERROR("failed to connect (%s)", strerror(errno));
- close(skt_fd);
- return -1;
- }
-
- len = buffer_sz;
- ret =
- setsockopt(skt_fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, (int)sizeof(len));
- if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
-
- ret =
- setsockopt(skt_fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, (int)sizeof(len));
- if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
-
- /* Socket send/receive timeout value */
- struct timeval tv;
- tv.tv_sec = SOCK_SEND_TIMEOUT_MS / 1000;
- tv.tv_usec = (SOCK_SEND_TIMEOUT_MS % 1000) * 1000;
-
- ret = setsockopt(skt_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
- if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
-
- tv.tv_sec = SOCK_RECV_TIMEOUT_MS / 1000;
- tv.tv_usec = (SOCK_RECV_TIMEOUT_MS % 1000) * 1000;
-
- ret = setsockopt(skt_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
- if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
-
- INFO("connected to stack fd = %d", skt_fd);
-
- return skt_fd;
-}
-
-static int skt_read(int fd, void* p, size_t len) {
- ssize_t read;
-
- FNLOG();
-
- ts_log("skt_read recv", len, NULL);
-
- OSI_NO_INTR(read = recv(fd, p, len, MSG_NOSIGNAL));
- if (read == -1) ERROR("read failed with errno=%d\n", errno);
-
- return (int)read;
-}
-
-static int skt_write(int fd, const void* p, size_t len) {
- ssize_t sent;
- FNLOG();
-
- ts_log("skt_write", len, NULL);
-
- if (WRITE_POLL_MS == 0) {
- // do not poll, use blocking send
- OSI_NO_INTR(sent = send(fd, p, len, MSG_NOSIGNAL));
- if (sent == -1) ERROR("write failed with error(%s)", strerror(errno));
-
- return (int)sent;
- }
-
- // use non-blocking send, poll
- int ms_timeout = SOCK_SEND_TIMEOUT_MS;
- size_t count = 0;
- while (count < len) {
- OSI_NO_INTR(sent = send(fd, p, len - count, MSG_NOSIGNAL | MSG_DONTWAIT));
- if (sent == -1) {
- if (errno != EAGAIN && errno != EWOULDBLOCK) {
- ERROR("write failed with error(%s)", strerror(errno));
- return -1;
- }
- if (ms_timeout >= WRITE_POLL_MS) {
- usleep(WRITE_POLL_MS * 1000);
- ms_timeout -= WRITE_POLL_MS;
- continue;
- }
- WARN("write timeout exceeded, sent %zu bytes", count);
- return -1;
- }
- count += sent;
- p = (const uint8_t*)p + sent;
- }
- return (int)count;
-}
-
-static int skt_disconnect(int fd) {
- INFO("fd %d", fd);
-
- if (fd != AUDIO_SKT_DISCONNECTED) {
- shutdown(fd, SHUT_RDWR);
- close(fd);
- }
- return 0;
-}
-
-/*****************************************************************************
- *
- * AUDIO CONTROL PATH
- *
- ****************************************************************************/
-
-static int ha_ctrl_receive(struct ha_stream_common* common, void* buffer,
- size_t length) {
- ssize_t ret;
- int i;
-
- for (i = 0;; i++) {
- OSI_NO_INTR(ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL));
- if (ret > 0) {
- break;
- }
- if (ret == 0) {
- ERROR("receive control data failed: peer closed");
- break;
- }
- if (errno != EWOULDBLOCK && errno != EAGAIN) {
- ERROR("receive control data failed: error(%s)", strerror(errno));
- break;
- }
- if (i == (CTRL_CHAN_RETRY_COUNT - 1)) {
- ERROR("receive control data failed: max retry count");
- break;
- }
- INFO("receive control data failed (%s), retrying", strerror(errno));
- }
- if (ret <= 0) {
- skt_disconnect(common->ctrl_fd);
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- }
- return ret;
-}
-
-// Sends control info for stream |common|. The data to send is stored in
-// |buffer| and has size |length|.
-// On success, returns the number of octets sent, otherwise -1.
-static int ha_ctrl_send(struct ha_stream_common* common, const void* buffer,
- size_t length) {
- ssize_t sent;
- size_t remaining = length;
- int i;
-
- if (length == 0) return 0; // Nothing to do
-
- for (i = 0;; i++) {
- OSI_NO_INTR(sent = send(common->ctrl_fd, buffer, remaining, MSG_NOSIGNAL));
- if (sent == static_cast<ssize_t>(remaining)) {
- remaining = 0;
- break;
- }
- if (sent > 0) {
- buffer = (static_cast<const char*>(buffer) + sent);
- remaining -= sent;
- continue;
- }
- if (sent < 0) {
- if (errno != EWOULDBLOCK && errno != EAGAIN) {
- ERROR("send control data failed: error(%s)", strerror(errno));
- break;
- }
- INFO("send control data failed (%s), retrying", strerror(errno));
- }
- if (i >= (CTRL_CHAN_RETRY_COUNT - 1)) {
- ERROR("send control data failed: max retry count");
- break;
- }
- }
- if (remaining > 0) {
- skt_disconnect(common->ctrl_fd);
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- return -1;
- }
- return length;
-}
-
-static int ha_command(struct ha_stream_common* common,
- tHEARING_AID_CTRL_CMD cmd) {
- char ack;
-
- DEBUG("HEARING_AID COMMAND %s", audio_ha_hw_dump_ctrl_event(cmd));
-
- if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) {
- INFO("starting up or recovering from previous error");
- ha_open_ctrl_path(common);
- if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) {
- ERROR("failure to open ctrl path");
- return -1;
- }
- }
-
- /* send command */
- ssize_t sent;
- OSI_NO_INTR(sent = send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL));
- if (sent == -1) {
- ERROR("cmd failed (%s)", strerror(errno));
- skt_disconnect(common->ctrl_fd);
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- return -1;
- }
-
- /* wait for ack byte */
- if (ha_ctrl_receive(common, &ack, 1) < 0) {
- ERROR("HEARING_AID COMMAND %s: no ACK", audio_ha_hw_dump_ctrl_event(cmd));
- return -1;
- }
-
- DEBUG("HEARING_AID COMMAND %s DONE STATUS %d",
- audio_ha_hw_dump_ctrl_event(cmd), ack);
-
- if (ack == HEARING_AID_CTRL_ACK_INCALL_FAILURE) return ack;
- if (ack != HEARING_AID_CTRL_ACK_SUCCESS) {
- ERROR("HEARING_AID COMMAND %s error %d", audio_ha_hw_dump_ctrl_event(cmd),
- ack);
- return -1;
- }
-
- return 0;
-}
-
-static int check_ha_ready(struct ha_stream_common* common) {
- if (ha_command(common, HEARING_AID_CTRL_CMD_CHECK_READY) < 0) {
- ERROR("check ha ready failed");
- return -1;
- }
- return 0;
-}
-
-static int ha_read_input_audio_config(struct ha_stream_common* common) {
- tHA_SAMPLE_RATE sample_rate;
- tHA_CHANNEL_COUNT channel_count;
-
- if (ha_command(common, HEARING_AID_CTRL_GET_INPUT_AUDIO_CONFIG) < 0) {
- ERROR("get ha input audio config failed");
- return -1;
- }
-
- if (ha_ctrl_receive(common, &sample_rate, sizeof(tHA_SAMPLE_RATE)) < 0)
- return -1;
- if (ha_ctrl_receive(common, &channel_count, sizeof(tHA_CHANNEL_COUNT)) < 0) {
- return -1;
- }
-
- switch (sample_rate) {
- case 16000:
- case 24000:
- case 44100:
- case 48000:
- common->cfg.rate = sample_rate;
- break;
- default:
- ERROR("Invalid sample rate: %" PRIu32, sample_rate);
- return -1;
- }
-
- switch (channel_count) {
- case 1:
- common->cfg.channel_mask = AUDIO_CHANNEL_IN_MONO;
- break;
- case 2:
- common->cfg.channel_mask = AUDIO_CHANNEL_IN_STEREO;
- break;
- default:
- ERROR("Invalid channel count: %" PRIu32, channel_count);
- return -1;
- }
-
- // TODO: For now input audio format is always hard-coded as PCM 16-bit
- common->cfg.format = AUDIO_FORMAT_PCM_16_BIT;
-
- INFO("got input audio config %d %d", common->cfg.format, common->cfg.rate);
-
- return 0;
-}
-
-static int ha_read_output_audio_config(
- struct ha_stream_common* common, btav_a2dp_codec_config_t* codec_config,
- btav_a2dp_codec_config_t* codec_capability, bool update_stream_config) {
- struct ha_config stream_config;
-
- if (ha_command(common, HEARING_AID_CTRL_GET_OUTPUT_AUDIO_CONFIG) < 0) {
- ERROR("get ha output audio config failed");
- return -1;
- }
-
- // Receive the current codec config
- if (ha_ctrl_receive(common, &codec_config->sample_rate,
- sizeof(btav_a2dp_codec_sample_rate_t)) < 0) {
- return -1;
- }
- if (ha_ctrl_receive(common, &codec_config->bits_per_sample,
- sizeof(btav_a2dp_codec_bits_per_sample_t)) < 0) {
- return -1;
- }
- if (ha_ctrl_receive(common, &codec_config->channel_mode,
- sizeof(btav_a2dp_codec_channel_mode_t)) < 0) {
- return -1;
- }
-
- // Receive the current codec capability
- if (ha_ctrl_receive(common, &codec_capability->sample_rate,
- sizeof(btav_a2dp_codec_sample_rate_t)) < 0) {
- return -1;
- }
- if (ha_ctrl_receive(common, &codec_capability->bits_per_sample,
- sizeof(btav_a2dp_codec_bits_per_sample_t)) < 0) {
- return -1;
- }
- if (ha_ctrl_receive(common, &codec_capability->channel_mode,
- sizeof(btav_a2dp_codec_channel_mode_t)) < 0) {
- return -1;
- }
-
- // Check the codec config sample rate
- switch (codec_config->sample_rate) {
- case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
- stream_config.rate = 44100;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
- stream_config.rate = 48000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
- stream_config.rate = 88200;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
- stream_config.rate = 96000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
- stream_config.rate = 176400;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
- stream_config.rate = 192000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
- stream_config.rate = 16000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
- stream_config.rate = 24000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE:
- default:
- ERROR("Invalid sample rate: 0x%x", codec_config->sample_rate);
- return -1;
- }
-
- // Check the codec config bits per sample
- switch (codec_config->bits_per_sample) {
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
- stream_config.format = AUDIO_FORMAT_PCM_16_BIT;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
- stream_config.format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
- stream_config.format = AUDIO_FORMAT_PCM_32_BIT;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
- default:
- ERROR("Invalid bits per sample: 0x%x", codec_config->bits_per_sample);
- return -1;
- }
-
- // Check the codec config channel mode
- switch (codec_config->channel_mode) {
- case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
- stream_config.channel_mask = AUDIO_CHANNEL_OUT_MONO;
- stream_config.is_stereo_to_mono = true;
- break;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
- stream_config.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
- stream_config.is_stereo_to_mono = false;
- break;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
- default:
- ERROR("Invalid channel mode: 0x%x", codec_config->channel_mode);
- return -1;
- }
- if (stream_config.is_stereo_to_mono) {
- stream_config.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
- }
-
- // Update the output stream configuration
- if (update_stream_config) {
- common->cfg.rate = stream_config.rate;
- common->cfg.channel_mask = stream_config.channel_mask;
- common->cfg.is_stereo_to_mono = stream_config.is_stereo_to_mono;
- common->cfg.format = stream_config.format;
- common->buffer_sz = audio_ha_hw_stream_compute_buffer_size(
- codec_config->sample_rate, codec_config->bits_per_sample,
- codec_config->channel_mode);
- if (common->cfg.is_stereo_to_mono) {
- // We need to fetch twice as much data from the Audio framework
- common->buffer_sz *= 2;
- }
- }
-
- INFO(
- "got output codec config (update_stream_config=%s): "
- "sample_rate=0x%x bits_per_sample=0x%x channel_mode=0x%x",
- update_stream_config ? "true" : "false", codec_config->sample_rate,
- codec_config->bits_per_sample, codec_config->channel_mode);
-
- INFO(
- "got output codec capability: sample_rate=0x%x bits_per_sample=0x%x "
- "channel_mode=0x%x",
- codec_capability->sample_rate, codec_capability->bits_per_sample,
- codec_capability->channel_mode);
-
- return 0;
-}
-
-static int ha_write_output_audio_config(struct ha_stream_common* common) {
- btav_a2dp_codec_config_t codec_config;
-
- if (ha_command(common, HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG) < 0) {
- ERROR("set ha output audio config failed");
- return -1;
- }
-
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
-
- switch (common->cfg.rate) {
- case 44100:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
- break;
- case 48000:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_48000;
- break;
- case 88200:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_88200;
- break;
- case 96000:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_96000;
- break;
- case 176400:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_176400;
- break;
- case 192000:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_192000;
- break;
- case 16000:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_16000;
- break;
- case 24000:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_24000;
- break;
- default:
- ERROR("Invalid sample rate: %" PRIu32, common->cfg.rate);
- return -1;
- }
-
- switch (common->cfg.format) {
- case AUDIO_FORMAT_PCM_16_BIT:
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;
- break;
- case AUDIO_FORMAT_PCM_24_BIT_PACKED:
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24;
- break;
- case AUDIO_FORMAT_PCM_32_BIT:
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32;
- break;
- case AUDIO_FORMAT_PCM_8_24_BIT:
- // All 24-bit audio is expected in AUDIO_FORMAT_PCM_24_BIT_PACKED format
- FALLTHROUGH_INTENDED; /* FALLTHROUGH */
- default:
- ERROR("Invalid audio format: 0x%x", common->cfg.format);
- return -1;
- }
-
- switch (common->cfg.channel_mask) {
- case AUDIO_CHANNEL_OUT_MONO:
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
- break;
- case AUDIO_CHANNEL_OUT_STEREO:
- if (common->cfg.is_stereo_to_mono) {
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
- } else {
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
- }
- break;
- default:
- ERROR("Invalid channel mask: 0x%x", common->cfg.channel_mask);
- return -1;
- }
-
- // Send the current codec config that has been selected by us
- if (ha_ctrl_send(common, &codec_config.sample_rate,
- sizeof(btav_a2dp_codec_sample_rate_t)) < 0)
- return -1;
- if (ha_ctrl_send(common, &codec_config.bits_per_sample,
- sizeof(btav_a2dp_codec_bits_per_sample_t)) < 0) {
- return -1;
- }
- if (ha_ctrl_send(common, &codec_config.channel_mode,
- sizeof(btav_a2dp_codec_channel_mode_t)) < 0) {
- return -1;
- }
-
- INFO(
- "sent output codec config: sample_rate=0x%x bits_per_sample=0x%x "
- "channel_mode=0x%x",
- codec_config.sample_rate, codec_config.bits_per_sample,
- codec_config.channel_mode);
-
- return 0;
-}
-
-static void ha_open_ctrl_path(struct ha_stream_common* common) {
- int i;
-
- if (common->ctrl_fd != AUDIO_SKT_DISCONNECTED) return; // already connected
-
- /* retry logic to catch any timing variations on control channel */
- for (i = 0; i < CTRL_CHAN_RETRY_COUNT; i++) {
- /* connect control channel if not already connected */
- if ((common->ctrl_fd = skt_connect(
- HEARING_AID_CTRL_PATH, AUDIO_STREAM_CONTROL_OUTPUT_BUFFER_SZ)) >=
- 0) {
- /* success, now check if stack is ready */
- if (check_ha_ready(common) == 0) break;
-
- ERROR("error : ha not ready, wait 250 ms and retry");
- usleep(250000);
- skt_disconnect(common->ctrl_fd);
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- }
-
- /* ctrl channel not ready, wait a bit */
- usleep(250000);
- }
-}
-
-/*****************************************************************************
- *
- * AUDIO DATA PATH
- *
- ****************************************************************************/
-
-static void ha_stream_common_init(struct ha_stream_common* common) {
- FNLOG();
-
- common->mutex = new std::recursive_mutex;
-
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- common->audio_fd = AUDIO_SKT_DISCONNECTED;
- common->state = AUDIO_HA_STATE_STOPPED;
-
- /* manages max capacity of socket pipe */
- common->buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ;
-}
-
-static void ha_stream_common_destroy(struct ha_stream_common* common) {
- FNLOG();
-
- delete common->mutex;
- common->mutex = NULL;
-}
-
-static int start_audio_datapath(struct ha_stream_common* common) {
- INFO("state %d", common->state);
-
- int oldstate = common->state;
- common->state = AUDIO_HA_STATE_STARTING;
-
- int ha_status = ha_command(common, HEARING_AID_CTRL_CMD_START);
- if (ha_status < 0) {
- ERROR("Audiopath start failed (status %d)", ha_status);
- goto error;
- } else if (ha_status == HEARING_AID_CTRL_ACK_INCALL_FAILURE) {
- ERROR("Audiopath start failed - in call, move to suspended");
- goto error;
- }
-
- /* connect socket if not yet connected */
- if (common->audio_fd == AUDIO_SKT_DISCONNECTED) {
- common->audio_fd = skt_connect(HEARING_AID_DATA_PATH, common->buffer_sz);
- if (common->audio_fd < 0) {
- ERROR("Audiopath start failed - error opening data socket");
- goto error;
- }
- }
- common->state = (ha_state_t)AUDIO_HA_STATE_STARTED;
- return 0;
-
-error:
- common->state = (ha_state_t)oldstate;
- return -1;
-}
-
-static int stop_audio_datapath(struct ha_stream_common* common) {
- int oldstate = common->state;
-
- INFO("state %d", common->state);
-
- /* prevent any stray output writes from autostarting the stream
- while stopping audiopath */
- common->state = AUDIO_HA_STATE_STOPPING;
-
- if (ha_command(common, HEARING_AID_CTRL_CMD_STOP) < 0) {
- ERROR("audiopath stop failed");
- common->state = (ha_state_t)oldstate;
- return -1;
- }
-
- common->state = (ha_state_t)AUDIO_HA_STATE_STOPPED;
-
- /* disconnect audio path */
- skt_disconnect(common->audio_fd);
- common->audio_fd = AUDIO_SKT_DISCONNECTED;
-
- return 0;
-}
-
-static int suspend_audio_datapath(struct ha_stream_common* common,
- bool standby) {
- INFO("state %d", common->state);
-
- if (common->state == AUDIO_HA_STATE_STOPPING) return -1;
-
- if (ha_command(common, HEARING_AID_CTRL_CMD_SUSPEND) < 0) return -1;
-
- if (standby)
- common->state = AUDIO_HA_STATE_STANDBY;
- else
- common->state = AUDIO_HA_STATE_SUSPENDED;
-
- /* disconnect audio path */
- skt_disconnect(common->audio_fd);
-
- common->audio_fd = AUDIO_SKT_DISCONNECTED;
-
- return 0;
-}
-
-/*****************************************************************************
- *
- * audio output callbacks
- *
- ****************************************************************************/
-
-static ssize_t out_write(struct audio_stream_out* stream, const void* buffer,
- size_t bytes) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
- int sent = -1;
- size_t write_bytes = bytes;
-
- DEBUG("write %zu bytes (fd %d)", bytes, out->common.audio_fd);
-
- std::unique_lock<std::recursive_mutex> lock(*out->common.mutex);
- if (out->common.state == AUDIO_HA_STATE_SUSPENDED ||
- out->common.state == AUDIO_HA_STATE_STOPPING) {
- DEBUG("stream suspended or closing");
- goto finish;
- }
-
- /* only allow autostarting if we are in stopped or standby */
- if ((out->common.state == AUDIO_HA_STATE_STOPPED) ||
- (out->common.state == AUDIO_HA_STATE_STANDBY)) {
- if (start_audio_datapath(&out->common) < 0) {
- goto finish;
- }
- } else if (out->common.state != AUDIO_HA_STATE_STARTED) {
- ERROR("stream not in stopped or standby");
- goto finish;
- }
-
- // Mix the stereo into mono if necessary
- if (out->common.cfg.is_stereo_to_mono) {
- const size_t frames = bytes / audio_stream_out_frame_size(stream);
- int16_t* src = (int16_t*)buffer;
- int16_t* dst = (int16_t*)buffer;
- for (size_t i = 0; i < frames; i++, dst++, src += 2) {
- *dst = (int16_t)(((int32_t)src[0] + (int32_t)src[1]) >> 1);
- }
- write_bytes /= 2;
- DEBUG("stereo-to-mono mixing: write %zu bytes (fd %d)", write_bytes,
- out->common.audio_fd);
- }
-
- lock.unlock();
- sent = skt_write(out->common.audio_fd, buffer, write_bytes);
- lock.lock();
-
- if (sent == -1) {
- skt_disconnect(out->common.audio_fd);
- out->common.audio_fd = AUDIO_SKT_DISCONNECTED;
- if ((out->common.state != AUDIO_HA_STATE_SUSPENDED) &&
- (out->common.state != AUDIO_HA_STATE_STOPPING)) {
- out->common.state = AUDIO_HA_STATE_STOPPED;
- } else {
- ERROR("write failed : stream suspended, avoid resetting state");
- }
- goto finish;
- }
-
-finish:;
- const size_t frames = bytes / audio_stream_out_frame_size(stream);
- out->frames_rendered += frames;
- out->frames_presented += frames;
- lock.unlock();
-
- // If send didn't work out, sleep to emulate write delay.
- if (sent == -1) {
- const int us_delay = calc_audiotime_usec(out->common.cfg, bytes);
- DEBUG("emulate ha write delay (%d us)", us_delay);
- usleep(us_delay);
- }
- return bytes;
-}
-
-static uint32_t out_get_sample_rate(const struct audio_stream* stream) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- DEBUG("rate %" PRIu32, out->common.cfg.rate);
-
- return out->common.cfg.rate;
-}
-
-static int out_set_sample_rate(struct audio_stream* stream, uint32_t rate) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- DEBUG("out_set_sample_rate : %" PRIu32, rate);
-
- out->common.cfg.rate = rate;
-
- return 0;
-}
-
-static size_t out_get_buffer_size(const struct audio_stream* stream) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
- // period_size is the AudioFlinger mixer buffer size.
- const size_t period_size =
- out->common.buffer_sz / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS;
-
- DEBUG("socket buffer size: %zu period size: %zu", out->common.buffer_sz,
- period_size);
-
- return period_size;
-}
-
-size_t audio_ha_hw_stream_compute_buffer_size(
- btav_a2dp_codec_sample_rate_t codec_sample_rate,
- btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample,
- btav_a2dp_codec_channel_mode_t codec_channel_mode) {
- size_t buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ; // Default value
- const uint64_t time_period_ms = 20; // Conservative 20ms
- uint32_t sample_rate;
- uint32_t bits_per_sample;
- uint32_t number_of_channels;
-
- // Check the codec config sample rate
- switch (codec_sample_rate) {
- case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
- sample_rate = 44100;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
- sample_rate = 48000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
- sample_rate = 88200;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
- sample_rate = 96000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
- sample_rate = 176400;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
- sample_rate = 192000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
- sample_rate = 16000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
- sample_rate = 24000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE:
- default:
- ERROR("Invalid sample rate: 0x%x", codec_sample_rate);
- return buffer_sz;
- }
-
- // Check the codec config bits per sample
- switch (codec_bits_per_sample) {
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
- bits_per_sample = 16;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
- bits_per_sample = 24;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
- bits_per_sample = 32;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
- default:
- ERROR("Invalid bits per sample: 0x%x", codec_bits_per_sample);
- return buffer_sz;
- }
-
- // Check the codec config channel mode
- switch (codec_channel_mode) {
- case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
- number_of_channels = 1;
- break;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
- number_of_channels = 2;
- break;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
- default:
- ERROR("Invalid channel mode: 0x%x", codec_channel_mode);
- return buffer_sz;
- }
-
- //
- // The buffer size is computed by using the following formula:
- //
- // AUDIO_STREAM_OUTPUT_BUFFER_SIZE =
- // (TIME_PERIOD_MS * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS *
- // SAMPLE_RATE_HZ * NUMBER_OF_CHANNELS * (BITS_PER_SAMPLE / 8)) / 1000
- //
- // AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is
- // divided for AudioFlinger data delivery. The AudioFlinger mixer delivers
- // data in chunks of
- // (AUDIO_STREAM_OUTPUT_BUFFER_SIZE / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS) .
- // If the number of periods is 2, the socket buffer represents "double
- // buffering" of the AudioFlinger mixer buffer.
- //
- // Furthermore, the AudioFlinger expects the buffer size to be a multiple
- // of 16 frames.
- const size_t divisor = (AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * 16 *
- number_of_channels * bits_per_sample) /
- 8;
-
- buffer_sz = (time_period_ms * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS *
- sample_rate * number_of_channels * (bits_per_sample / 8)) /
- 1000;
-
- // Adjust the buffer size so it can be divided by the divisor
- const size_t remainder = buffer_sz % divisor;
- if (remainder != 0) {
- buffer_sz += divisor - remainder;
- }
-
- return buffer_sz;
-}
-
-static audio_channel_mask_t out_get_channels(
- const struct audio_stream* stream) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- DEBUG("channels 0x%" PRIx32, out->common.cfg.channel_mask);
-
- return (audio_channel_mask_t)out->common.cfg.channel_mask;
-}
-
-static audio_format_t out_get_format(const struct audio_stream* stream) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
- DEBUG("format 0x%x", out->common.cfg.format);
- return (audio_format_t)out->common.cfg.format;
-}
-
-static int out_set_format(UNUSED_ATTR struct audio_stream* stream,
- UNUSED_ATTR audio_format_t format) {
- DEBUG("setting format not yet supported (0x%x)", format);
- return -ENOSYS;
-}
-
-static int out_standby(struct audio_stream* stream) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
- int retVal = 0;
-
- FNLOG();
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
- // Do nothing in SUSPENDED state.
- if (out->common.state != AUDIO_HA_STATE_SUSPENDED)
- retVal = suspend_audio_datapath(&out->common, true);
- out->frames_rendered = 0; // rendered is reset, presented is not
-
- return retVal;
-}
-
-static int out_dump(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR int fd) {
- FNLOG();
- return 0;
-}
-
-static int out_set_parameters(struct audio_stream* stream,
- const char* kvpairs) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- INFO("state %d kvpairs %s", out->common.state, kvpairs);
-
- std::unordered_map<std::string, std::string> params =
- hash_map_utils_new_from_string_params(kvpairs);
- int status = 0;
-
- if (params.empty()) return status;
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
-
- /* dump params */
- hash_map_utils_dump_string_keys_string_values(params);
-
- if (params["closing"].compare("true") == 0) {
- DEBUG("stream closing, disallow any writes");
- out->common.state = AUDIO_HA_STATE_STOPPING;
- }
-
- if (params["HearingAidSuspended"].compare("true") == 0) {
- if (out->common.state == AUDIO_HA_STATE_STARTED)
- status = suspend_audio_datapath(&out->common, false);
- } else {
- /* Do not start the streaming automatically. If the phone was streaming
- * prior to being suspended, the next out_write shall trigger the
- * AVDTP start procedure */
- if (out->common.state == AUDIO_HA_STATE_SUSPENDED)
- out->common.state = AUDIO_HA_STATE_STANDBY;
- /* Irrespective of the state, return 0 */
- }
-
- return status;
-}
-
-static char* out_get_parameters(const struct audio_stream* stream,
- const char* keys) {
- FNLOG();
-
- btav_a2dp_codec_config_t codec_config;
- btav_a2dp_codec_config_t codec_capability;
-
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- std::unordered_map<std::string, std::string> params =
- hash_map_utils_new_from_string_params(keys);
- std::unordered_map<std::string, std::string> return_params;
-
- if (params.empty()) return strdup("");
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
-
- if (ha_read_output_audio_config(&out->common, &codec_config,
- &codec_capability,
- false /* update_stream_config */) < 0) {
- ERROR("ha_read_output_audio_config failed");
- goto done;
- }
-
- // Add the format
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_FORMATS) != params.end()) {
- std::string param;
- if (codec_capability.bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16) {
- if (!param.empty()) param += "|";
- param += "AUDIO_FORMAT_PCM_16_BIT";
- }
- if (codec_capability.bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24) {
- if (!param.empty()) param += "|";
- param += "AUDIO_FORMAT_PCM_24_BIT_PACKED";
- }
- if (codec_capability.bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32) {
- if (!param.empty()) param += "|";
- param += "AUDIO_FORMAT_PCM_32_BIT";
- }
- if (param.empty()) {
- ERROR("Invalid codec capability bits_per_sample=0x%x",
- codec_capability.bits_per_sample);
- goto done;
- } else {
- return_params[AUDIO_PARAMETER_STREAM_SUP_FORMATS] = param;
- }
- }
-
- // Add the sample rate
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES) != params.end()) {
- std::string param;
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_44100) {
- if (!param.empty()) param += "|";
- param += "44100";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_48000) {
- if (!param.empty()) param += "|";
- param += "48000";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_88200) {
- if (!param.empty()) param += "|";
- param += "88200";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_96000) {
- if (!param.empty()) param += "|";
- param += "96000";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_176400) {
- if (!param.empty()) param += "|";
- param += "176400";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_192000) {
- if (!param.empty()) param += "|";
- param += "192000";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_16000) {
- if (!param.empty()) param += "|";
- param += "16000";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_24000) {
- if (!param.empty()) param += "|";
- param += "24000";
- }
- if (param.empty()) {
- ERROR("Invalid codec capability sample_rate=0x%x",
- codec_capability.sample_rate);
- goto done;
- } else {
- return_params[AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES] = param;
- }
- }
-
- // Add the channel mask
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_CHANNELS) != params.end()) {
- std::string param;
- if (codec_capability.channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_MONO) {
- if (!param.empty()) param += "|";
- param += "AUDIO_CHANNEL_OUT_MONO";
- }
- if (codec_capability.channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO) {
- if (!param.empty()) param += "|";
- param += "AUDIO_CHANNEL_OUT_STEREO";
- }
- if (param.empty()) {
- ERROR("Invalid codec capability channel_mode=0x%x",
- codec_capability.channel_mode);
- goto done;
- } else {
- return_params[AUDIO_PARAMETER_STREAM_SUP_CHANNELS] = param;
- }
- }
-
-done:
- std::string result;
- for (const auto& ptr : return_params) {
- result += ptr.first + "=" + ptr.second + ";";
- }
-
- INFO("get parameters result = %s", result.c_str());
-
- return strdup(result.c_str());
-}
-
-static uint32_t out_get_latency(const struct audio_stream_out* stream) {
- int latency_us;
-
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- FNLOG();
-
- latency_us =
- ((out->common.buffer_sz * 1000) /
- audio_stream_out_frame_size(&out->stream) / out->common.cfg.rate) *
- 1000;
-
- return (latency_us / 1000) + 200;
-}
-
-static int out_set_volume(UNUSED_ATTR struct audio_stream_out* stream,
- UNUSED_ATTR float left, UNUSED_ATTR float right) {
- FNLOG();
-
- /* volume controlled in audioflinger mixer (digital) */
-
- return -ENOSYS;
-}
-
-static int out_get_presentation_position(const struct audio_stream_out* stream,
- uint64_t* frames,
- struct timespec* timestamp) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- FNLOG();
- if (stream == NULL || frames == NULL || timestamp == NULL) return -EINVAL;
-
- int ret = -EWOULDBLOCK;
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
- uint64_t latency_frames =
- (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
- if (out->frames_presented >= latency_frames) {
- *frames = out->frames_presented - latency_frames;
- clock_gettime(CLOCK_MONOTONIC,
- timestamp); // could also be associated with out_write().
- ret = 0;
- }
- return ret;
-}
-
-static int out_get_render_position(const struct audio_stream_out* stream,
- uint32_t* dsp_frames) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- FNLOG();
- if (stream == NULL || dsp_frames == NULL) return -EINVAL;
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
- uint64_t latency_frames =
- (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
- if (out->frames_rendered >= latency_frames) {
- *dsp_frames = (uint32_t)(out->frames_rendered - latency_frames);
- } else {
- *dsp_frames = 0;
- }
- return 0;
-}
-
-static int out_add_audio_effect(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR effect_handle_t effect) {
- FNLOG();
- return 0;
-}
-
-static int out_remove_audio_effect(
- UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR effect_handle_t effect) {
- FNLOG();
- return 0;
-}
-
-/*
- * AUDIO INPUT STREAM
- */
-
-static uint32_t in_get_sample_rate(const struct audio_stream* stream) {
- struct ha_stream_in* in = (struct ha_stream_in*)stream;
-
- FNLOG();
- return in->common.cfg.rate;
-}
-
-static int in_set_sample_rate(struct audio_stream* stream, uint32_t rate) {
- struct ha_stream_in* in = (struct ha_stream_in*)stream;
-
- FNLOG();
-
- if (in->common.cfg.rate > 0 && in->common.cfg.rate == rate)
- return 0;
- else
- return -1;
-}
-
-static size_t in_get_buffer_size(
- UNUSED_ATTR const struct audio_stream* stream) {
- FNLOG();
- return 320;
-}
-
-static audio_channel_mask_t in_get_channels(const struct audio_stream* stream) {
- struct ha_stream_in* in = (struct ha_stream_in*)stream;
-
- FNLOG();
- return (audio_channel_mask_t)in->common.cfg.channel_mask;
-}
-
-static audio_format_t in_get_format(
- UNUSED_ATTR const struct audio_stream* stream) {
- FNLOG();
- return AUDIO_FORMAT_PCM_16_BIT;
-}
-
-static int in_set_format(UNUSED_ATTR struct audio_stream* stream,
- UNUSED_ATTR audio_format_t format) {
- FNLOG();
- if (format == AUDIO_FORMAT_PCM_16_BIT)
- return 0;
- else
- return -1;
-}
-
-static int in_standby(UNUSED_ATTR struct audio_stream* stream) {
- FNLOG();
- return 0;
-}
-
-static int in_dump(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR int fd) {
- FNLOG();
- return 0;
-}
-
-static int in_set_parameters(UNUSED_ATTR struct audio_stream* stream,
- UNUSED_ATTR const char* kvpairs) {
- FNLOG();
- return 0;
-}
-
-static char* in_get_parameters(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR const char* keys) {
- FNLOG();
- return strdup("");
-}
-
-static int in_set_gain(UNUSED_ATTR struct audio_stream_in* stream,
- UNUSED_ATTR float gain) {
- FNLOG();
- return 0;
-}
-
-static ssize_t in_read(struct audio_stream_in* stream, void* buffer,
- size_t bytes) {
- struct ha_stream_in* in = (struct ha_stream_in*)stream;
- int read;
- int us_delay;
-
- DEBUG("read %zu bytes, state: %d", bytes, in->common.state);
-
- std::unique_lock<std::recursive_mutex> lock(*in->common.mutex);
- if (in->common.state == AUDIO_HA_STATE_SUSPENDED ||
- in->common.state == AUDIO_HA_STATE_STOPPING) {
- DEBUG("stream suspended");
- goto error;
- }
-
- /* only allow autostarting if we are in stopped or standby */
- if ((in->common.state == AUDIO_HA_STATE_STOPPED) ||
- (in->common.state == AUDIO_HA_STATE_STANDBY)) {
- if (start_audio_datapath(&in->common) < 0) {
- goto error;
- }
- } else if (in->common.state != AUDIO_HA_STATE_STARTED) {
- ERROR("stream not in stopped or standby");
- goto error;
- }
-
- lock.unlock();
- read = skt_read(in->common.audio_fd, buffer, bytes);
- lock.lock();
- if (read == -1) {
- skt_disconnect(in->common.audio_fd);
- in->common.audio_fd = AUDIO_SKT_DISCONNECTED;
- if ((in->common.state != AUDIO_HA_STATE_SUSPENDED) &&
- (in->common.state != AUDIO_HA_STATE_STOPPING)) {
- in->common.state = AUDIO_HA_STATE_STOPPED;
- } else {
- ERROR("read failed : stream suspended, avoid resetting state");
- }
- goto error;
- } else if (read == 0) {
- DEBUG("read time out - return zeros");
- memset(buffer, 0, bytes);
- read = bytes;
- }
- lock.unlock();
-
- DEBUG("read %d bytes out of %zu bytes", read, bytes);
- return read;
-
-error:
- memset(buffer, 0, bytes);
- us_delay = calc_audiotime_usec(in->common.cfg, bytes);
- DEBUG("emulate ha read delay (%d us)", us_delay);
-
- usleep(us_delay);
- return bytes;
-}
-
-static uint32_t in_get_input_frames_lost(
- UNUSED_ATTR struct audio_stream_in* stream) {
- FNLOG();
- return 0;
-}
-
-static int in_add_audio_effect(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR effect_handle_t effect) {
- FNLOG();
- return 0;
-}
-
-static int in_remove_audio_effect(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR effect_handle_t effect) {
- FNLOG();
-
- return 0;
-}
-
-static int adev_open_output_stream(struct audio_hw_device* dev,
- UNUSED_ATTR audio_io_handle_t handle,
- UNUSED_ATTR audio_devices_t devices,
- UNUSED_ATTR audio_output_flags_t flags,
- struct audio_config* config,
- struct audio_stream_out** stream_out,
- UNUSED_ATTR const char* address)
-
-{
- struct ha_audio_device* ha_dev = (struct ha_audio_device*)dev;
- struct ha_stream_out* out;
- int ret = 0;
-
- INFO("opening output");
- // protect against adev->output and stream_out from being inconsistent
- std::lock_guard<std::recursive_mutex> lock(*ha_dev->mutex);
- out = (struct ha_stream_out*)calloc(1, sizeof(struct ha_stream_out));
-
- if (!out) return -ENOMEM;
-
- out->stream.common.get_sample_rate = out_get_sample_rate;
- out->stream.common.set_sample_rate = out_set_sample_rate;
- out->stream.common.get_buffer_size = out_get_buffer_size;
- out->stream.common.get_channels = out_get_channels;
- out->stream.common.get_format = out_get_format;
- out->stream.common.set_format = out_set_format;
- out->stream.common.standby = out_standby;
- out->stream.common.dump = out_dump;
- out->stream.common.set_parameters = out_set_parameters;
- out->stream.common.get_parameters = out_get_parameters;
- out->stream.common.add_audio_effect = out_add_audio_effect;
- out->stream.common.remove_audio_effect = out_remove_audio_effect;
- out->stream.get_latency = out_get_latency;
- out->stream.set_volume = out_set_volume;
- out->stream.write = out_write;
- out->stream.get_render_position = out_get_render_position;
- out->stream.get_presentation_position = out_get_presentation_position;
-
- /* initialize ha specifics */
- ha_stream_common_init(&out->common);
-
- // Make sure we always have the feeding parameters configured
- btav_a2dp_codec_config_t codec_config;
- btav_a2dp_codec_config_t codec_capability;
- if (ha_read_output_audio_config(&out->common, &codec_config,
- &codec_capability,
- true /* update_stream_config */) < 0) {
- ERROR("ha_read_output_audio_config failed");
- ret = -1;
- goto err_open;
- }
- // ha_read_output_audio_config() opens the socket control path (or fails)
-
- /* set output config values */
- if (config != nullptr) {
- // Try to use the config parameters and send it to the remote side
- // TODO: Shall we use out_set_format() and similar?
- if (config->format != 0) out->common.cfg.format = config->format;
- if (config->sample_rate != 0) out->common.cfg.rate = config->sample_rate;
- if (config->channel_mask != 0)
- out->common.cfg.channel_mask = config->channel_mask;
- if ((out->common.cfg.format != 0) || (out->common.cfg.rate != 0) ||
- (out->common.cfg.channel_mask != 0)) {
- if (ha_write_output_audio_config(&out->common) < 0) {
- ERROR("ha_write_output_audio_config failed");
- ret = -1;
- goto err_open;
- }
- // Read again and make sure we use the same parameters as the remote side
- if (ha_read_output_audio_config(&out->common, &codec_config,
- &codec_capability,
- true /* update_stream_config */) < 0) {
- ERROR("ha_read_output_audio_config failed");
- ret = -1;
- goto err_open;
- }
- }
- config->format = out_get_format((const struct audio_stream*)&out->stream);
- config->sample_rate =
- out_get_sample_rate((const struct audio_stream*)&out->stream);
- config->channel_mask =
- out_get_channels((const struct audio_stream*)&out->stream);
-
- INFO(
- "Output stream config: format=0x%x sample_rate=%d channel_mask=0x%x "
- "buffer_sz=%zu",
- config->format, config->sample_rate, config->channel_mask,
- out->common.buffer_sz);
- }
- *stream_out = &out->stream;
- ha_dev->output = out;
-
- DEBUG("success");
- /* Delay to ensure Headset is in proper state when START is initiated from
- * DUT immediately after the connection due to ongoing music playback. */
- usleep(250000);
- return 0;
-
-err_open:
- ha_stream_common_destroy(&out->common);
- free(out);
- *stream_out = NULL;
- ha_dev->output = NULL;
- ERROR("failed");
- return ret;
-}
-
-static void adev_close_output_stream(struct audio_hw_device* dev,
- struct audio_stream_out* stream) {
- struct ha_audio_device* ha_dev = (struct ha_audio_device*)dev;
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- // prevent interference with adev_set_parameters.
- std::lock_guard<std::recursive_mutex> lock(*ha_dev->mutex);
- {
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
- const ha_state_t state = out->common.state;
- INFO("closing output (state %d)", (int)state);
- if ((state == AUDIO_HA_STATE_STARTED) ||
- (state == AUDIO_HA_STATE_STOPPING)) {
- stop_audio_datapath(&out->common);
- }
-
- skt_disconnect(out->common.ctrl_fd);
- out->common.ctrl_fd = AUDIO_SKT_DISCONNECTED;
- }
-
- ha_stream_common_destroy(&out->common);
- free(stream);
- ha_dev->output = NULL;
-
- DEBUG("done");
-}
-
-static int adev_set_parameters(struct audio_hw_device* dev,
- const char* kvpairs) {
- struct ha_audio_device* ha_dev = (struct ha_audio_device*)dev;
- int retval = 0;
-
- // prevent interference with adev_close_output_stream
- std::lock_guard<std::recursive_mutex> lock(*ha_dev->mutex);
- struct ha_stream_out* out = ha_dev->output;
-
- if (out == NULL) return retval;
-
- INFO("state %d", out->common.state);
-
- retval =
- out->stream.common.set_parameters((struct audio_stream*)out, kvpairs);
-
- return retval;
-}
-
-static char* adev_get_parameters(UNUSED_ATTR const struct audio_hw_device* dev,
- const char* keys) {
- FNLOG();
-
- std::unordered_map<std::string, std::string> params =
- hash_map_utils_new_from_string_params(keys);
- hash_map_utils_dump_string_keys_string_values(params);
-
- return strdup("");
-}
-
-static int adev_init_check(UNUSED_ATTR const struct audio_hw_device* dev) {
- FNLOG();
-
- return 0;
-}
-
-static int adev_set_voice_volume(UNUSED_ATTR struct audio_hw_device* dev,
- UNUSED_ATTR float volume) {
- FNLOG();
-
- return -ENOSYS;
-}
-
-static int adev_set_master_volume(UNUSED_ATTR struct audio_hw_device* dev,
- UNUSED_ATTR float volume) {
- FNLOG();
-
- return -ENOSYS;
-}
-
-static int adev_set_mode(UNUSED_ATTR struct audio_hw_device* dev,
- UNUSED_ATTR audio_mode_t mode) {
- FNLOG();
-
- return 0;
-}
-
-static int adev_set_mic_mute(UNUSED_ATTR struct audio_hw_device* dev,
- UNUSED_ATTR bool state) {
- FNLOG();
-
- return -ENOSYS;
-}
-
-static int adev_get_mic_mute(UNUSED_ATTR const struct audio_hw_device* dev,
- UNUSED_ATTR bool* state) {
- FNLOG();
-
- return -ENOSYS;
-}
-
-static size_t adev_get_input_buffer_size(
- UNUSED_ATTR const struct audio_hw_device* dev,
- UNUSED_ATTR const struct audio_config* config) {
- FNLOG();
-
- return 320;
-}
-
-static int adev_open_input_stream(struct audio_hw_device* dev,
- UNUSED_ATTR audio_io_handle_t handle,
- UNUSED_ATTR audio_devices_t devices,
- UNUSED_ATTR struct audio_config* config,
- struct audio_stream_in** stream_in,
- UNUSED_ATTR audio_input_flags_t flags,
- UNUSED_ATTR const char* address,
- UNUSED_ATTR audio_source_t source) {
- struct ha_audio_device* ha_dev = (struct ha_audio_device*)dev;
- struct ha_stream_in* in;
- int ret;
-
- FNLOG();
-
- // protect against adev->input and stream_in from being inconsistent
- std::lock_guard<std::recursive_mutex> lock(*ha_dev->mutex);
- in = (struct ha_stream_in*)calloc(1, sizeof(struct ha_stream_in));
-
- if (!in) return -ENOMEM;
-
- in->stream.common.get_sample_rate = in_get_sample_rate;
- in->stream.common.set_sample_rate = in_set_sample_rate;
- in->stream.common.get_buffer_size = in_get_buffer_size;
- in->stream.common.get_channels = in_get_channels;
- in->stream.common.get_format = in_get_format;
- in->stream.common.set_format = in_set_format;
- in->stream.common.standby = in_standby;
- in->stream.common.dump = in_dump;
- in->stream.common.set_parameters = in_set_parameters;
- in->stream.common.get_parameters = in_get_parameters;
- in->stream.common.add_audio_effect = in_add_audio_effect;
- in->stream.common.remove_audio_effect = in_remove_audio_effect;
- in->stream.set_gain = in_set_gain;
- in->stream.read = in_read;
- in->stream.get_input_frames_lost = in_get_input_frames_lost;
-
- /* initialize ha specifics */
- ha_stream_common_init(&in->common);
-
- *stream_in = &in->stream;
- ha_dev->input = in;
-
- if (ha_read_input_audio_config(&in->common) < 0) {
- ERROR("ha_read_input_audio_config failed (%s)", strerror(errno));
- ret = -1;
- goto err_open;
- }
- // ha_read_input_audio_config() opens socket control path (or fails)
-
- DEBUG("success");
- return 0;
-
-err_open:
- ha_stream_common_destroy(&in->common);
- free(in);
- *stream_in = NULL;
- ha_dev->input = NULL;
- ERROR("failed");
- return ret;
-}
-
-static void adev_close_input_stream(struct audio_hw_device* dev,
- struct audio_stream_in* stream) {
- struct ha_audio_device* ha_dev = (struct ha_audio_device*)dev;
- struct ha_stream_in* in = (struct ha_stream_in*)stream;
-
- std::lock_guard<std::recursive_mutex> lock(*ha_dev->mutex);
- {
- std::lock_guard<std::recursive_mutex> lock(*in->common.mutex);
- const ha_state_t state = in->common.state;
- INFO("closing input (state %d)", (int)state);
-
- if ((state == AUDIO_HA_STATE_STARTED) || (state == AUDIO_HA_STATE_STOPPING))
- stop_audio_datapath(&in->common);
-
- skt_disconnect(in->common.ctrl_fd);
- in->common.ctrl_fd = AUDIO_SKT_DISCONNECTED;
- }
- ha_stream_common_destroy(&in->common);
- free(stream);
- ha_dev->input = NULL;
-
- DEBUG("done");
-}
-
-static int adev_dump(UNUSED_ATTR const audio_hw_device_t* device,
- UNUSED_ATTR int fd) {
- FNLOG();
-
- return 0;
-}
-
-static int adev_close(hw_device_t* device) {
- struct ha_audio_device* ha_dev = (struct ha_audio_device*)device;
- FNLOG();
-
- delete ha_dev->mutex;
- ha_dev->mutex = nullptr;
- free(device);
- return 0;
-}
-
-static int adev_open(const hw_module_t* module, const char* name,
- hw_device_t** device) {
- struct ha_audio_device* adev;
-
- INFO(" adev_open in ha_hw module");
- FNLOG();
-
- if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) {
- ERROR("interface %s not matching [%s]", name, AUDIO_HARDWARE_INTERFACE);
- return -EINVAL;
- }
-
- adev = (struct ha_audio_device*)calloc(1, sizeof(struct ha_audio_device));
-
- if (!adev) return -ENOMEM;
-
- adev->mutex = new std::recursive_mutex;
-
- adev->device.common.tag = HARDWARE_DEVICE_TAG;
- adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
- adev->device.common.module = (struct hw_module_t*)module;
- adev->device.common.close = adev_close;
-
- adev->device.init_check = adev_init_check;
- adev->device.set_voice_volume = adev_set_voice_volume;
- adev->device.set_master_volume = adev_set_master_volume;
- adev->device.set_mode = adev_set_mode;
- adev->device.set_mic_mute = adev_set_mic_mute;
- adev->device.get_mic_mute = adev_get_mic_mute;
- adev->device.set_parameters = adev_set_parameters;
- adev->device.get_parameters = adev_get_parameters;
- adev->device.get_input_buffer_size = adev_get_input_buffer_size;
- adev->device.open_output_stream = adev_open_output_stream;
- adev->device.close_output_stream = adev_close_output_stream;
- adev->device.open_input_stream = adev_open_input_stream;
- adev->device.close_input_stream = adev_close_input_stream;
- adev->device.dump = adev_dump;
-
- adev->output = NULL;
-
- *device = &adev->device.common;
-
- return 0;
-}
-
-static struct hw_module_methods_t hal_module_methods = {
- .open = adev_open,
-};
-
-__attribute__((
- visibility("default"))) struct audio_module HAL_MODULE_INFO_SYM = {
- .common =
- {
- .tag = HARDWARE_MODULE_TAG,
- .version_major = 1,
- .version_minor = 0,
- .id = AUDIO_HARDWARE_MODULE_ID,
- .name = "Hearing Aid Audio HW HAL",
- .author = "The Android Open Source Project",
- .methods = &hal_module_methods,
- },
-};
diff --git a/audio_hearing_aid_hw/src/audio_hearing_aid_hw_utils.cc b/audio_hearing_aid_hw/src/audio_hearing_aid_hw_utils.cc
deleted file mode 100644
index cb1eee7..0000000
--- a/audio_hearing_aid_hw/src/audio_hearing_aid_hw_utils.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2018 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 "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h"
-
-#define CASE_RETURN_STR(const) \
- case const: \
- return #const;
-
-const char* audio_ha_hw_dump_ctrl_event(tHEARING_AID_CTRL_CMD event) {
- switch (event) {
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_NONE)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_CHECK_READY)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_START)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_STOP)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_SUSPEND)
- CASE_RETURN_STR(HEARING_AID_CTRL_GET_INPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(HEARING_AID_CTRL_GET_OUTPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_OFFLOAD_START)
- default:
- break;
- }
-
- return "UNKNOWN HEARING_AID_CTRL_CMD";
-}
diff --git a/audio_hearing_aid_hw/test/audio_hearing_aid_hw_test.cc b/audio_hearing_aid_hw/test/audio_hearing_aid_hw_test.cc
deleted file mode 100644
index c5d0e2b..0000000
--- a/audio_hearing_aid_hw/test/audio_hearing_aid_hw_test.cc
+++ /dev/null
@@ -1,146 +0,0 @@
-/******************************************************************************
- *
- * Copyright 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.
- *
- ******************************************************************************/
-
-#include <gtest/gtest.h>
-
-#include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h"
-
-namespace {
-static uint32_t codec_sample_rate2value(
- btav_a2dp_codec_sample_rate_t codec_sample_rate) {
- switch (codec_sample_rate) {
- case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
- return 44100;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
- return 48000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
- return 88200;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
- return 96000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
- return 176400;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
- return 192000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
- return 16000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
- return 24000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE:
- break;
- }
- return 0;
-}
-
-static uint32_t codec_bits_per_sample2value(
- btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample) {
- switch (codec_bits_per_sample) {
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
- return 16;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
- return 24;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
- return 32;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
- break;
- }
- return 0;
-}
-
-static uint32_t codec_channel_mode2value(
- btav_a2dp_codec_channel_mode_t codec_channel_mode) {
- switch (codec_channel_mode) {
- case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
- return 1;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
- return 2;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
- break;
- }
- return 0;
-}
-
-} // namespace
-
-class AudioA2dpHwTest : public ::testing::Test {
- protected:
- AudioA2dpHwTest() {}
-
- private:
-};
-
-TEST_F(AudioA2dpHwTest, test_compute_buffer_size) {
- const btav_a2dp_codec_sample_rate_t codec_sample_rate_array[] = {
- BTAV_A2DP_CODEC_SAMPLE_RATE_NONE, BTAV_A2DP_CODEC_SAMPLE_RATE_44100,
- BTAV_A2DP_CODEC_SAMPLE_RATE_48000, BTAV_A2DP_CODEC_SAMPLE_RATE_88200,
- BTAV_A2DP_CODEC_SAMPLE_RATE_96000, BTAV_A2DP_CODEC_SAMPLE_RATE_176400,
- BTAV_A2DP_CODEC_SAMPLE_RATE_192000};
-
- const btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample_array[] = {
- BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE, BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16,
- BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24, BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32};
-
- const btav_a2dp_codec_channel_mode_t codec_channel_mode_array[] = {
- BTAV_A2DP_CODEC_CHANNEL_MODE_NONE, BTAV_A2DP_CODEC_CHANNEL_MODE_MONO,
- BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO};
-
- for (const auto codec_sample_rate : codec_sample_rate_array) {
- for (const auto codec_bits_per_sample : codec_bits_per_sample_array) {
- for (const auto codec_channel_mode : codec_channel_mode_array) {
- size_t buffer_size = audio_ha_hw_stream_compute_buffer_size(
- codec_sample_rate, codec_bits_per_sample, codec_channel_mode);
-
- // Check for invalid input
- if ((codec_sample_rate == BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) ||
- (codec_bits_per_sample == BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) ||
- (codec_channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE)) {
- EXPECT_EQ(buffer_size,
- static_cast<size_t>(AUDIO_STREAM_OUTPUT_BUFFER_SZ));
- continue;
- }
-
- uint32_t sample_rate = codec_sample_rate2value(codec_sample_rate);
- EXPECT_TRUE(sample_rate != 0);
-
- uint32_t bits_per_sample =
- codec_bits_per_sample2value(codec_bits_per_sample);
- EXPECT_TRUE(bits_per_sample != 0);
-
- uint32_t number_of_channels =
- codec_channel_mode2value(codec_channel_mode);
- EXPECT_TRUE(number_of_channels != 0);
-
- const uint64_t time_period_ms = 20; // TODO: Must be a parameter
- size_t expected_buffer_size =
- (time_period_ms * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * sample_rate *
- number_of_channels * (bits_per_sample / 8)) /
- 1000;
-
- // Compute the divisor and adjust the buffer size
- const size_t divisor = (AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * 16 *
- number_of_channels * bits_per_sample) /
- 8;
- const size_t remainder = expected_buffer_size % divisor;
- if (remainder != 0) {
- expected_buffer_size += divisor - remainder;
- }
-
- EXPECT_EQ(buffer_size, expected_buffer_size);
- }
- }
- }
-}
diff --git a/binder/Android.bp b/binder/Android.bp
deleted file mode 100644
index c5d6f6b..0000000
--- a/binder/Android.bp
+++ /dev/null
@@ -1,53 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-// AIDL interface between libbluetooth-binder and framework.jar
-filegroup {
- name: "libbluetooth-binder-aidl",
- srcs: [
- "android/bluetooth/IBluetooth.aidl",
- "android/bluetooth/IBluetoothA2dp.aidl",
- "android/bluetooth/IBluetoothA2dpSink.aidl",
- "android/bluetooth/IBluetoothAvrcpController.aidl",
- "android/bluetooth/IBluetoothAvrcpTarget.aidl",
- "android/bluetooth/IBluetoothCallback.aidl",
- "android/bluetooth/IBluetoothCsipSetCoordinator.aidl",
- "android/bluetooth/IBluetoothCsipSetCoordinatorCallback.aidl",
- "android/bluetooth/IBluetoothCsipSetCoordinatorLockCallback.aidl",
- "android/bluetooth/IBluetoothProfileServiceConnection.aidl",
- "android/bluetooth/IBluetoothHeadset.aidl",
- "android/bluetooth/IBluetoothHearingAid.aidl",
- "android/bluetooth/IBluetoothVolumeControl.aidl",
- "android/bluetooth/IBluetoothHidHost.aidl",
- "android/bluetooth/IBluetoothLeAudio.aidl",
- "android/bluetooth/IBluetoothPan.aidl",
- "android/bluetooth/IBluetoothManager.aidl",
- "android/bluetooth/IBluetoothManagerCallback.aidl",
- "android/bluetooth/IBluetoothMap.aidl",
- "android/bluetooth/IBluetoothMapClient.aidl",
- "android/bluetooth/IBluetoothMcpServiceManager.aidl",
- "android/bluetooth/IBluetoothPbap.aidl",
- "android/bluetooth/IBluetoothPbapClient.aidl",
- "android/bluetooth/IBluetoothSap.aidl",
- "android/bluetooth/IBluetoothSocketManager.aidl",
- "android/bluetooth/IBluetoothStateChangeCallback.aidl",
- "android/bluetooth/IBluetoothHeadsetClient.aidl",
- "android/bluetooth/IBluetoothHidDevice.aidl",
- "android/bluetooth/IBluetoothHidDeviceCallback.aidl",
- "android/bluetooth/IBluetoothGatt.aidl",
- "android/bluetooth/IBluetoothGattCallback.aidl",
- "android/bluetooth/IBluetoothMetadataListener.aidl",
- "android/bluetooth/IBluetoothGattServerCallback.aidl",
- "android/bluetooth/IBluetoothOobDataCallback.aidl",
- "android/bluetooth/le/IAdvertisingSetCallback.aidl",
- "android/bluetooth/le/IPeriodicAdvertisingCallback.aidl",
- "android/bluetooth/le/IScannerCallback.aidl",
- "android/bluetooth/IBluetoothConnectionCallback.aidl",
- ],
-}
diff --git a/binder/android/bluetooth/BluetoothActivityEnergyInfo.aidl b/binder/android/bluetooth/BluetoothActivityEnergyInfo.aidl
deleted file mode 100644
index 1410019..0000000
--- a/binder/android/bluetooth/BluetoothActivityEnergyInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package android.bluetooth;
-
-parcelable BluetoothActivityEnergyInfo;
diff --git a/binder/android/bluetooth/BluetoothAudioConfig.aidl b/binder/android/bluetooth/BluetoothAudioConfig.aidl
deleted file mode 100644
index 2ef113d..0000000
--- a/binder/android/bluetooth/BluetoothAudioConfig.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2009 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.
- */
-
-package android.bluetooth;
-
-parcelable BluetoothAudioConfig;
diff --git a/binder/android/bluetooth/BluetoothAvrcpPlayerSettings.aidl b/binder/android/bluetooth/BluetoothAvrcpPlayerSettings.aidl
deleted file mode 100644
index 41b8af6..0000000
--- a/binder/android/bluetooth/BluetoothAvrcpPlayerSettings.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2015 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.
- */
-
-package android.bluetooth;
-
-parcelable BluetoothAvrcpPlayerSettings;
diff --git a/binder/android/bluetooth/BluetoothClass.aidl b/binder/android/bluetooth/BluetoothClass.aidl
deleted file mode 100644
index 8699b1e..0000000
--- a/binder/android/bluetooth/BluetoothClass.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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.
- */
-
-package android.bluetooth;
-
-parcelable BluetoothClass;
diff --git a/binder/android/bluetooth/BluetoothCodecConfig.aidl b/binder/android/bluetooth/BluetoothCodecConfig.aidl
deleted file mode 100644
index 5890637..0000000
--- a/binder/android/bluetooth/BluetoothCodecConfig.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth;
-
-parcelable BluetoothCodecConfig;
diff --git a/binder/android/bluetooth/BluetoothCodecStatus.aidl b/binder/android/bluetooth/BluetoothCodecStatus.aidl
deleted file mode 100644
index f674db7..0000000
--- a/binder/android/bluetooth/BluetoothCodecStatus.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth;
-
-parcelable BluetoothCodecStatus;
diff --git a/binder/android/bluetooth/BluetoothDevice.aidl b/binder/android/bluetooth/BluetoothDevice.aidl
deleted file mode 100644
index b9b0589..0000000
--- a/binder/android/bluetooth/BluetoothDevice.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2009 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.
- */
-
-package android.bluetooth;
-
-parcelable BluetoothDevice cpp_header "android/bluetooth/bluetooth_device.h";
diff --git a/binder/android/bluetooth/BluetoothGattCharacteristic.aidl b/binder/android/bluetooth/BluetoothGattCharacteristic.aidl
deleted file mode 100644
index 463b7a7..0000000
--- a/binder/android/bluetooth/BluetoothGattCharacteristic.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth;
-
-parcelable BluetoothGattCharacteristic;
diff --git a/binder/android/bluetooth/BluetoothGattDescriptor.aidl b/binder/android/bluetooth/BluetoothGattDescriptor.aidl
deleted file mode 100644
index 6d4cdeb..0000000
--- a/binder/android/bluetooth/BluetoothGattDescriptor.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth;
-
-parcelable BluetoothGattDescriptor;
diff --git a/binder/android/bluetooth/BluetoothGattIncludedService.aidl b/binder/android/bluetooth/BluetoothGattIncludedService.aidl
deleted file mode 100644
index d911973..0000000
--- a/binder/android/bluetooth/BluetoothGattIncludedService.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth;
-
-parcelable BluetoothGattIncludedService;
diff --git a/binder/android/bluetooth/BluetoothGattService.aidl b/binder/android/bluetooth/BluetoothGattService.aidl
deleted file mode 100644
index 8e72ba9..0000000
--- a/binder/android/bluetooth/BluetoothGattService.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth;
-
-parcelable BluetoothGattService;
diff --git a/binder/android/bluetooth/BluetoothHeadsetClientCall.aidl b/binder/android/bluetooth/BluetoothHeadsetClientCall.aidl
deleted file mode 100644
index 5403d51..0000000
--- a/binder/android/bluetooth/BluetoothHeadsetClientCall.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-package android.bluetooth;
-
-parcelable BluetoothHeadsetClientCall;
diff --git a/binder/android/bluetooth/BluetoothHidDeviceAppQosSettings.aidl b/binder/android/bluetooth/BluetoothHidDeviceAppQosSettings.aidl
deleted file mode 100644
index 14f9114..0000000
--- a/binder/android/bluetooth/BluetoothHidDeviceAppQosSettings.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-** Copyright 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.
-*/
-
-package android.bluetooth;
-
-parcelable BluetoothHidDeviceAppQosSettings;
diff --git a/binder/android/bluetooth/BluetoothHidDeviceAppSdpSettings.aidl b/binder/android/bluetooth/BluetoothHidDeviceAppSdpSettings.aidl
deleted file mode 100644
index 87dd10e..0000000
--- a/binder/android/bluetooth/BluetoothHidDeviceAppSdpSettings.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-** Copyright 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.
-*/
-
-package android.bluetooth;
-
-parcelable BluetoothHidDeviceAppSdpSettings;
diff --git a/binder/android/bluetooth/BufferConstraints.aidl b/binder/android/bluetooth/BufferConstraints.aidl
deleted file mode 100644
index 751f5ac..0000000
--- a/binder/android/bluetooth/BufferConstraints.aidl
+++ /dev/null
@@ -1,3 +0,0 @@
-package android.bluetooth;
-
-parcelable BufferConstraints;
diff --git a/binder/android/bluetooth/IBluetooth.aidl b/binder/android/bluetooth/IBluetooth.aidl
deleted file mode 100644
index 3e78f5b..0000000
--- a/binder/android/bluetooth/IBluetooth.aidl
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright 2008, 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.IBluetoothCallback;
-import android.bluetooth.IBluetoothConnectionCallback;
-import android.bluetooth.IBluetoothMetadataListener;
-import android.bluetooth.IBluetoothOobDataCallback;
-import android.bluetooth.IBluetoothSocketManager;
-import android.bluetooth.IBluetoothStateChangeCallback;
-import android.bluetooth.BluetoothActivityEnergyInfo;
-import android.bluetooth.BluetoothClass;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.OobData;
-import android.content.AttributionSource;
-import android.os.ParcelUuid;
-import android.os.ParcelFileDescriptor;
-import android.os.ResultReceiver;
-
-/**
- * System private API for talking with the Bluetooth service.
- *
- * {@hide}
- */
-interface IBluetooth
-{
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- int getState();
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean enable(boolean quietMode, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disable(in AttributionSource attributionSource);
-
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.LOCAL_MAC_ADDRESS})")
- String getAddress();
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.LOCAL_MAC_ADDRESS})")
- String getAddressWithAttribution(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- ParcelUuid[] getUuids(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean setName(in String name, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- String getName(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)")
- int getNameLengthForAdvertise(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- BluetoothClass getBluetoothClass(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setBluetoothClass(in BluetoothClass bluetoothClass, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getIoCapability(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setIoCapability(int capability, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getLeIoCapability(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setLeIoCapability(int capability, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- int getScanMode(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- boolean setScanMode(int mode, int duration, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- int getDiscoverableTimeout(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- boolean setDiscoverableTimeout(int timeout, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- boolean startDiscovery(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- boolean cancelDiscovery(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- boolean isDiscovering(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- long getDiscoveryEndMillis(in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- int getAdapterConnectionState();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- int getProfileConnectionState(int profile);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- BluetoothDevice[] getBondedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean createBond(in BluetoothDevice device, in int transport, in OobData p192Data, in OobData p256Data, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean cancelBondProcess(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean removeBond(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getBondState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean isBondingInitiatedLocally(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- long getSupportedProfiles();
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionStateWithAttribution(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- String getRemoteName(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getRemoteType(in BluetoothDevice device, in AttributionSource attributionSource);
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- String getRemoteAlias(in BluetoothDevice device);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- String getRemoteAliasWithAttribution(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int setRemoteAlias(in BluetoothDevice device, in String name, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getRemoteClass(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- ParcelUuid[] getRemoteUuids(in BluetoothDevice device, in AttributionSource attributionSource);
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean fetchRemoteUuids(in BluetoothDevice device);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean fetchRemoteUuidsWithAttribution(in BluetoothDevice device, in int transport, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean sdpSearch(in BluetoothDevice device, in ParcelUuid uuid, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getBatteryLevel(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getMaxConnectedAudioDevices(in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean setPin(in BluetoothDevice device, boolean accept, int len, in byte[] pinCode, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean setPasskey(in BluetoothDevice device, boolean accept, int len, in byte[] passkey, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setPairingConfirmation(in BluetoothDevice device, boolean accept, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getPhonebookAccessPermission(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setSilenceMode(in BluetoothDevice device, boolean silence, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean getSilenceMode(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setPhonebookAccessPermission(in BluetoothDevice device, int value, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getMessageAccessPermission(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setMessageAccessPermission(in BluetoothDevice device, int value, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getSimAccessPermission(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setSimAccessPermission(in BluetoothDevice device, int value, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void registerCallback(in IBluetoothCallback callback, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void unregisterCallback(in IBluetoothCallback callback, in AttributionSource attributionSource);
-
- // For Socket
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- IBluetoothSocketManager getSocketManager();
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean factoryReset(in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isMultiAdvertisementSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isOffloadedFilteringSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isOffloadedScanBatchingSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isActivityAndEnergyReportingSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isLe2MPhySupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isLeCodedPhySupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isLeExtendedAdvertisingSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isLePeriodicAdvertisingSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- int isCisCentralSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- int isLePeriodicAdvertisingSyncTransferSenderSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- int getLeMaximumAdvertisingDataLength();
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- BluetoothActivityEnergyInfo reportActivityInfo(in AttributionSource attributionSource);
-
- // For Metadata
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean registerMetadataListener(in IBluetoothMetadataListener listener, in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean unregisterMetadataListener(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setMetadata(in BluetoothDevice device, in int key, in byte[] value, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- byte[] getMetadata(in BluetoothDevice device, in int key, in AttributionSource attributionSource);
-
- /**
- * Requests the controller activity info asynchronously.
- * The implementor is expected to reply with the
- * {@link android.bluetooth.BluetoothActivityEnergyInfo} object placed into the Bundle with the
- * key {@link android.os.BatteryStats#RESULT_RECEIVER_CONTROLLER_KEY}.
- * The result code is ignored.
- */
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- oneway void requestActivityInfo(in ResultReceiver result, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void onLeServiceUp(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void onBrEdrDown(in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED,android.Manifest.permission.MODIFY_PHONE_STATE})")
- int connectAllEnabledProfiles(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- int disconnectAllEnabledProfiles(in BluetoothDevice device, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED,android.Manifest.permission.MODIFY_PHONE_STATE})")
- boolean setActiveDevice(in BluetoothDevice device, in int profiles, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)")
- List<BluetoothDevice> getActiveDevices(in int profile, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getMostRecentlyConnectedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED,android.Manifest.permission.MODIFY_PHONE_STATE})")
- boolean removeActiveDevice(in int profiles, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean registerBluetoothConnectionCallback(in IBluetoothConnectionCallback callback, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean unregisterBluetoothConnectionCallback(in IBluetoothConnectionCallback callback, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean canBondWithoutDialog(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void generateLocalOobData(in int transport, IBluetoothOobDataCallback callback, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothA2dp.aidl b/binder/android/bluetooth/IBluetoothA2dp.aidl
deleted file mode 100644
index 94379af..0000000
--- a/binder/android/bluetooth/IBluetoothA2dp.aidl
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2008 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothCodecConfig;
-import android.bluetooth.BluetoothCodecStatus;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BufferConstraints;
-import android.content.AttributionSource;
-
-/**
- * APIs for Bluetooth A2DP service
- *
- * @hide
- */
-interface IBluetoothA2dp {
- // Public API
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean connect(in BluetoothDevice device);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean connectWithAttribution(in BluetoothDevice device, in AttributionSource attributionSource);
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disconnect(in BluetoothDevice device);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disconnectWithAttribution(in BluetoothDevice device, in AttributionSource attributionSource);
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevices();
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevicesWithAttribution(in AttributionSource attributionSource);
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStatesWithAttribution(in int[] states, in AttributionSource attributionSource);
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionStateWithAttribution(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean setActiveDevice(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- BluetoothDevice getActiveDevice(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- int getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isAvrcpAbsoluteVolumeSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- oneway void setAvrcpAbsoluteVolume(int volume, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean isA2dpPlaying(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- BluetoothCodecStatus getCodecStatus(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- oneway void setCodecConfigPreference(in BluetoothDevice device, in BluetoothCodecConfig codecConfig, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- oneway void enableOptionalCodecs(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- oneway void disableOptionalCodecs(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int supportsOptionalCodecs(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getOptionalCodecsEnabled(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- oneway void setOptionalCodecsEnabled(in BluetoothDevice device, int value, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- int getDynamicBufferSupport(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- BufferConstraints getBufferConstraints(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setBufferLengthMillis(int codec, int size, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getPriority(in BluetoothDevice device, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothA2dpSink.aidl b/binder/android/bluetooth/IBluetoothA2dpSink.aidl
deleted file mode 100644
index 53c1216..0000000
--- a/binder/android/bluetooth/IBluetoothA2dpSink.aidl
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothAudioConfig;
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-
-/**
- * APIs for Bluetooth A2DP sink service
- *
- * @hide
- */
-interface IBluetoothA2dpSink {
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean connect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disconnect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- BluetoothAudioConfig getAudioConfig(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- int getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean isA2dpPlaying(in BluetoothDevice device, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothAvrcpController.aidl b/binder/android/bluetooth/IBluetoothAvrcpController.aidl
deleted file mode 100644
index 058ffcb..0000000
--- a/binder/android/bluetooth/IBluetoothAvrcpController.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothAvrcpPlayerSettings;
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-import android.media.MediaMetadata;
-import android.media.session.PlaybackState;
-
-/**
- * APIs for Bluetooth AVRCP controller service
- *
- * @hide
- */
-interface IBluetoothAvrcpController {
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- BluetoothAvrcpPlayerSettings getPlayerSettings(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean setPlayerApplicationSetting(in BluetoothAvrcpPlayerSettings plAppSetting, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void sendGroupNavigationCmd(in BluetoothDevice device, int keyCode, int keyState, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothAvrcpTarget.aidl b/binder/android/bluetooth/IBluetoothAvrcpTarget.aidl
deleted file mode 100644
index 64fbb7c..0000000
--- a/binder/android/bluetooth/IBluetoothAvrcpTarget.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-package android.bluetooth;
-
-/**
- * API for Bluetooth AVRCP Target Interface
- *
- * @hide
- */
-interface IBluetoothAvrcpTarget {
- /**
- * @hide
- */
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void sendVolumeChanged(in int volume);
-}
diff --git a/binder/android/bluetooth/IBluetoothCallback.aidl b/binder/android/bluetooth/IBluetoothCallback.aidl
deleted file mode 100644
index 3c0680f..0000000
--- a/binder/android/bluetooth/IBluetoothCallback.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2009, 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.
- */
-
-package android.bluetooth;
-
-/**
- * System private API for Bluetooth service callbacks.
- *
- * {@hide}
- */
-interface IBluetoothCallback
-{
- //void onRfcommChannelFound(int channel);
- void onBluetoothStateChange(int prevState, int newState);
-}
diff --git a/binder/android/bluetooth/IBluetoothConnectionCallback.aidl b/binder/android/bluetooth/IBluetoothConnectionCallback.aidl
deleted file mode 100644
index 56de49c..0000000
--- a/binder/android/bluetooth/IBluetoothConnectionCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 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.
- */
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-
-/**
- * Callback definitions for identifying when an ACL connection or disconnection happens
- * @hide
- */
-oneway interface IBluetoothConnectionCallback {
- void onDeviceConnected(in BluetoothDevice device);
- void onDeviceDisconnected(in BluetoothDevice device, in int hciReason);
-}
diff --git a/binder/android/bluetooth/IBluetoothCsipSetCoordinator.aidl b/binder/android/bluetooth/IBluetoothCsipSetCoordinator.aidl
deleted file mode 100644
index 4c451cd..0000000
--- a/binder/android/bluetooth/IBluetoothCsipSetCoordinator.aidl
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-import android.os.ParcelUuid;
-import android.bluetooth.IBluetoothCsipSetCoordinatorLockCallback;
-import java.util.List;
-import java.util.Map;
-
-/**
- * APIs for Bluetooth CSIP Set Coordinator
- *
- * @hide
- */
-interface IBluetoothCsipSetCoordinator {
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)")
- boolean connect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)")
- boolean disconnect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)")
- boolean setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)")
- int getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource);
-
- /**
- * Get the list of group identifiers for the given context {@var uuid}.
- * @return group identifiers as <code>List<Integer></code>
- */
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List getAllGroupIds(in ParcelUuid uuid, in AttributionSource attributionSource);
-
- /**
- * Get all groups that {@var device} belongs to.
- * @return group identifiers and their context uuids as <code>Map<Integer, ParcelUuid></code>
- */
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- Map getGroupUuidMapByDevice(in BluetoothDevice device, in AttributionSource attributionSource);
-
- /**
- * Get the number of known group members or
- * {@link android.bluetooth.IBluetoothCsipSetCoordinator.CSIS_GROUP_SIZE_UNKNOWN} if unknown.
- * @return group size
- */
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getDesiredGroupSize(in int group_id, in AttributionSource attributionSource);
-
- /**
- * Lock group identified with {@var groupId}.
- * @return unique lock identifier required for unlocking
- */
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- ParcelUuid groupLock(int groupId, in IBluetoothCsipSetCoordinatorLockCallback callback, in AttributionSource attributionSource);
-
- /**
- * Unlock group using {@var lockUuid} acquired through
- * {@link android.bluetooth.IBluetoothCsipSetCoordinator.groupLock}.
- */
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void groupUnlock(in ParcelUuid lockUuid, in AttributionSource attributionSource);
-
- const int CSIS_GROUP_ID_INVALID = -1;
- const int CSIS_GROUP_SIZE_UNKNOWN = 1;
-}
diff --git a/binder/android/bluetooth/IBluetoothCsipSetCoordinatorCallback.aidl b/binder/android/bluetooth/IBluetoothCsipSetCoordinatorCallback.aidl
deleted file mode 100644
index 3be11cb..0000000
--- a/binder/android/bluetooth/IBluetoothCsipSetCoordinatorCallback.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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.
- */
-
-package android.bluetooth;
-import android.bluetooth.BluetoothDevice;
-
-/**
- * Callback definitions for interacting with CSIP Set Coordinator
- *
- * @hide
- */
-oneway interface IBluetoothCsipSetCoordinatorCallback {
- void onCsisSetMemberAvailable(in BluetoothDevice device, in int groupId);
-}
diff --git a/binder/android/bluetooth/IBluetoothCsipSetCoordinatorLockCallback.aidl b/binder/android/bluetooth/IBluetoothCsipSetCoordinatorLockCallback.aidl
deleted file mode 100644
index 82ba371..0000000
--- a/binder/android/bluetooth/IBluetoothCsipSetCoordinatorLockCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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.
- */
-
-package android.bluetooth;
-
-/**
- * Callback definitions for interacting with CSIP Set Coordinator group locking method
- *
- * @hide
- */
-oneway interface IBluetoothCsipSetCoordinatorLockCallback {
- void onGroupLockSet(in int groupId, in int opStatus, in boolean isLocked);
-}
diff --git a/binder/android/bluetooth/IBluetoothGatt.aidl b/binder/android/bluetooth/IBluetoothGatt.aidl
deleted file mode 100644
index 9b69398..0000000
--- a/binder/android/bluetooth/IBluetoothGatt.aidl
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2013 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.
- */
-
-package android.bluetooth;
-
-import android.app.PendingIntent;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothGattService;
-import android.bluetooth.le.AdvertiseSettings;
-import android.bluetooth.le.AdvertiseData;
-import android.bluetooth.le.AdvertisingSetParameters;
-import android.bluetooth.le.PeriodicAdvertisingParameters;
-import android.bluetooth.le.ScanFilter;
-import android.bluetooth.le.ScanResult;
-import android.bluetooth.le.ScanSettings;
-import android.bluetooth.le.ResultStorageDescriptor;
-import android.content.AttributionSource;
-import android.os.ParcelUuid;
-import android.os.WorkSource;
-
-import android.bluetooth.IBluetoothGattCallback;
-import android.bluetooth.IBluetoothGattServerCallback;
-import android.bluetooth.le.IAdvertisingSetCallback;
-import android.bluetooth.le.IPeriodicAdvertisingCallback;
-import android.bluetooth.le.IScannerCallback;
-
-/**
- * API for interacting with BLE / GATT
- * @hide
- */
-interface IBluetoothGatt {
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- void registerScanner(in IScannerCallback callback, in WorkSource workSource, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- void unregisterScanner(in int scannerId, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- void startScan(in int scannerId, in ScanSettings settings, in List<ScanFilter> filters,
- in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- void startScanForIntent(in PendingIntent intent, in ScanSettings settings, in List<ScanFilter> filters,
- in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- void stopScanForIntent(in PendingIntent intent, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- void stopScan(in int scannerId, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- void flushPendingBatchResults(in int scannerId, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)")
- void startAdvertisingSet(in AdvertisingSetParameters parameters, in AdvertiseData advertiseData,
- in AdvertiseData scanResponse, in PeriodicAdvertisingParameters periodicParameters,
- in AdvertiseData periodicData, in int duration, in int maxExtAdvEvents,
- in IAdvertisingSetCallback callback, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)")
- void stopAdvertisingSet(in IAdvertisingSetCallback callback, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_ADVERTISE,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void getOwnAddress(in int advertiserId, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)")
- void enableAdvertisingSet(in int advertiserId, in boolean enable, in int duration, in int maxExtAdvEvents, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)")
- void setAdvertisingData(in int advertiserId, in AdvertiseData data, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)")
- void setScanResponseData(in int advertiserId, in AdvertiseData data, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)")
- void setAdvertisingParameters(in int advertiserId, in AdvertisingSetParameters parameters, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)")
- void setPeriodicAdvertisingParameters(in int advertiserId, in PeriodicAdvertisingParameters parameters, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)")
- void setPeriodicAdvertisingData(in int advertiserId, in AdvertiseData data, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)")
- void setPeriodicAdvertisingEnable(in int advertiserId, in boolean enable, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- void registerSync(in ScanResult scanResult, in int skip, in int timeout, in IPeriodicAdvertisingCallback callback, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- void unregisterSync(in IPeriodicAdvertisingCallback callback, in AttributionSource attributionSource);
-
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void registerClient(in ParcelUuid appId, in IBluetoothGattCallback callback, boolean eatt_support, in AttributionSource attributionSource);
-
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void unregisterClient(in int clientIf, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void clientConnect(in int clientIf, in String address, in boolean isDirect, in int transport, in boolean opportunistic, in int phy, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void clientDisconnect(in int clientIf, in String address, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void clientSetPreferredPhy(in int clientIf, in String address, in int txPhy, in int rxPhy, in int phyOptions, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void clientReadPhy(in int clientIf, in String addres, in AttributionSource attributionSources);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void refreshDevice(in int clientIf, in String address, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void discoverServices(in int clientIf, in String address, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void discoverServiceByUuid(in int clientIf, in String address, in ParcelUuid uuid, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void readCharacteristic(in int clientIf, in String address, in int handle, in int authReq, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void readUsingCharacteristicUuid(in int clientIf, in String address, in ParcelUuid uuid,
- in int startHandle, in int endHandle, in int authReq, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int writeCharacteristic(in int clientIf, in String address, in int handle,
- in int writeType, in int authReq, in byte[] value, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void readDescriptor(in int clientIf, in String address, in int handle, in int authReq, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int writeDescriptor(in int clientIf, in String address, in int handle,
- in int authReq, in byte[] value, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void registerForNotification(in int clientIf, in String address, in int handle, in boolean enable, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void beginReliableWrite(in int clientIf, in String address, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void endReliableWrite(in int clientIf, in String address, in boolean execute, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void readRemoteRssi(in int clientIf, in String address, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void configureMTU(in int clientIf, in String address, in int mtu, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void connectionParameterUpdate(in int clientIf, in String address, in int connectionPriority, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void leConnectionUpdate(int clientIf, String address, int minInterval,
- int maxInterval, int peripheralLatency, int supervisionTimeout,
- int minConnectionEventLen, int maxConnectionEventLen, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void registerServer(in ParcelUuid appId, in IBluetoothGattServerCallback callback, boolean eatt_support, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void unregisterServer(in int serverIf, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void serverConnect(in int serverIf, in String address, in boolean isDirect, in int transport, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void serverDisconnect(in int serverIf, in String address, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void serverSetPreferredPhy(in int clientIf, in String address, in int txPhy, in int rxPhy, in int phyOptions, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void serverReadPhy(in int clientIf, in String address, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void addService(in int serverIf, in BluetoothGattService service, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void removeService(in int serverIf, in int handle, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void clearServices(in int serverIf, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void sendResponse(in int serverIf, in String address, in int requestId,
- in int status, in int offset, in byte[] value, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void sendNotification(in int serverIf, in String address, in int handle,
- in boolean confirm, in byte[] value, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void disconnectAll(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void unregAll(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int numHwTrackFiltersAvailable(in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothGattCallback.aidl b/binder/android/bluetooth/IBluetoothGattCallback.aidl
deleted file mode 100644
index a140ea9..0000000
--- a/binder/android/bluetooth/IBluetoothGattCallback.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2013 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.
- */
-package android.bluetooth;
-
-import android.os.ParcelUuid;
-import android.bluetooth.BluetoothGattService;
-
-/**
- * Callback definitions for interacting with BLE / GATT
- * @hide
- */
-oneway interface IBluetoothGattCallback {
- void onClientRegistered(in int status, in int clientIf);
- void onClientConnectionState(in int status, in int clientIf,
- in boolean connected, in String address);
- void onPhyUpdate(in String address, in int txPhy, in int rxPhy, in int status);
- void onPhyRead(in String address, in int txPhy, in int rxPhy, in int status);
- void onSearchComplete(in String address, in List<BluetoothGattService> services, in int status);
- void onCharacteristicRead(in String address, in int status, in int handle, in byte[] value);
- void onCharacteristicWrite(in String address, in int status, in int handle, in byte[] value);
- void onExecuteWrite(in String address, in int status);
- void onDescriptorRead(in String address, in int status, in int handle, in byte[] value);
- void onDescriptorWrite(in String address, in int status, in int handle, in byte[] value);
- void onNotify(in String address, in int handle, in byte[] value);
- void onReadRemoteRssi(in String address, in int rssi, in int status);
- void onConfigureMTU(in String address, in int mtu, in int status);
- void onConnectionUpdated(in String address, in int interval, in int latency,
- in int timeout, in int status);
- void onServiceChanged(in String address);
-}
diff --git a/binder/android/bluetooth/IBluetoothGattServerCallback.aidl b/binder/android/bluetooth/IBluetoothGattServerCallback.aidl
deleted file mode 100644
index 3f0ee20..0000000
--- a/binder/android/bluetooth/IBluetoothGattServerCallback.aidl
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 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.
- */
-package android.bluetooth;
-
-import android.bluetooth.BluetoothGattService;
-
-/**
- * Callback definitions for interacting with BLE / GATT
- * @hide
- */
-oneway interface IBluetoothGattServerCallback {
- void onServerRegistered(in int status, in int serverIf);
- void onServerConnectionState(in int status, in int serverIf,
- in boolean connected, in String address);
- void onServiceAdded(in int status, in BluetoothGattService service);
- void onCharacteristicReadRequest(in String address, in int transId, in int offset,
- in boolean isLong, in int handle);
- void onDescriptorReadRequest(in String address, in int transId,
- in int offset, in boolean isLong,
- in int handle);
- void onCharacteristicWriteRequest(in String address, in int transId, in int offset,
- in int length, in boolean isPrep, in boolean needRsp,
- in int handle, in byte[] value);
- void onDescriptorWriteRequest(in String address, in int transId, in int offset,
- in int length, in boolean isPrep, in boolean needRsp,
- in int handle, in byte[] value);
- void onExecuteWrite(in String address, in int transId, in boolean execWrite);
- void onNotificationSent(in String address, in int status);
- void onMtuChanged(in String address, in int mtu);
- void onPhyUpdate(in String address, in int txPhy, in int rxPhy, in int status);
- void onPhyRead(in String address, in int txPhy, in int rxPhy, in int status);
- void onConnectionUpdated(in String address, in int interval, in int latency,
- in int timeout, in int status);
-}
diff --git a/binder/android/bluetooth/IBluetoothHeadset.aidl b/binder/android/bluetooth/IBluetoothHeadset.aidl
deleted file mode 100644
index e94ce5a..0000000
--- a/binder/android/bluetooth/IBluetoothHeadset.aidl
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2008 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-
-/**
- * API for Bluetooth Headset service
- *
- * Note before adding anything new:
- * Internal interactions within com.android.bluetooth should be handled through
- * HeadsetService directly instead of going through binder
- *
- * {@hide}
- */
-interface IBluetoothHeadset {
- // Public API
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevices();
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevicesWithAttribution(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionStateWithAttribution(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.MODIFY_PHONE_STATE})")
- boolean startVoiceRecognition(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean stopVoiceRecognition(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean isAudioConnected(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean sendVendorSpecificResultCode(in BluetoothDevice device, in String command, in String arg, in AttributionSource attributionSource);
-
- // Hidden API
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.MODIFY_PHONE_STATE})")
- boolean connect(in BluetoothDevice device);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.MODIFY_PHONE_STATE})")
- boolean connectWithAttribution(in BluetoothDevice device, in AttributionSource attributionSource);
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disconnect(in BluetoothDevice device);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disconnectWithAttribution(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED,android.Manifest.permission.MODIFY_PHONE_STATE})")
- boolean setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- int getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getAudioState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean isAudioOn(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean connectAudio(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disconnectAudio(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void setAudioRouteAllowed(boolean allowed, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean getAudioRouteAllowed(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void setForceScoAudio(boolean forced, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.MODIFY_PHONE_STATE})")
- boolean startScoUsingVirtualVoiceCall(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.MODIFY_PHONE_STATE})")
- boolean stopScoUsingVirtualVoiceCall(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.MODIFY_PHONE_STATE})")
- oneway void phoneStateChanged(int numActive, int numHeld, int callState, String number, int type, String name, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.MODIFY_PHONE_STATE})")
- void clccResponse(int index, int direction, int status, int mode, boolean mpty, String number, int type, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.MODIFY_PHONE_STATE})")
- boolean setActiveDevice(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- BluetoothDevice getActiveDevice(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean isInbandRingingEnabled(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.MODIFY_PHONE_STATE})")
- boolean setPriority(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getPriority(in BluetoothDevice device, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean isNoiseReductionSupported(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean isVoiceRecognitionSupported(in BluetoothDevice device, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothHeadsetClient.aidl b/binder/android/bluetooth/IBluetoothHeadsetClient.aidl
deleted file mode 100644
index b223590..0000000
--- a/binder/android/bluetooth/IBluetoothHeadsetClient.aidl
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHeadsetClientCall;
-import android.content.AttributionSource;
-import android.os.Bundle;
-
-/**
- * API for Bluetooth Headset Client service (HFP HF Role)
- *
- * {@hide}
- */
-interface IBluetoothHeadsetClient {
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean connect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disconnect(in BluetoothDevice device, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean startVoiceRecognition(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean stopVoiceRecognition(in BluetoothDevice device, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothHeadsetClientCall> getCurrentCalls(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- Bundle getCurrentAgEvents(in BluetoothDevice device, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean acceptCall(in BluetoothDevice device, int flag, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean holdCall(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean rejectCall(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean terminateCall(in BluetoothDevice device, in BluetoothHeadsetClientCall call, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean enterPrivateMode(in BluetoothDevice device, int index, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean explicitCallTransfer(in BluetoothDevice device, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- BluetoothHeadsetClientCall dial(in BluetoothDevice device, String number, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean sendDTMF(in BluetoothDevice device, byte code, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean getLastVoiceTagNumber(in BluetoothDevice device, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getAudioState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean connectAudio(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disconnectAudio(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void setAudioRouteAllowed(in BluetoothDevice device, boolean allowed, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean getAudioRouteAllowed(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean sendVendorAtCommand(in BluetoothDevice device, int vendorId, String atCommand, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- Bundle getCurrentAgFeatures(in BluetoothDevice device, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothHearingAid.aidl b/binder/android/bluetooth/IBluetoothHearingAid.aidl
deleted file mode 100644
index 211e3ee..0000000
--- a/binder/android/bluetooth/IBluetoothHearingAid.aidl
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-
-/**
- * APIs for Bluetooth Hearing Aid service
- *
- * @hide
- */
-interface IBluetoothHearingAid {
- // Public API
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean connect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean disconnect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean setActiveDevice(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getActiveDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- int getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void setVolume(int volume, in AttributionSource attributionSource);
-
- const int HI_SYNC_ID_INVALID = 0;
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- long getHiSyncId(in BluetoothDevice device, in AttributionSource attributionSource);
-
- const int SIDE_LEFT = 0;
- const int SIDE_RIGHT = 1;
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getDeviceSide(in BluetoothDevice device, in AttributionSource attributionSource);
-
- const int MODE_MONAURAL = 0;
- const int MODE_BINAURAL = 1;
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getDeviceMode(in BluetoothDevice device, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothHidDevice.aidl b/binder/android/bluetooth/IBluetoothHidDevice.aidl
deleted file mode 100644
index c53d1e6..0000000
--- a/binder/android/bluetooth/IBluetoothHidDevice.aidl
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.IBluetoothHidDeviceCallback;
-import android.bluetooth.BluetoothHidDeviceAppSdpSettings;
-import android.bluetooth.BluetoothHidDeviceAppQosSettings;
-import android.content.AttributionSource;
-
-/** @hide */
-interface IBluetoothHidDevice {
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean registerApp(in BluetoothHidDeviceAppSdpSettings sdp, in BluetoothHidDeviceAppQosSettings inQos, in BluetoothHidDeviceAppQosSettings outQos, in IBluetoothHidDeviceCallback callback, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean unregisterApp(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean sendReport(in BluetoothDevice device, in int id, in byte[] data, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean replyReport(in BluetoothDevice device, in byte type, in byte id, in byte[] data, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean reportError(in BluetoothDevice device, byte error, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean unplug(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean connect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disconnect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- String getUserAppName(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothHidDeviceCallback.aidl b/binder/android/bluetooth/IBluetoothHidDeviceCallback.aidl
deleted file mode 100644
index 8205c67..0000000
--- a/binder/android/bluetooth/IBluetoothHidDeviceCallback.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-
-/** @hide */
-interface IBluetoothHidDeviceCallback {
- void onAppStatusChanged(in BluetoothDevice device, boolean registered);
- void onConnectionStateChanged(in BluetoothDevice device, in int state);
- void onGetReport(in BluetoothDevice device, in byte type, in byte id, in int bufferSize);
- void onSetReport(in BluetoothDevice device, in byte type, in byte id, in byte[] data);
- void onSetProtocol(in BluetoothDevice device, in byte protocol);
- void onInterruptData(in BluetoothDevice device, in byte reportId, in byte[] data);
- void onVirtualCableUnplug(in BluetoothDevice device);
-}
diff --git a/binder/android/bluetooth/IBluetoothHidHost.aidl b/binder/android/bluetooth/IBluetoothHidHost.aidl
deleted file mode 100644
index 23fbd60..0000000
--- a/binder/android/bluetooth/IBluetoothHidHost.aidl
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2012 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-
-/**
- * API for Bluetooth HID service
- *
- * {@hide}
- */
-interface IBluetoothHidHost {
- // Public API
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean connect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean disconnect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- int getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean getProtocolMode(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean virtualUnplug(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean setProtocolMode(in BluetoothDevice device, int protocolMode, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean getReport(in BluetoothDevice device, byte reportType, byte reportId, int bufferSize, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean setReport(in BluetoothDevice device, byte reportType, String report, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean sendData(in BluetoothDevice device, String report, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean getIdleTime(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean setIdleTime(in BluetoothDevice device, byte idleTime, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothLeAudio.aidl b/binder/android/bluetooth/IBluetoothLeAudio.aidl
deleted file mode 100644
index 2f158e3..0000000
--- a/binder/android/bluetooth/IBluetoothLeAudio.aidl
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2020 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-
-/**
- * APIs for Bluetooth LE Audio service
- *
- * @hide
- */
-interface IBluetoothLeAudio {
- // Public API
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean connect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disconnect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean setActiveDevice(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getActiveDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource);
-
- /* Same value as bluetooth::groups::kGroupUnknown */
- const int LE_AUDIO_GROUP_ID_INVALID = -1;
-
- const int GROUP_STATUS_INACTIVE = 0;
- const int GROUP_STATUS_ACTIVE = 1;
-
- const int GROUP_NODE_ADDED = 1;
- const int GROUP_NODE_REMOVED = 2;
-
- /**
- * Get device group id. Devices with same group id belong to same group (i.e left and right
- * earbud)
- */
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getGroupId(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void setVolume(int volume, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean groupAddNode(int group_id, in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean groupRemoveNode(int group_id, in BluetoothDevice device, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothManager.aidl b/binder/android/bluetooth/IBluetoothManager.aidl
deleted file mode 100644
index c0cc204..0000000
--- a/binder/android/bluetooth/IBluetoothManager.aidl
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2012 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.IBluetooth;
-import android.bluetooth.IBluetoothGatt;
-import android.bluetooth.IBluetoothManagerCallback;
-import android.bluetooth.IBluetoothProfileServiceConnection;
-import android.bluetooth.IBluetoothStateChangeCallback;
-import android.content.AttributionSource;
-
-/**
- * System private API for talking with the Bluetooth service.
- *
- * {@hide}
- */
-interface IBluetoothManager
-{
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- IBluetooth registerAdapter(in IBluetoothManagerCallback callback);
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- void unregisterAdapter(in IBluetoothManagerCallback callback);
- @UnsupportedAppUsage
- void registerStateChangeCallback(in IBluetoothStateChangeCallback callback);
- @UnsupportedAppUsage
- void unregisterStateChangeCallback(in IBluetoothStateChangeCallback callback);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean enable(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean enableNoAutoConnect(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disable(in AttributionSource attributionSource, boolean persist);
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- int getState();
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- IBluetoothGatt getBluetoothGatt();
-
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean bindBluetoothProfileService(int profile, IBluetoothProfileServiceConnection proxy);
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- void unbindBluetoothProfileService(int profile, IBluetoothProfileServiceConnection proxy);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.LOCAL_MAC_ADDRESS})")
- String getAddress(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- String getName(in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean onFactoryReset(in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isBleScanAlwaysAvailable();
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean enableBle(in AttributionSource attributionSource, IBinder b);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disableBle(in AttributionSource attributionSource, IBinder b);
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isBleAppPresent();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isHearingAidProfileSupported();
-}
diff --git a/binder/android/bluetooth/IBluetoothManagerCallback.aidl b/binder/android/bluetooth/IBluetoothManagerCallback.aidl
deleted file mode 100644
index 27ad2a0..0000000
--- a/binder/android/bluetooth/IBluetoothManagerCallback.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2012 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.IBluetooth;
-
-/**
- * API for Communication between BluetoothAdapter and BluetoothManager
- *
- * {@hide}
- */
-oneway interface IBluetoothManagerCallback {
- void onBluetoothServiceUp(in IBluetooth bluetoothService);
- void onBluetoothServiceDown();
- void onBrEdrDown();
-}
diff --git a/binder/android/bluetooth/IBluetoothMap.aidl b/binder/android/bluetooth/IBluetoothMap.aidl
deleted file mode 100644
index 2862005..0000000
--- a/binder/android/bluetooth/IBluetoothMap.aidl
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2008 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-
-/**
- * System private API for Bluetooth MAP service
- *
- * {@hide}
- */
-interface IBluetoothMap {
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getState(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- BluetoothDevice getClient(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disconnect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean isConnected(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- List<BluetoothDevice> getConnectedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- int getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothMapClient.aidl b/binder/android/bluetooth/IBluetoothMapClient.aidl
deleted file mode 100644
index 38aa2c4..0000000
--- a/binder/android/bluetooth/IBluetoothMapClient.aidl
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth;
-
-import android.app.PendingIntent;
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-import android.net.Uri;
-
-/**
- * System private API for Bluetooth MAP MCE service
- *
- * {@hide}
- */
-interface IBluetoothMapClient {
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf = { android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED })")
- boolean connect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf = { android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED })")
- boolean disconnect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean isConnected(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf = { android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED })")
- boolean setConnectionPolicy(in BluetoothDevice device,in int connectionPolicy, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf = { android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED })")
- int getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf = { android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.SEND_SMS })")
- boolean sendMessage(in BluetoothDevice device, in Uri[] contacts, in String message, in PendingIntent sentIntent, in PendingIntent deliveryIntent, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf = { android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.READ_SMS })")
- boolean getUnreadMessages(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getSupportedFeatures(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf = { android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.READ_SMS })")
- boolean setMessageStatus(in BluetoothDevice device, in String handle, in int status, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothMcpServiceManager.aidl b/binder/android/bluetooth/IBluetoothMcpServiceManager.aidl
deleted file mode 100644
index 823edf0..0000000
--- a/binder/android/bluetooth/IBluetoothMcpServiceManager.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-
-/**
- * Media Control Profile service manager
- * @hide
- */
-interface IBluetoothMcpServiceManager
-{
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)")
- void setDeviceAuthorized(in BluetoothDevice device, boolean isAuthorized, in AttributionSource source);
-}
diff --git a/binder/android/bluetooth/IBluetoothMetadataListener.aidl b/binder/android/bluetooth/IBluetoothMetadataListener.aidl
deleted file mode 100644
index e08919f..0000000
--- a/binder/android/bluetooth/IBluetoothMetadataListener.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth;
-
-import android.os.ParcelUuid;
-import android.bluetooth.BluetoothDevice;
-
-/**
- * Callback definitions for interacting with database change
- * @hide
- */
-oneway interface IBluetoothMetadataListener {
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- void onMetadataChanged(in BluetoothDevice devices, in int key, in byte[] value);
-}
diff --git a/binder/android/bluetooth/IBluetoothOobDataCallback.aidl b/binder/android/bluetooth/IBluetoothOobDataCallback.aidl
deleted file mode 100644
index 00975b6..0000000
--- a/binder/android/bluetooth/IBluetoothOobDataCallback.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.IBluetooth;
-import android.bluetooth.OobData;
-
-/**
- * API for receiving OobData from the host stack
- *
- * {@hide}
- */
-oneway interface IBluetoothOobDataCallback {
- void onOobData(int transport, in OobData oobData);
- void onError(int errorCode);
-}
diff --git a/binder/android/bluetooth/IBluetoothPan.aidl b/binder/android/bluetooth/IBluetoothPan.aidl
deleted file mode 100644
index 4ee664e..0000000
--- a/binder/android/bluetooth/IBluetoothPan.aidl
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2012 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-
-/**
- * API for Bluetooth Pan service
- *
- * {@hide}
- */
-interface IBluetoothPan {
- // Public API
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean isTetheringOn(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED,android.Manifest.permission.TETHER_PRIVILEGED})")
- void setBluetoothTethering(boolean value, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean connect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disconnect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- List<BluetoothDevice> getConnectedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- int getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothPbap.aidl b/binder/android/bluetooth/IBluetoothPbap.aidl
deleted file mode 100644
index 5d4f334..0000000
--- a/binder/android/bluetooth/IBluetoothPbap.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2008 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-
-/**
- * System private API for Bluetooth pbap service
- *
- * {@hide}
- */
-interface IBluetoothPbap {
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- int getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void disconnect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothPbapClient.aidl b/binder/android/bluetooth/IBluetoothPbapClient.aidl
deleted file mode 100644
index 1512e44..0000000
--- a/binder/android/bluetooth/IBluetoothPbapClient.aidl
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-
-/**
- * API for Bluetooth Phone Book Access Provile Client Side
- *
- * {@hide}
- */
-interface IBluetoothPbapClient {
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean connect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean disconnect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- int getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothProfileServiceConnection.aidl b/binder/android/bluetooth/IBluetoothProfileServiceConnection.aidl
deleted file mode 100644
index 5a048cf..0000000
--- a/binder/android/bluetooth/IBluetoothProfileServiceConnection.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package android.bluetooth;
-
-import android.content.ComponentName;
-import android.os.IBinder;
-
-/**
- * Callback for bluetooth profile connections.
- *
- * {@hide}
- */
-oneway interface IBluetoothProfileServiceConnection {
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- void onServiceConnected(in ComponentName comp, in IBinder service);
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- void onServiceDisconnected(in ComponentName comp);
-}
diff --git a/binder/android/bluetooth/IBluetoothSap.aidl b/binder/android/bluetooth/IBluetoothSap.aidl
deleted file mode 100644
index c97403e..0000000
--- a/binder/android/bluetooth/IBluetoothSap.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2013 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-
-/**
- * System private API for Bluetooth SAP service
- *
- * {@hide}
- */
-interface IBluetoothSap {
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getState(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- BluetoothDevice getClient(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean connect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disconnect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean isConnected(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- int getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/IBluetoothSocketManager.aidl b/binder/android/bluetooth/IBluetoothSocketManager.aidl
deleted file mode 100644
index e895b42..0000000
--- a/binder/android/bluetooth/IBluetoothSocketManager.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.os.ParcelUuid;
-import android.os.ParcelFileDescriptor;
-
-/**
- * API for Bluetooth Sockets service.
- *
- * {@hide}
- */
-interface IBluetoothSocketManager
-{
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- @nullable ParcelFileDescriptor connectSocket(in BluetoothDevice device, int type, in @nullable ParcelUuid uuid, int port, int flag);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- @nullable ParcelFileDescriptor createSocketChannel(int type, in @nullable String serviceName, in @nullable ParcelUuid uuid, int port, int flag);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void requestMaximumTxDataLength(in BluetoothDevice device);
-}
diff --git a/binder/android/bluetooth/IBluetoothStateChangeCallback.aidl b/binder/android/bluetooth/IBluetoothStateChangeCallback.aidl
deleted file mode 100644
index 1716801..0000000
--- a/binder/android/bluetooth/IBluetoothStateChangeCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2011, 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.
- */
-
-package android.bluetooth;
-
-/**
- * System private API for Bluetooth state change callback.
- *
- * {@hide}
- */
-oneway interface IBluetoothStateChangeCallback
-{
- void onBluetoothStateChange(boolean on);
-}
diff --git a/binder/android/bluetooth/IBluetoothVolumeControl.aidl b/binder/android/bluetooth/IBluetoothVolumeControl.aidl
deleted file mode 100644
index d390bf0..0000000
--- a/binder/android/bluetooth/IBluetoothVolumeControl.aidl
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-
-/**
- * APIs for Bluetooth Volume Control service
- *
- * @hide
- */
-interface IBluetoothVolumeControl {
- /* Public API */
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean connect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disconnect(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getConnectedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setConnectionPolicy(in BluetoothDevice device, int connectionPolicy, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- int getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void setVolume(in BluetoothDevice device, int volume, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void setVolumeGroup(int group_id, int volume, in AttributionSource attributionSource);
-}
diff --git a/binder/android/bluetooth/OobData.aidl b/binder/android/bluetooth/OobData.aidl
deleted file mode 100644
index 529e0b0..0000000
--- a/binder/android/bluetooth/OobData.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth;
-
-parcelable OobData;
diff --git a/binder/android/bluetooth/bluetooth_device.cc b/binder/android/bluetooth/bluetooth_device.cc
deleted file mode 100644
index 4247cf9..0000000
--- a/binder/android/bluetooth/bluetooth_device.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// Copyright 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.
-//
-
-#include "android/bluetooth/bluetooth_device.h"
-
-#include <utils/String16.h>
-
-#include "types/raw_address.h"
-
-using android::OK;
-using android::Parcel;
-using android::status_t;
-using android::String16;
-using android::String8;
-
-namespace android {
-namespace bluetooth {
-
-status_t BluetoothDevice::writeToParcel(Parcel* parcel) const {
- status_t status = parcel->writeString16(String16(address.ToString().c_str()));
- return status;
-}
-
-status_t BluetoothDevice::readFromParcel(const Parcel* parcel) {
- String16 tmp;
-
- status_t status = parcel->readString16(&tmp);
- if (status != OK) return status;
-
- RawAddress::FromString(String8(tmp).string(), address);
- return OK;
-}
-
-} // namespace bluetooth
-} // namespace android
diff --git a/binder/android/bluetooth/bluetooth_device.h b/binder/android/bluetooth/bluetooth_device.h
deleted file mode 100644
index 01bc00a..0000000
--- a/binder/android/bluetooth/bluetooth_device.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// Copyright 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.
-//
-
-#pragma once
-
-#include <binder/Parcel.h>
-#include <binder/Parcelable.h>
-
-#include <raw_address.h>
-
-namespace android {
-namespace bluetooth {
-
-class BluetoothDevice : public android::Parcelable {
- public:
- BluetoothDevice() = default;
- ~BluetoothDevice() = default;
-
- // Write |this| parcelable to the given |parcel|. Keep in mind that
- // implementations of writeToParcel must be manually kept in sync
- // with readFromParcel and the Java equivalent versions of these methods.
- //
- // Returns android::OK on success and an appropriate error otherwise.
- android::status_t writeToParcel(android::Parcel* parcel) const override;
-
- // Read data from the given |parcel| into |this|. After readFromParcel
- // completes, |this| should have equivalent state to the object that
- // wrote itself to the parcel.
- //
- // Returns android::OK on success and an appropriate error otherwise.
- android::status_t readFromParcel(const android::Parcel* parcel) override;
-
- RawAddress address;
-};
-
-} // namespace bluetooth
-} // namespace android
diff --git a/binder/android/bluetooth/le/AdvertiseData.aidl b/binder/android/bluetooth/le/AdvertiseData.aidl
deleted file mode 100644
index 713635d..0000000
--- a/binder/android/bluetooth/le/AdvertiseData.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package android.bluetooth.le;
-
-parcelable AdvertiseData;
diff --git a/binder/android/bluetooth/le/AdvertiseSettings.aidl b/binder/android/bluetooth/le/AdvertiseSettings.aidl
deleted file mode 100644
index 3677e75..0000000
--- a/binder/android/bluetooth/le/AdvertiseSettings.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package android.bluetooth.le;
-
-parcelable AdvertiseSettings;
\ No newline at end of file
diff --git a/binder/android/bluetooth/le/AdvertisingSetParameters.aidl b/binder/android/bluetooth/le/AdvertisingSetParameters.aidl
deleted file mode 100644
index 3918864..0000000
--- a/binder/android/bluetooth/le/AdvertisingSetParameters.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth.le;
-
-parcelable AdvertisingSetParameters;
diff --git a/binder/android/bluetooth/le/IAdvertisingSetCallback.aidl b/binder/android/bluetooth/le/IAdvertisingSetCallback.aidl
deleted file mode 100644
index 2e3241c..0000000
--- a/binder/android/bluetooth/le/IAdvertisingSetCallback.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 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.
- */
-package android.bluetooth.le;
-
-/**
- * Callback definitions for interacting with Advertiser
- * @hide
- */
-oneway interface IAdvertisingSetCallback {
- void onAdvertisingSetStarted(in int advertiserId, in int tx_power, in int status);
- void onOwnAddressRead(in int advertiserId, in int addressType, in String address);
- void onAdvertisingSetStopped(in int advertiserId);
- void onAdvertisingEnabled(in int advertiserId, in boolean enable, in int status);
- void onAdvertisingDataSet(in int advertiserId, in int status);
- void onScanResponseDataSet(in int advertiserId, in int status);
- void onAdvertisingParametersUpdated(in int advertiserId, in int tx_power, in int status);
- void onPeriodicAdvertisingParametersUpdated(in int advertiserId, in int status);
- void onPeriodicAdvertisingDataSet(in int advertiserId, in int status);
- void onPeriodicAdvertisingEnabled(in int advertiserId, in boolean enable, in int status);
-}
diff --git a/binder/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl b/binder/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl
deleted file mode 100644
index 84bbc14..0000000
--- a/binder/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 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.
- */
-package android.bluetooth.le;
-
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.le.PeriodicAdvertisingReport;
-
-/**
- * Callback definitions for interacting with Periodic Advertising
- * @hide
- */
-oneway interface IPeriodicAdvertisingCallback {
-
- void onSyncEstablished(in int syncHandle, in BluetoothDevice device, in int advertisingSid,
- in int skip, in int timeout, in int status);
- void onPeriodicAdvertisingReport(in PeriodicAdvertisingReport report);
- void onSyncLost(in int syncHandle);
-}
diff --git a/binder/android/bluetooth/le/IScannerCallback.aidl b/binder/android/bluetooth/le/IScannerCallback.aidl
deleted file mode 100644
index 025e7ff..0000000
--- a/binder/android/bluetooth/le/IScannerCallback.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 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.
- */
-package android.bluetooth.le;
-
-import android.bluetooth.le.ScanResult;
-
-/**
- * Callback definitions for interacting with Advertiser
- * @hide
- */
-oneway interface IScannerCallback {
- void onScannerRegistered(in int status, in int scannerId);
-
- void onScanResult(in ScanResult scanResult);
- void onBatchScanResults(in List<ScanResult> batchResults);
- void onFoundOrLost(in boolean onFound, in ScanResult scanResult);
- void onScanManagerErrorCallback(in int errorCode);
-}
diff --git a/binder/android/bluetooth/le/PeriodicAdvertisingParameters.aidl b/binder/android/bluetooth/le/PeriodicAdvertisingParameters.aidl
deleted file mode 100644
index 3f714f0..0000000
--- a/binder/android/bluetooth/le/PeriodicAdvertisingParameters.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth.le;
-
-parcelable PeriodicAdvertisingParameters;
diff --git a/binder/android/bluetooth/le/PeriodicAdvertisingReport.aidl b/binder/android/bluetooth/le/PeriodicAdvertisingReport.aidl
deleted file mode 100644
index 986ac61..0000000
--- a/binder/android/bluetooth/le/PeriodicAdvertisingReport.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package android.bluetooth.le;
-
-parcelable PeriodicAdvertisingReport;
diff --git a/binder/android/bluetooth/le/ResultStorageDescriptor.aidl b/binder/android/bluetooth/le/ResultStorageDescriptor.aidl
deleted file mode 100644
index afc1b41..0000000
--- a/binder/android/bluetooth/le/ResultStorageDescriptor.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package android.bluetooth.le;
-
-/**
- * {@hide}
- */
-
-parcelable ResultStorageDescriptor;
diff --git a/binder/android/bluetooth/le/ScanFilter.aidl b/binder/android/bluetooth/le/ScanFilter.aidl
deleted file mode 100644
index e3ebd85..0000000
--- a/binder/android/bluetooth/le/ScanFilter.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package android.bluetooth.le;
-
-parcelable ScanFilter;
diff --git a/binder/android/bluetooth/le/ScanResult.aidl b/binder/android/bluetooth/le/ScanResult.aidl
deleted file mode 100644
index f16dc18..0000000
--- a/binder/android/bluetooth/le/ScanResult.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package android.bluetooth.le;
-
-parcelable ScanResult;
\ No newline at end of file
diff --git a/binder/android/bluetooth/le/ScanSettings.aidl b/binder/android/bluetooth/le/ScanSettings.aidl
deleted file mode 100644
index e84e078..0000000
--- a/binder/android/bluetooth/le/ScanSettings.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package android.bluetooth.le;
-
-parcelable ScanSettings;
diff --git a/binder/android/os/parcel_uuid.cc b/binder/android/os/parcel_uuid.cc
deleted file mode 100644
index ea97104..0000000
--- a/binder/android/os/parcel_uuid.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-//
-// Copyright 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.
-//
-
-#include "android/os/parcel_uuid.h"
-
-using android::OK;
-using android::Parcel;
-using android::status_t;
-using ::bluetooth::Uuid;
-
-namespace android {
-namespace os {
-
-namespace {
-static uint64_t uuid_lsb(const Uuid& uuid) {
- uint64_t lsb = 0;
-
- auto uu = uuid.To128BitBE();
- for (int i = 8; i <= 15; i++) {
- lsb <<= 8;
- lsb |= uu[i];
- }
-
- return lsb;
-}
-
-static uint64_t uuid_msb(const Uuid& uuid) {
- uint64_t msb = 0;
-
- auto uu = uuid.To128BitBE();
- for (int i = 0; i <= 7; i++) {
- msb <<= 8;
- msb |= uu[i];
- }
-
- return msb;
-}
-} // namespace
-
-status_t ParcelUuid::writeToParcel(Parcel* parcel) const {
- status_t status = parcel->writeInt64(uuid_msb(uuid));
- if (status != OK) return status;
-
- status = parcel->writeInt64(uuid_lsb(uuid));
- return status;
-}
-
-status_t ParcelUuid::readFromParcel(const Parcel* parcel) {
- int64_t uuid_msb, uuid_lsb;
-
- status_t status = parcel->readInt64(&uuid_msb);
- if (status != OK) return status;
-
- status = parcel->readInt64(&uuid_lsb);
- if (status != OK) return status;
-
- std::array<uint8_t, Uuid::kNumBytes128> uu;
- for (int i = 0; i < 8; i++) {
- uu[7 - i] = (uuid_msb >> (8 * i)) & 0xFF;
- uu[15 - i] = (uuid_lsb >> (8 * i)) & 0xFF;
- }
-
- uuid = Uuid::From128BitBE(uu);
- return OK;
-}
-
-} // namespace os
-} // namespace android
\ No newline at end of file
diff --git a/binder/android/os/parcel_uuid.h b/binder/android/os/parcel_uuid.h
deleted file mode 100644
index 76bf9c4..0000000
--- a/binder/android/os/parcel_uuid.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// Copyright 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.
-//
-
-#pragma once
-
-#include <binder/Parcel.h>
-#include <binder/Parcelable.h>
-#include <bluetooth/uuid.h>
-
-namespace android {
-namespace os {
-
-class ParcelUuid : public android::Parcelable {
- public:
- ParcelUuid() = default;
- ~ParcelUuid() = default;
-
- // Write |this| parcelable to the given |parcel|. Keep in mind that
- // implementations of writeToParcel must be manually kept in sync
- // with readFromParcel and the Java equivalent versions of these methods.
- //
- // Returns android::OK on success and an appropriate error otherwise.
- android::status_t writeToParcel(android::Parcel* parcel) const override;
-
- // Read data from the given |parcel| into |this|. After readFromParcel
- // completes, |this| should have equivalent state to the object that
- // wrote itself to the parcel.
- //
- // Returns android::OK on success and an appropriate error otherwise.
- android::status_t readFromParcel(const android::Parcel* parcel) override;
-
- ::bluetooth::Uuid uuid;
-};
-
-} // namespace os
-} // namespace android
diff --git a/blueberry/controllers/android_bt_target_device.py b/blueberry/controllers/android_bt_target_device.py
deleted file mode 100644
index 9e7aebf..0000000
--- a/blueberry/controllers/android_bt_target_device.py
+++ /dev/null
@@ -1,515 +0,0 @@
-"""Controller class for an android bt device with git_master-bds-dev build.
-
-The config for this derived_bt_target_device in mobileharness is:
-- name: android_bt_target_device
- devices:
- - type: MiscTestbedSubDevice
- dimensions:
- mobly_type: DerivedBtDevice
- properties:
- ModuleName: android_bt_target_device
- ClassName: AndroidBtTargetDevice
- Params:
- config:
- device_id: phone_serial_number
- audio_params:
- channel: 2
- duration: 50
- music_file: "music.wav"
- sample_rate: 44100
-"""
-
-import logging
-import os
-import time
-
-from mobly import asserts
-from mobly.controllers.android_device import AndroidDevice
-from mobly.signals import ControllerError
-# Internal import
-from blueberry.utils import bt_constants
-from blueberry.utils.android_bluetooth_decorator import AndroidBluetoothDecorator
-import blueberry.utils.bt_test_utils as btutils
-
-ADB_FILE = "rec.pcm"
-ADB_PATH = "/sdcard/Music/"
-WAVE_FILE_TEMPLATE = "recorded_audio_%s.wav"
-DEFAULT_WAIT_TIME = 3.0
-
-# A MediaBrowserService implemented in the SL4A app to intercept Media keys and
-# commands.
-BLUETOOTH_SL4A_AUDIO_SRC_MBS = "BluetoothSL4AAudioSrcMBS"
-
-A2DP_HFP_PROFILES = [
- bt_constants.BluetoothProfile.A2DP_SINK,
- bt_constants.BluetoothProfile.HEADSET_CLIENT
-]
-
-
-class AndroidBtTargetDevice(object):
- """Implements an android device as a hfp and a2dp sink device.
-
- With git_master-bds-dev build, the android device can act as a bluetooth
- hfp and a2dp sink device.
- """
-
- def __init__(self, config):
- """Initializes an android hfp device."""
- logging.info("Initializes the android hfp device")
- self.pri_ad = None
- self.sec_ad = None
- self.serial = config.get("device_id", None)
- self.audio_params = config.get("audio_params", None)
-
- if self.serial:
- # self._ad for accessing the device at the end of the test
- self._ad = AndroidDevice(self.serial)
- self.aud = adb_ui_device.AdbUiDevice(self._ad)
- self.pri_ad = AndroidBluetoothDecorator(self._ad)
- self.pri_ad.init_setup()
- self.pri_ad.sl4a_setup()
- self.sl4a = self._ad.services.sl4a
- self.mac_address = self.sl4a.bluetoothGetLocalAddress()
-
- if self.audio_params:
- self._initialize_audio_params()
- self.avrcp_ready = False
-
- def __getattr__(self, name):
- return getattr(self.pri_ad, name)
-
- def _disable_profiles(self):
- if self.sec_ad is None:
- raise MissingBtClientDeviceError("Please provide sec_ad forsetting"
- "profiles")
- self.set_profiles_policy_off(self.sec_ad, A2DP_HFP_PROFILES)
-
- def _initialize_audio_params(self):
- self.audio_capture_path = os.path.join(self._ad.log_path, "audio_capture")
- os.makedirs(self.audio_capture_path)
- self.adb_path = os.path.join(ADB_PATH, ADB_FILE)
- self.wave_file_template = os.path.join(self.audio_capture_path,
- WAVE_FILE_TEMPLATE)
- self.wave_file_number = 0
-
- def _verify_pri_ad(self):
- if not self.pri_ad:
- raise ControllerError("No be target device")
-
- def clean_up(self):
- """Resets Bluetooth and stops all services when the device is destroyed."""
- self.deactivate_ble_pairing_mode()
- self.factory_reset_bluetooth()
- self._ad.services.stop_all()
-
- def a2dp_sink_connect(self):
- """Establishes the hft connection between self.pri_ad and self.sec_ad."""
- self._verify_pri_ad()
- connected = self.pri_ad.a2dp_sink_connect(self.sec_ad)
- asserts.assert_true(
- connected, "The a2dp sink connection between {} and {} failed".format(
- self.serial, self.sec_ad.serial))
- self.log.info("The a2dp sink connection between %s and %s succeeded",
- self.serial, self.sec_ad.serial)
- return True
-
- def activate_pairing_mode(self):
- """Makes the android hfp device discoverable over Bluetooth."""
- self.log.info("Activating the pairing mode of the android target device")
- self.pri_ad.activate_pairing_mode()
-
- def activate_ble_pairing_mode(self):
- """Activates BLE pairing mode on an AndroidBtTargetDevice."""
- self.pri_ad.activate_ble_pairing_mode()
-
- def deactivate_ble_pairing_mode(self):
- """Deactivates BLE pairing mode on an AndroidBtTargetDevice."""
- self.pri_ad.deactivate_ble_pairing_mode()
-
- def add_pri_ad_device(self, pri_ad):
- """Adds primary android device as bt target device.
-
- The primary android device should have been initialized with
- android_bluetooth_decorator.
-
- Args:
- pri_ad: the primary android device as bt target device.
- """
- self._ad = pri_ad
- self.pri_ad = pri_ad
- self.sl4a = self._ad.services.sl4a
- self.mac_address = self.sl4a.bluetoothGetLocalAddress()
- self.log = self.pri_ad.log
- self.serial = self.pri_ad.serial
- self.log.info(
- "Adds primary android device with id %s for the bluetooth"
- "connection", pri_ad.serial)
- if self.audio_params:
- self._initialize_audio_params()
-
- def add_sec_ad_device(self, sec_ad):
- """Adds second android device for bluetooth connection.
-
- The second android device should have sl4a service acitvated.
-
- Args:
- sec_ad: the second android device for bluetooth connection.
- """
- self.log.info(
- "Adds second android device with id %s for the bluetooth"
- "connection", sec_ad.serial)
- self.sec_ad = sec_ad
- self.sec_ad_mac_address = self.sec_ad.sl4a.bluetoothGetLocalAddress()
-
- def answer_phone_call(self):
- """Answers an incoming phone call."""
- if not self.is_hfp_connected():
- self.hfp_connect()
- # Make sure the device is in ringing state.
- if not self.wait_for_call_state(
- bt_constants.CALL_STATE_RINGING, bt_constants.CALL_STATE_TIMEOUT_SEC):
- raise ControllerError(
- "Timed out after %ds waiting for the device %s to be ringing state "
- "before anwsering the incoming phone call." %
- (bt_constants.CALL_STATE_TIMEOUT_SEC, self.serial))
- self.log.info("Answers the incoming phone call from hf phone %s for %s",
- self.mac_address, self.sec_ad_mac_address)
- return self.sl4a.bluetoothHfpClientAcceptCall(self.sec_ad_mac_address)
-
- def call_volume_down(self):
- """Lowers the volume."""
- current_volume = self.mbs.getVoiceCallVolume()
- if current_volume > 0:
- change_volume = current_volume - 1
- self.log.debug("Set voice call volume from %d to %d." %
- (current_volume, change_volume))
- self.mbs.setVoiceCallVolume(change_volume)
-
- def call_volume_up(self):
- """Raises the volume."""
- current_volume = self.mbs.getVoiceCallVolume()
- if current_volume < self.mbs.getVoiceCallMaxVolume():
- change_volume = current_volume + 1
- self.log.debug("Set voice call volume from %d to %d." %
- (current_volume, change_volume))
- self.mbs.setVoiceCallVolume(change_volume)
-
- def disconnect_all(self):
- self._disable_profiles()
-
- def factory_reset_bluetooth(self):
- """Factory resets Bluetooth on the android hfp device."""
- self.log.info("Factory resets Bluetooth on the android target device")
- self.pri_ad.factory_reset_bluetooth()
-
- def get_bluetooth_mac_address(self):
- """Gets Bluetooth mac address of this android_bt_device."""
- self.log.info("Getting Bluetooth mac address for AndroidBtTargetDevice.")
- mac_address = self.sl4a.bluetoothGetLocalAddress()
- self.log.info("Bluetooth mac address of AndroidBtTargetDevice: %s",
- mac_address)
- return mac_address
-
- def get_audio_params(self):
- """Gets audio params from the android_bt_target_device."""
- return self.audio_params
-
- def get_new_wave_file_path(self):
- """Gets a new wave file path for the audio capture."""
- wave_file_path = self.wave_file_template % self.wave_file_number
- while os.path.exists(wave_file_path):
- self.wave_file_number += 1
- wave_file_path = self.wave_file_template % self.wave_file_number
- return wave_file_path
-
- def get_unread_messages(self) -> None:
- """Gets unread messages from the connected device (MSE)."""
- self.sl4a.mapGetUnreadMessages(self.sec_ad_mac_address)
-
- def hangup_phone_call(self):
- """Hangs up an ongoing phone call."""
- if not self.is_hfp_connected():
- self.hfp_connect()
- self.log.info("Hangs up the phone call from hf phone %s for %s",
- self.mac_address, self.sec_ad_mac_address)
- return self.sl4a.bluetoothHfpClientTerminateAllCalls(
- self.sec_ad_mac_address)
-
- def hfp_connect(self):
- """Establishes the hft connection between self.pri_ad and self.sec_ad."""
- self._verify_pri_ad()
- connected = self.pri_ad.hfp_connect(self.sec_ad)
- asserts.assert_true(
- connected, "The hfp connection between {} and {} failed".format(
- self.serial, self.sec_ad.serial))
- self.log.info("The hfp connection between %s and %s succeed", self.serial,
- self.sec_ad.serial)
- return connected
-
- def init_ambs_for_avrcp(self):
- """Initializes media browser service for avrcp.
-
- This is required to be done before running any of the passthrough
- commands.
-
- Steps:
- 1. Starts up the AvrcpMediaBrowserService on the A2dp source phone. This
- MediaBrowserService is part of the SL4A app.
- 2. Switch the playback state to be paused.
- 3. Connects a MediaBrowser to the A2dp sink's A2dpMediaBrowserService.
-
- Returns:
- True: if it is avrcp ready after the initialization.
- False: if it is still not avrcp ready after the initialization.
-
- Raises:
- Signals.ControllerError: raise if AvrcpMediaBrowserService on the A2dp
- source phone fails to be started.
- """
- if self.is_avrcp_ready():
- return True
- if not self.is_a2dp_sink_connected():
- self.a2dp_sink_connect()
-
- self.sec_ad.log.info("Starting AvrcpMediaBrowserService")
- self.sec_ad.sl4a.bluetoothMediaPhoneSL4AMBSStart()
-
- time.sleep(DEFAULT_WAIT_TIME)
-
- # Check if the media session "BluetoothSL4AAudioSrcMBS" is active on sec_ad.
- active_sessions = self.sec_ad.sl4a.bluetoothMediaGetActiveMediaSessions()
- if BLUETOOTH_SL4A_AUDIO_SRC_MBS not in active_sessions:
- raise ControllerError("Failed to start AvrcpMediaBrowserService.")
-
- self.log.info("Connecting to A2dp media browser service")
- self.sl4a.bluetoothMediaConnectToCarMBS()
-
- # TODO(user) Wait for an event back instead of sleep
- time.sleep(DEFAULT_WAIT_TIME)
- self.avrcp_ready = True
- return self.avrcp_ready
-
- def is_avrcp_ready(self):
- """Checks if the pri_ad and sec_ad are ready for avrcp."""
- self._verify_pri_ad()
- if self.avrcp_ready:
- return True
- active_sessions = self.sl4a.bluetoothMediaGetActiveMediaSessions()
- if not active_sessions:
- self.log.info("The device is not avrcp ready")
- self.avrcp_ready = False
- else:
- self.log.info("The device is avrcp ready")
- self.avrcp_ready = True
- return self.avrcp_ready
-
- def is_hfp_connected(self):
- """Checks if the pri_ad and sec_ad are hfp connected."""
- self._verify_pri_ad()
- if self.sec_ad is None:
- raise MissingBtClientDeviceError("The sec_ad was not added")
- return self.sl4a.bluetoothHfpClientGetConnectionStatus(
- self.sec_ad_mac_address)
-
- def is_a2dp_sink_connected(self):
- """Checks if the pri_ad and sec_ad are hfp connected."""
- self._verify_pri_ad()
- if self.sec_ad is None:
- raise MissingBtClientDeviceError("The sec_ad was not added")
- return self.sl4a.bluetoothA2dpSinkGetConnectionStatus(
- self.sec_ad_mac_address)
-
- def last_number_dial(self):
- """Redials last outgoing phone number."""
- if not self.is_hfp_connected():
- self.hfp_connect()
- self.log.info("Redials last number from hf phone %s for %s",
- self.mac_address, self.sec_ad_mac_address)
- self.sl4a.bluetoothHfpClientDial(self.sec_ad_mac_address, None)
-
- def map_connect(self):
- """Establishes the map connection between self.pri_ad and self.sec_ad."""
- self._verify_pri_ad()
- connected = self.pri_ad.map_connect(self.sec_ad)
- asserts.assert_true(
- connected, "The map connection between {} and {} failed".format(
- self.serial, self.sec_ad.serial))
- self.log.info("The map connection between %s and %s succeed", self.serial,
- self.sec_ad.serial)
-
- def map_disconnect(self) -> None:
- """Initiates a map disconnection to the connected device.
-
- Raises:
- BluetoothProfileConnectionError: raised if failed to disconnect.
- """
- self._verify_pri_ad()
- if not self.pri_ad.map_disconnect(self.sec_ad_mac_address):
- raise BluetoothProfileConnectionError(
- 'Failed to terminate the MAP connection with the device "%s".' %
- self.sec_ad_mac_address)
-
- def pbap_connect(self):
- """Establishes the pbap connection between self.pri_ad and self.sec_ad."""
- connected = self.pri_ad.pbap_connect(self.sec_ad)
- asserts.assert_true(
- connected, "The pbap connection between {} and {} failed".format(
- self.serial, self.sec_ad.serial))
- self.log.info("The pbap connection between %s and %s succeed", self.serial,
- self.sec_ad.serial)
-
- def pause(self):
- """Sends Avrcp pause command."""
- self.send_media_passthrough_cmd(bt_constants.CMD_MEDIA_PAUSE, self.sec_ad)
-
- def play(self):
- """Sends Avrcp play command."""
- self.send_media_passthrough_cmd(bt_constants.CMD_MEDIA_PLAY, self.sec_ad)
-
- def power_on(self):
- """Turns the Bluetooth on the android bt garget device."""
- self.log.info("Turns on the bluetooth")
- return self.sl4a.bluetoothToggleState(True)
-
- def power_off(self):
- """Turns the Bluetooth off the android bt garget device."""
- self.log.info("Turns off the bluetooth")
- return self.sl4a.bluetoothToggleState(False)
-
- def route_call_audio(self, connect=False):
- """Routes call audio during a call."""
- if not self.is_hfp_connected():
- self.hfp_connect()
- self.log.info(
- "Routes call audio during a call from hf phone %s for %s "
- "audio connection %s after routing", self.mac_address,
- self.sec_ad_mac_address, connect)
- if connect:
- self.sl4a.bluetoothHfpClientConnectAudio(self.sec_ad_mac_address)
- else:
- self.sl4a.bluetoothHfpClientDisconnectAudio(self.sec_ad_mac_address)
-
- def reject_phone_call(self):
- """Rejects an incoming phone call."""
- if not self.is_hfp_connected():
- self.hfp_connect()
- # Make sure the device is in ringing state.
- if not self.wait_for_call_state(
- bt_constants.CALL_STATE_RINGING, bt_constants.CALL_STATE_TIMEOUT_SEC):
- raise ControllerError(
- "Timed out after %ds waiting for the device %s to be ringing state "
- "before rejecting the incoming phone call." %
- (bt_constants.CALL_STATE_TIMEOUT_SEC, self.serial))
- self.log.info("Rejects the incoming phone call from hf phone %s for %s",
- self.mac_address, self.sec_ad_mac_address)
- return self.sl4a.bluetoothHfpClientRejectCall(self.sec_ad_mac_address)
-
- def set_audio_params(self, audio_params):
- """Sets audio params to the android_bt_target_device."""
- self.audio_params = audio_params
-
- def track_previous(self):
- """Sends Avrcp skip prev command."""
- self.send_media_passthrough_cmd(
- bt_constants.CMD_MEDIA_SKIP_PREV, self.sec_ad)
-
- def track_next(self):
- """Sends Avrcp skip next command."""
- self.send_media_passthrough_cmd(
- bt_constants.CMD_MEDIA_SKIP_NEXT, self.sec_ad)
-
- def start_audio_capture(self):
- """Starts the audio capture over adb."""
- if self.audio_params is None:
- raise MissingAudioParamsError("Missing audio params for captureing audio")
- if not self.is_a2dp_sink_connected():
- self.a2dp_sink_connect()
- cmd = "ap2f --usage 1 --start --duration {} --target {}".format(
- self.audio_params["duration"], self.adb_path)
- self.log.info("Starts capturing audio with adb shell command %s", cmd)
- self.adb.shell(cmd)
-
- def stop_audio_capture(self):
- """Stops the audio capture and stores it in wave file.
-
- Returns:
- File name of the recorded file.
-
- Raises:
- MissingAudioParamsError: when self.audio_params is None
- """
- if self.audio_params is None:
- raise MissingAudioParamsError("Missing audio params for captureing audio")
- if not self.is_a2dp_sink_connected():
- self.a2dp_sink_connect()
- adb_pull_args = [self.adb_path, self.audio_capture_path]
- self.log.info("start adb -s %s pull %s", self.serial, adb_pull_args)
- self._ad.adb.pull(adb_pull_args)
- pcm_file_path = os.path.join(self.audio_capture_path, ADB_FILE)
- self.log.info("delete the recored file %s", self.adb_path)
- self._ad.adb.shell("rm {}".format(self.adb_path))
- wave_file_path = self.get_new_wave_file_path()
- self.log.info("convert pcm file %s to wav file %s", pcm_file_path,
- wave_file_path)
- btutils.convert_pcm_to_wav(pcm_file_path, wave_file_path, self.audio_params)
- return wave_file_path
-
- def stop_all_services(self):
- """Stops all services for the pri_ad device."""
- self.log.info("Stops all services on the android bt target device")
- self._ad.services.stop_all()
-
- def stop_ambs_for_avrcp(self):
- """Stops media browser service for avrcp."""
- if self.is_avrcp_ready():
- self.log.info("Stops avrcp connection")
- self.sec_ad.sl4a.bluetoothMediaPhoneSL4AMBSStop()
- self.avrcp_ready = False
-
- def stop_voice_dial(self):
- """Stops voice dial."""
- if not self.is_hfp_connected():
- self.hfp_connect()
- self.log.info("Stops voice dial from hf phone %s for %s", self.mac_address,
- self.sec_ad_mac_address)
- if self.is_hfp_connected():
- self.sl4a.bluetoothHfpClientStopVoiceRecognition(
- self.sec_ad_mac_address)
-
- def take_bug_report(self,
- test_name=None,
- begin_time=None,
- timeout=300,
- destination=None):
- """Wrapper method to capture bugreport on the android bt target device."""
- self._ad.take_bug_report(test_name, begin_time, timeout, destination)
-
- def voice_dial(self):
- """Triggers voice dial."""
- if not self.is_hfp_connected():
- self.hfp_connect()
- self.log.info("Triggers voice dial from hf phone %s for %s",
- self.mac_address, self.sec_ad_mac_address)
- if self.is_hfp_connected():
- self.sl4a.bluetoothHfpClientStartVoiceRecognition(
- self.sec_ad_mac_address)
-
- def log_type(self):
- """Gets the log type of Android bt target device.
-
- Returns:
- A string, the log type of Android bt target device.
- """
- return bt_constants.LogType.BLUETOOTH_DEVICE_SIMULATOR
-
-
-class BluetoothProfileConnectionError(Exception):
- """Error for Bluetooth Profile connection problems."""
-
-
-class MissingBtClientDeviceError(Exception):
- """Error for missing required bluetooth client device."""
-
-
-class MissingAudioParamsError(Exception):
- """Error for missing the audio params."""
diff --git a/blueberry/controllers/bt_stub.py b/blueberry/controllers/bt_stub.py
deleted file mode 100644
index 0cd024e..0000000
--- a/blueberry/controllers/bt_stub.py
+++ /dev/null
@@ -1,294 +0,0 @@
-"""Bluetooth stub class.
-
-This controller offers no direct control to any device. It simply prompts the
-user to perform a certain action on the device it is standing in for. For use
-in test scripts where no controller for the DUT exists.
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import six
-
-
-class BtStub(object):
- """Stub for when controller class does not exist for a Bluetooth device.
-
- This class will simulate semi-automation by prompting user to manually
- perform actions on the Bluetooth device.
- """
-
- # Connection Commands
- def power_off(self):
- """Prompt the user to power off the Bluetooth device."""
- six.moves.input("Power Off Bluetooth device, then press enter.")
-
- def power_on(self):
- """Prompt the user to power on the Bluetooth device."""
- six.moves.input("Power ON Bluetooth device, then press enter.")
-
- def activate_pairing_mode(self):
- """Prompt the user to put the Bluetooth device into pairing mode."""
- six.moves.input("Put Bluetooth device into pairing mode,"
- "then press enter.")
-
- def get_bluetooth_mac_address(self):
- """Prompt the user to input the Bluetooth MAC address for this device.
-
- Returns:
- mac_address (str): the string received from user input.
- """
- mac_address = six.moves.input("Enter BT MAC address, then press enter.")
- return mac_address
-
- def set_device_name(self, device_name):
- """Prompt the user to set the device name (Carkit Only).
-
- Args:
- device_name: String of device name to be set.
-
- Returns: None
- """
- six.moves.input("Device name is: %s", device_name)
-
- def factory_reset_bluetooth(self):
- """Prompt the user to factory reset Bluetooth on the device."""
- six.moves.input("Factory reset Bluetooth on the Bluetooth device, "
- "then press enter.")
-
- # A2DP: Bluetooth stereo streaming protocol methods.
- def is_audio_playing(self):
- """Prompt the user to indicate if the audio is playing.
-
- Returns:
- A Bool, true is audio is playing, false if not.
- """
- audio_playing = six.moves.input("Indicate if audio is playing: "
- "true/false.")
- return bool(audio_playing)
-
- # AVRCP Commands
- def volume_up(self):
- """Prompt the user to raise the volume on the Bluetooth device."""
- six.moves.input("Press the Volume Up Button on the Bluetooth device, "
- "then press enter.")
-
- def volume_down(self):
- """Prompt the user to lower the volume on the Bluetooth device."""
- six.moves.input("Press the Volume Down Button on the Bluetooth device, "
- "then press enter.")
-
- def track_next(self):
- """Prompt the user to skip the track on the Bluetooth device."""
- six.moves.input("Press the Skip Track Button on the Bluetooth device, "
- "then press enter.")
-
- def track_previous(self):
- """Prompt the user to rewind the track on the Bluetooth device."""
- six.moves.input("Press the Rewind Track Button on the Bluetooth device, "
- "then press enter.")
-
- def play(self):
- """Prompt the user to press play on the Bluetooth device."""
- six.moves.input("Press the Play Button on the Bluetooth device, "
- "then press enter.")
-
- def pause(self):
- """Prompt the user to press pause on the Bluetooth device."""
- six.moves.input("Press the Pause Button on the Bluetooth device, "
- "then press enter.")
-
- def repeat(self):
- """Prompt the user to set the repeat option on the device."""
- six.moves.input("Press the Repeat Button on the Bluetooth device, "
- "then press enter.")
-
- def fast_forward(self):
- """Prompt the user to press the fast forward option/button on the device.
-
- Returns: None
- """
- six.moves.input("Press the Fast Forward Button on the Bluetooth device, "
- "then press enter.")
-
- def rewind(self):
- """Prompt the user to press Rewind option on the device.
-
- Returns: None
- """
- six.moves.input("Press the Rewind option on the Bluetooth device, "
- "then press enter.")
-
- # TODO(user): browse_media_content may need more work in terms of input
- # params and value(s) returned
- def browse_media_content(self, directory=""):
- """Prompt the user to enter to the paired device media folders.
-
- Args:
- directory: A path to the directory to browse to.
-
- Returns:
- List - empty
- """
- six.moves.input("Navigate to directory: %s", directory)
- return []
-
- def delete_song(self, file_path=""):
- """Prompt the user to delete a song.
-
- Args:
- file_path (optional): A file path to the song to be deleted.
-
- Returns: None
- """
- six.moves.input("Delete a song %s", file_path)
-
- def shuffle_song(self):
- """Prompt the user to shuffle a playlist.
-
- Returns: None
- """
- six.moves.input("Shuffle a playlist")
-
- # HFP (Hands Free Phone protocol) Commands
- def call_volume_up(self):
- """Prompt the user to press the volume up button on an active call.
-
- Returns: None
- """
- six.moves.input("Press the volume up button for an active call.")
-
- def call_volume_down(self):
- """Prompt the user to press the volume down button on an active call.
-
- Returns: None
- """
- six.moves.input("Press the volume down button for an active call.")
-
- def answer_phone_call(self):
- """Prompt the user to press the button to answer a phone call..
-
- Returns: None
- """
- six.moves.input("Press the button to answer the phone call.")
-
- def hangup_phone_call(self):
- """Prompt the user to press the button to hang up on an active phone call.
-
- Returns: None
- """
- six.moves.input("Press the button to hang up on the phone call.")
-
- def call_contact(self, name):
- """Prompt the user to select a contact from the phonebook and call.
-
- Args:
- name: string name of contact to call
-
- Returns: None
- """
- six.moves.input("Select contact, %s, to call.", name)
-
- def call_number(self, phone_number):
- """Prompt the user to dial a phone number and call.
-
- Args:
- phone_number: string of phone number to dial and call
-
- Returns: None
- """
- six.moves.input("Dial phone number and initiate a call. %s", phone_number)
-
- def swap_call(self):
- """Prompt the user to push the button to swap.
-
- Function swaps between the primary and secondary calls. One call will
- be active and the other will be on hold.
-
- Returns: None
- """
- six.moves.input("Press the button to swap calls.")
-
- def merge_call(self):
- """Prompt the user to push the button to merge calls.
-
- Merges calls between the primary and secondary calls into a conference
- call.
-
- Returns: None
- """
- six.moves.input("Press the button to merge calls into a conference call.")
-
- def hold_call(self):
- """Prompt the user to put the primary call on hold.
-
- Primary call will be on hold, while the secondary call becomes active.
-
- Returns: None
- """
- six.moves.input("Press the hold button to put primary call on hold.")
-
- def mute_call(self):
- """Prompt the user to mute the ongoing active call.
-
- Returns: None
- """
- six.moves.input("Press Mute button on active call.")
-
- def unmute_call(self):
- """Prompt the user to unmute the ongoing active call.
-
- Returns: None
- """
- six.moves.input("Press the Unmute button on an active call.")
-
- def reject_phone_call(self):
- """Prompt the user to reject an incoming call.
-
- Returns: None
- """
- six.moves.input("Press the Reject button to reject an incoming call.")
-
- def answer_voip_call(self):
- """Prompt the user to press the button to answer a VOIP call.
-
- Returns: None
- """
- six.moves.input("Press the Answer button on an incoming VOIP phone call.")
-
- def hangup_voip_call(self):
- """Prompt the user to press the button to hangup on the active VOIP call.
-
- Returns: None
- """
- six.moves.input("Press the hangup button on the active VOIP call.")
-
- def reject_voip_call(self):
- """Prompt the user to press the Reject button on the incoming VOIP call.
-
- Returns: None
- """
- six.moves.input("Press the Reject button on the incoming VOIP call.")
-
- def voice_dial(self):
- """Prompt user to initiate a voice dial from the phone.
-
- Returns: None
- """
- six.moves.input("Initiate a voice dial.")
-
- def last_number_dial(self):
- """Prompt user to iniate a call to the last number dialed.
-
- Returns: None
- """
- six.moves.input("Initiate a call to the last number dialed.")
-
- # TODO(user): does this method need a input parameter?
- def route_call_audio(self):
- """Prompt user to route a call from AG to HF, and vice versa.
-
- Returns: None
- """
- six.moves.input("Reroute call audio.")
diff --git a/blueberry/controllers/derived_bt_device.py b/blueberry/controllers/derived_bt_device.py
deleted file mode 100644
index 37fafc1..0000000
--- a/blueberry/controllers/derived_bt_device.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# Copyright 2019 Google LLC
-#
-# 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.
-"""Controller class for a Bluetooth Device.
-
-This controller will instantiate derived classes from BtDevice and the
-module/class specified via strings in configs dictionary.
-
-The idea is to allow vendors to run blueberry tests with their controller class
-through this controller module, eliminating the need to edit the test classes
-themselves.
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import importlib
-import logging
-import yaml
-
-MOBLY_CONTROLLER_CONFIG_NAME = "DerivedBtDevice"
-MOBLY_CONTROLLER_CONFIG_MODULE_KEY = "ModuleName"
-MOBLY_CONTROLLER_CONFIG_CLASS_KEY = "ClassName"
-MOBLY_CONTROLLER_CONFIG_PARAMS_KEY = "Params"
-
-
-def create(configs):
- """Creates DerivedBtDevice controller objects.
-
- For each config dict in configs:
- Import desired controller class from config, compose DerivedBtDevice class
- from that class and BtDevice, instantiate with params from config.
-
- Args:
- configs (list): A list of dicts, each representing a configuration for a
- Bluetooth device. Each dict should be of the format:
- {"ModuleName": <name of module in blueberry.controllers>,
- "ClassName": <name of class to derive controller from>,
- "Params": <kwargs in dict form to instantiate class with>}
-
- Returns:
- A list with DerivedBtDevice objects.
- """
- return [_create_bt_device_class(config) for config in configs]
-
-
-def _create_bt_device_class(config):
- """Created new device class from associated device controller from config."""
- module = importlib.import_module(
- "blueberry.controllers.%s" %
- config[MOBLY_CONTROLLER_CONFIG_MODULE_KEY])
- logging.info("Creating DerivedBtDevice from %r", config)
- cls = getattr(module, config[MOBLY_CONTROLLER_CONFIG_CLASS_KEY])
- params = yaml.safe_load("%s" %
- config.get(MOBLY_CONTROLLER_CONFIG_PARAMS_KEY, {}))
- new_class = type(MOBLY_CONTROLLER_CONFIG_NAME, (cls, BtDevice), params)
- new_class_inst = new_class(**params)
- return new_class_inst
-
-
-def destroy(derived_bt_devices):
- """Cleans up DerivedBtDevice objects."""
- for device in derived_bt_devices:
- # Execute cleanup if the controller class has the method "clean_up".
- if hasattr(device, "clean_up"):
- device.clean_up()
- del derived_bt_devices
-
-
-class BtDevice(object):
- """Base class for all Bluetooth Devices.
-
- Provides additional necessary functionality for use within blueberry.
- """
-
- def __init__(self):
- """Initializes a derived bt base class."""
- self._user_params = {}
-
- def setup(self):
- """For devices that need extra setup."""
-
- def set_user_params(self, params):
- """Intended for passing mobly user_params into a derived device class.
-
- Args:
- params: Mobly user params.
- """
- self._user_params = params
-
- def get_user_params(self):
- """Return saved user_params.
-
- Returns:
- user_params.
- """
- return self._user_params
-
- def factory_reset_bluetooth(self) -> None:
- """Factory resets Bluetooth on an BT Device."""
- raise NotImplementedError
-
- def activate_pairing_mode(self) -> None:
- """Activates pairing mode on an AndroidDevice."""
- raise NotImplementedError
diff --git a/blueberry/controllers/grpc_bt_sync_mock.py b/blueberry/controllers/grpc_bt_sync_mock.py
deleted file mode 100644
index d3e00e8..0000000
--- a/blueberry/controllers/grpc_bt_sync_mock.py
+++ /dev/null
@@ -1,81 +0,0 @@
-"""A generic gRPC mock device controller.
-
-Example MH testbed config for Hostside:
-- name: GrpcBtSyncStub-1
- devices:
- - type: MiscTestbedSubDevice
- dimensions:
- mobly_type: DerivedBtDevice
- properties:
- ModuleName: grpc_bt_sync_mock
- ClassName: GrpcBtSyncMock
- Params:
- config:
- mac_address: FE:ED:BE:EF:CA:FE
- dimensions:
- device: GrpcBtSyncStub
-"""
-import subprocess
-
-from absl import flags
-from absl import logging
-import grpc
-
-# Internal import
-from blueberry.grpc.proto import blueberry_device_controller_pb2
-from blueberry.grpc.proto import blueberry_device_controller_pb2_grpc
-
-FLAGS = flags.FLAGS
-flags.DEFINE_string('server', 'dns:///[::1]:10000', 'server address')
-
-
-class GrpcBtSyncMock(object):
- """Generic GRPC device controller."""
-
- def __init__(self, config):
- """Initialize GRPC object."""
- super(GrpcBtSyncMock, self).__init__()
- self.mac_address = config['mac_address']
-
- def __del__(self):
- self.server_proc.terminate()
- del self.channel_creds
- del self.channel
- del self.stub
-
- def setup(self):
- """Setup the gRPC server that the sync mock will respond to."""
- server_path = self.get_user_params()['mh_files']['grpc_server'][0]
- logging.info('Start gRPC server: %s', server_path)
- self.server_proc = subprocess.Popen([server_path],
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- universal_newlines=True,
- bufsize=0)
-
- self.channel_creds = loas2.loas2_channel_credentials()
- self.channel = grpc.secure_channel(FLAGS.server, self.channel_creds)
- grpc.channel_ready_future(self.channel).result()
- self.stub = blueberry_device_controller_pb2_grpc.BlueberryDeviceControllerStub(
- self.channel)
-
- def init_setup(self):
- logging.info('init setup TO BE IMPLEMENTED')
-
- def set_target(self, bt_device):
- self._target_device = bt_device
-
- def pair_and_connect_bluetooth(self, target_mac_address):
- """Pair and connect to a peripheral Bluetooth device."""
- request = blueberry_device_controller_pb2.TargetMacAddress(
- mac_address=target_mac_address)
- try:
- response = self.stub.PairAndConnectBluetooth(request)
- logging.info('pair and connect bluetooth response: %s', response)
- if response.error:
- print('error handler TO BE IMPLEMENTED')
- else:
- return response.pairing_time_sec, response.connection_time_sec
- except grpc.RpcError as rpc_error:
- print(rpc_error)
diff --git a/blueberry/controllers/grpc_bt_target_mock.py b/blueberry/controllers/grpc_bt_target_mock.py
deleted file mode 100644
index 85f6b51..0000000
--- a/blueberry/controllers/grpc_bt_target_mock.py
+++ /dev/null
@@ -1,78 +0,0 @@
-"""gRPC mock target for testing purposes.
-
-Example MH testbed config for Hostside:
-- name: GrpcBtTargetStub-1
- devices:
- - type: MiscTestbedSubDevice
- dimensions:
- mobly_type: DerivedBtDevice
- properties:
- ModuleName: grpc_bt_target_mock
- ClassName: GrpcBtTargetMock
- Params:
- config:
- mac_address: FE:ED:BE:EF:CA:FE
- dimensions:
- device: GrpcBtTargetStub
-"""
-import subprocess
-
-from absl import flags
-from absl import logging
-import grpc
-
-# Internal import
-from blueberry.grpc.proto import blueberry_device_controller_pb2
-from blueberry.grpc.proto import blueberry_device_controller_pb2_grpc
-
-FLAGS = flags.FLAGS
-
-
-class GrpcBtTargetMock(object):
- """BT Mock Target for testing the GRPC interface."""
-
- def __init__(self, config):
- """Initialize GRPC object."""
- super(GrpcBtTargetMock, self).__init__()
- self.mac_address = config['mac_address']
-
- def __del__(self):
- self.server_proc.terminate()
- del self.channel_creds
- del self.channel
- del self.stub
-
- def setup(self):
- """Setup the gRPC server that the target mock will respond to."""
- server_path = self.get_user_params()['mh_files']['grpc_server'][0]
- logging.info('Start gRPC server: %s', server_path)
- self.server_proc = subprocess.Popen([server_path],
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- universal_newlines=True,
- bufsize=0)
-
- self.channel_creds = loas2.loas2_channel_credentials()
- self.channel = grpc.secure_channel(FLAGS.server, self.channel_creds)
- grpc.channel_ready_future(self.channel).result()
- self.stub = blueberry_device_controller_pb2_grpc.BlueberryDeviceControllerStub(
- self.channel)
-
- def activate_pairing_mode(self):
- logging.info('activate pairing mode TO BE IMPLEMENTED')
- request = blueberry_device_controller_pb2.DiscoverableMode(mode=True)
- try:
- response = self.stub.SetDiscoverableMode(request)
- logging.info('set discoverageble response: %s', response)
- return 0
- except grpc.RpcError as rpc_error:
- print(rpc_error)
- return -1
-
- def factory_reset_bluetooth(self):
- logging.info('factory reset TO BE IMPLEMENTED')
-
- def get_bluetooth_mac_address(self):
- logging.info('mac_address: %s', self.mac_address)
- return self.mac_address
diff --git a/blueberry/decorators/android_bluetooth_client_decorator.py b/blueberry/decorators/android_bluetooth_client_decorator.py
deleted file mode 100644
index f9834ea..0000000
--- a/blueberry/decorators/android_bluetooth_client_decorator.py
+++ /dev/null
@@ -1,48 +0,0 @@
-"""A Bluetooth Client Decorator util for an Android Device.
-
-This utility allows the user to decorate an device with a custom decorator from
-the blueberry/decorators directory.
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-
-from __future__ import print_function
-
-import importlib
-import re
-from mobly.controllers.android_device import AndroidDevice
-
-
-def decorate(ad, decorator):
- """Utility to decorate an AndroidDevice.
-
- Args:
- ad: Device, must be of type AndroidDevice.
- decorator: String, class name of the decorator to use.
- Returns:
- AndroidDevice object.
- """
-
- if not isinstance(ad, AndroidDevice):
- raise TypeError('Must apply AndroidBluetoothClientDecorator to an '
- 'AndroidDevice')
- decorator_module = camel_to_snake(decorator)
- module = importlib.import_module(
- 'blueberry.decorators.%s' % decorator_module)
- cls = getattr(module, decorator)
- ad = cls(ad)
-
- return ad
-
-
-def camel_to_snake(cls_name):
- """Utility to convert a class name from camel case to snake case.
-
- Args:
- cls_name: string
- Returns:
- string
- """
- s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', cls_name)
- return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
diff --git a/blueberry/decorators/android_bluetooth_client_test_decorator.py b/blueberry/decorators/android_bluetooth_client_test_decorator.py
deleted file mode 100644
index 769579e..0000000
--- a/blueberry/decorators/android_bluetooth_client_test_decorator.py
+++ /dev/null
@@ -1,25 +0,0 @@
-"""An example Bluetooth Client Decorator.
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-
-from __future__ import print_function
-
-from mobly.controllers.android_device import AndroidDevice
-
-
-class AndroidBluetoothClientTestDecorator(AndroidDevice):
- """A class used to test Blueberry's BT Client Profile decoration."""
-
- def __init__(self, ad):
- self._ad = ad
- if not isinstance(self._ad, AndroidDevice):
- raise TypeError('Must apply AndroidBluetoothClientTestDecorator to an '
- 'AndroidDevice')
-
- def __getattr__(self, name):
- return getattr(self._ad, name)
-
- def test_decoration(self):
- return 'I make this device fancy!'
diff --git a/blueberry/grpc/blueberry_device_controller.py b/blueberry/grpc/blueberry_device_controller.py
deleted file mode 100644
index c99a204..0000000
--- a/blueberry/grpc/blueberry_device_controller.py
+++ /dev/null
@@ -1,40 +0,0 @@
-"""Blueberry gRPC device controller.
-
-This is a server to act as a mock device for testing the Blueberry gRPC
-interface.
-"""
-
-from concurrent import futures
-from absl import app
-from absl import flags
-
-import grpc
-
-# Internal import
-from blueberry.grpc import blueberry_device_controller_service
-from blueberry.grpc.proto import blueberry_device_controller_pb2_grpc
-
-
-_HOST = '[::]'
-
-FLAGS = flags.FLAGS
-flags.DEFINE_integer('port', 10000, 'port to listen on')
-flags.DEFINE_integer('threads', 10, 'number of worker threads in thread pool')
-
-
-def main(unused_argv):
- server = grpc.server(
- futures.ThreadPoolExecutor(max_workers=FLAGS.threads),
- ports=(FLAGS.port,)) # pytype: disable=wrong-keyword-args
- servicer = (
- blueberry_device_controller_service.BlueberryDeviceControllerServicer())
- blueberry_device_controller_pb2_grpc.add_BlueberryDeviceControllerServicer_to_server(
- servicer, server)
- server_creds = loas2.loas2_server_credentials()
- server.add_secure_port(f'{_HOST}:{FLAGS.port}', server_creds)
- server.start()
- server.wait_for_termination()
-
-
-if __name__ == '__main__':
- app.run(main)
diff --git a/blueberry/grpc/blueberry_device_controller_service.py b/blueberry/grpc/blueberry_device_controller_service.py
deleted file mode 100644
index a17d7db..0000000
--- a/blueberry/grpc/blueberry_device_controller_service.py
+++ /dev/null
@@ -1,37 +0,0 @@
-"""Blueberry gRPC Mock Service.
-
-This is simple mock service that is used to verify the implementation of the
-Blueberry gRPC device controller interface.
-"""
-
-from blueberry.grpc.proto import blueberry_device_controller_pb2
-from blueberry.grpc.proto import blueberry_device_controller_pb2_grpc
-
-
-class BlueberryDeviceControllerServicer(
- blueberry_device_controller_pb2_grpc.BlueberryDeviceControllerServicer):
- """A BlueberryTest gRPC server."""
-
- def __init__(self, *args, **kwargs):
- super(BlueberryDeviceControllerServicer, self).__init__(*args, **kwargs)
- self._error = "testing 123"
-
- def SetDiscoverableMode(self, request, servicer_context):
- """Sets the device's discoverable mode.
-
- Args:
- request: a blueberry_test_server_pb2.DiscoverableMode object containing
- the "mode" to set the device to.
- servicer_context: A grpc.ServicerContext for use during service of the
- RPC.
-
- Returns:
- A blueberry_test_server_pb2.DiscoverableResult
- """
- return blueberry_device_controller_pb2.DiscoverableResult(
- result=True,
- error=self._error)
-
- def PairAndConnectBluetooth(self, request, servicer_context):
- return blueberry_device_controller_pb2.PairAndConnectBluetoothResult(
- pairing_time_sec=0.1, connection_time_sec=0.2, error=None)
diff --git a/blueberry/grpc/blueberry_test_client.py b/blueberry/grpc/blueberry_test_client.py
deleted file mode 100644
index 1fe8eb1..0000000
--- a/blueberry/grpc/blueberry_test_client.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""Blueberry Test Client.
-
-Simple gRPC client to test the Blueberry Mock server.
-"""
-
-from absl import app
-from absl import flags
-
-import grpc
-
-# Internal import
-from blueberry.grpc.proto import blueberry_device_controller_pb2
-from blueberry.grpc.proto import blueberry_device_controller_pb2_grpc
-
-FLAGS = flags.FLAGS
-flags.DEFINE_string('server', 'dns:///[::1]:10000', 'server address')
-
-
-def _UpdateDiscoveryMode(stub, request):
- try:
- print('try SetDiscoverableMode')
- response = stub.SetDiscoverableMode(request)
- print('complete response')
- print(response)
- return 0
- except grpc.RpcError as rpc_error:
- print(rpc_error)
- return -1
-
-
-def main(unused_argv):
- channel_creds = loas2.loas2_channel_credentials()
- with grpc.secure_channel(FLAGS.server, channel_creds) as channel:
- grpc.channel_ready_future(channel).result()
- stub = blueberry_device_controller_pb2_grpc.BlueberryDeviceControllerStub(
- channel)
-
- print('request grpc')
- request = blueberry_device_controller_pb2.DiscoverableMode(
- mode=True)
- print('Call _UpdateDiscoveryMode')
- return _UpdateDiscoveryMode(stub, request)
-
-
-if __name__ == '__main__':
- app.run(main)
diff --git a/blueberry/grpc/proto/blueberry_device_controller.proto b/blueberry/grpc/proto/blueberry_device_controller.proto
deleted file mode 100644
index d3f3906..0000000
--- a/blueberry/grpc/proto/blueberry_device_controller.proto
+++ /dev/null
@@ -1,36 +0,0 @@
-syntax = "proto3";
-
-package wearables.qa.blueberry.grpc;
-
-option java_multiple_files = true;
-option jspb_use_correct_proto2_semantics = true;
-
-message DiscoverableMode {
- bool mode = 1; // True to set discoverable on, False to set discoverable off.
-}
-
-message DiscoverableResult {
- bool result = 1; // True if successful, False if unsuccessful.
- string error = 2; // Error message if unsuccessful.
-}
-
-message TargetMacAddress {
- string mac_address = 1; // Mac Address of target device.
-}
-
-message PairAndConnectBluetoothResult {
- double pairing_time_sec =
- 1; // The time it takes in seconds to pair the devices.
- double connection_time_sec =
- 2; // The time it takes in seconds to connect the devices.
- string error = 3; // Error message if unsuccessful.
-}
-
-service BlueberryDeviceController {
- // Returns the result from a request to set device to discoverable.
- rpc SetDiscoverableMode(DiscoverableMode) returns (DiscoverableResult) {}
-
- // Returns the result from a request to connect to a target device.
- rpc PairAndConnectBluetooth(TargetMacAddress)
- returns (PairAndConnectBluetoothResult) {}
-}
diff --git a/blueberry/sample_testbed.yaml b/blueberry/sample_testbed.yaml
deleted file mode 100644
index 99da384..0000000
--- a/blueberry/sample_testbed.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-TestBeds:
- - Name: SampleTestBed
- Controllers:
- AndroidDevice:
- - serial: 94GAZ00A5C
- phone_number: 12341234
- DerivedBtDevice:
- - ModuleName: iclever_hb01
- ClassName: IcleverHb01
- Params: '{"config":{"mac_address":"C4:45:67:02:94:F0","fifo_id":"AH06IVJP","arduino_port":"1"}}'
diff --git a/blueberry/tests/a2dp/bluetooth_a2dp_test.py b/blueberry/tests/a2dp/bluetooth_a2dp_test.py
deleted file mode 100644
index 9b578be..0000000
--- a/blueberry/tests/a2dp/bluetooth_a2dp_test.py
+++ /dev/null
@@ -1,221 +0,0 @@
-# Lint as: python3
-"""Tests for Bluetooth A2DP audio streamming."""
-
-import time
-
-from mobly import asserts
-from mobly import test_runner
-from mobly import signals
-
-from blueberry.controllers import android_bt_target_device
-from blueberry.utils import blueberry_base_test
-from blueberry.utils import bt_audio_utils
-from blueberry.utils import bt_constants
-from blueberry.utils import bt_test_utils
-
-# Number of seconds for A2DP audio check.
-A2DP_AUDIO_CHECK_TIMEOUT_SEC = 3
-
-# Number of seconds for duration of reference audio.
-REFERENCE_AUDIO_DURATION_SEC = 1.0
-
-# Default threshold of the mean opinion score (MOS).
-MOS_THRESHOLD = 4.5
-
-# The audio parameters for creating a sine wave.
-AUDIO_PARAMS = {
- 'file_path': '/sdcard/Music',
- 'frequency': 480,
- 'channel': 2,
- 'sample_rate': 48000,
- 'sample_format': 16,
- 'duration_sec': 60
-}
-
-
-class BluetoothA2dpTest(blueberry_base_test.BlueberryBaseTest):
- """Test class for Bluetooth A2DP test.
-
- This test uses a fixed frequency sine wave to be the reference audio, makes a
- DUT play this audio and then starts audio capture from a connected Bluetooth
- sink device, measures mean opinion score (MOS) of the recorded audio and
- compares the MOS with a threshold to detemine the test result.
- """
-
- def setup_class(self):
- """Standard Mobly setup class."""
- super(BluetoothA2dpTest, self).setup_class()
-
- # Threshold of the MOS to determine a test result. Default value is 4.5.
- self.threshold = float(self.user_params.get('mos_threshold', MOS_THRESHOLD))
-
- self.phone = self.android_devices[0]
- self.phone.init_setup()
- self.phone.sl4a_setup()
-
- # Generates a sine wave to be reference audio in comparison, and push it to
- # the phone storage.
- self.audio_file_on_device, self.audio_file_on_host = (
- bt_audio_utils.generate_sine_wave_to_device(
- self.phone,
- AUDIO_PARAMS['file_path'],
- AUDIO_PARAMS['frequency'],
- AUDIO_PARAMS['channel'],
- AUDIO_PARAMS['sample_rate'],
- AUDIO_PARAMS['sample_format'],
- AUDIO_PARAMS['duration_sec'])
- )
-
- # Trims the audio to 1 second duration for reference.
- self.reference_audio_file = bt_audio_utils.trim_audio(
- audio_file=self.audio_file_on_host,
- duration_sec=REFERENCE_AUDIO_DURATION_SEC)
-
- self.derived_bt_device = self.derived_bt_devices[0]
- self.derived_bt_device.factory_reset_bluetooth()
- self.derived_bt_device.activate_pairing_mode()
- self.mac_address = self.derived_bt_device.get_bluetooth_mac_address()
- self.phone.pair_and_connect_bluetooth(self.mac_address)
-
- # Sleep until the connection stabilizes.
- time.sleep(3)
-
- # Adds the phone to be the secondary device in the android-to-android case.
- if isinstance(self.derived_bt_device,
- android_bt_target_device.AndroidBtTargetDevice):
- self.derived_bt_device.add_sec_ad_device(self.phone)
-
- def assert_a2dp_expected_status(self, is_playing, fail_msg):
- """Asserts that A2DP audio is in the expected status.
-
- Args:
- is_playing: bool, True if A2DP audio is playing as expected.
- fail_msg: string, a message explaining the details of test failure.
- """
- bt_test_utils.wait_until(
- timeout_sec=A2DP_AUDIO_CHECK_TIMEOUT_SEC,
- condition_func=self.phone.mbs.btIsA2dpPlaying,
- func_args=[self.mac_address],
- expected_value=is_playing,
- exception=signals.TestFailure(fail_msg))
-
- def test_play_a2dp_audio(self):
- """Test for playing A2DP audio through Bluetooth."""
-
- # Plays media audio from the phone.
- audio_file_url = 'file://' + self.audio_file_on_device
- if not self.phone.sl4a.mediaPlayOpen(audio_file_url):
- raise signals.TestError(
- 'Failed to open and play "%s" on the phone "%s".' %
- (self.audio_file_on_device, self.phone.serial))
- self.phone.sl4a.mediaPlayStart()
-
- # Starts audio capture for Bluetooth audio stream.
- self.derived_bt_device.start_audio_capture()
-
- # Stops audio capture and generates an recorded audio file.
- recorded_audio_file = self.derived_bt_device.stop_audio_capture()
- self.phone.sl4a.mediaPlayStop()
- self.phone.sl4a.mediaPlayClose()
-
- # Measures MOS for the recorded audio.
- mos = bt_audio_utils.measure_audio_mos(recorded_audio_file,
- self.reference_audio_file)
-
- # Asserts that the measured MOS should be more than the threshold.
- asserts.assert_true(
- mos >= self.threshold,
- 'MOS of the recorded audio "%.3f" is lower than the threshold "%.3f".' %
- (mos, self.threshold))
-
- def test_resume_a2dp_audio_after_phone_call_ended(self):
- """Test for resuming A2DP audio after a phone call ended.
-
- Tests that A2DP audio can be paused when receiving a incoming phone call,
- and resumed after this phone call ended.
- """
- # Checks if two android device exist.
- if len(self.android_devices) < 2:
- raise signals.TestError('This test requires two android devices.')
- pri_phone = self.phone
- sec_phone = self.android_devices[1]
- sec_phone.init_setup()
- pri_number = pri_phone.dimensions.get('phone_number')
- if not pri_number:
- raise signals.TestError('Please set the dimension "phone_number" to the '
- 'primary phone.')
- sec_number = sec_phone.dimensions.get('phone_number')
- if not sec_number:
- raise signals.TestError('Please set the dimension "phone_number" to the '
- 'secondary phone.')
-
- # Plays media audio from the phone.
- audio_file_url = 'file://' + self.audio_file_on_device
- if not self.phone.sl4a.mediaPlayOpen(audio_file_url):
- raise signals.TestError(
- 'Failed to open and play "%s" on the phone "%s".' %
- (self.audio_file_on_device, self.phone.serial))
- self.phone.sl4a.mediaPlayStart()
-
- # Checks if A2DP audio is playing.
- self.assert_a2dp_expected_status(
- is_playing=True,
- fail_msg='A2DP audio is not playing.')
-
- try:
- # Makes a incoming phone call.
- sec_phone.sl4a.telecomCallNumber(pri_number)
- sec_phone.log.info('Made a phone call to device "%s".' % pri_phone.serial)
- pri_phone.log.info('Waiting for the incoming call from device "%s"...'
- % sec_phone.serial)
-
- is_ringing = pri_phone.wait_for_call_state(
- bt_constants.CALL_STATE_RINGING,
- bt_constants.CALL_STATE_TIMEOUT_SEC)
- if not is_ringing:
- raise signals.TestError(
- 'Timed out after %ds waiting for the incoming call from device '
- '"%s".' % (bt_constants.CALL_STATE_TIMEOUT_SEC, sec_phone.serial))
-
- # Checks if A2DP audio is paused.
- self.assert_a2dp_expected_status(
- is_playing=False,
- fail_msg='A2DP audio is not paused when receiving a phone call.')
- finally:
- # Ends the incoming phone call.
- sec_phone.sl4a.telecomEndCall()
- sec_phone.log.info('Ended the phone call.')
- is_idle = pri_phone.wait_for_call_state(
- bt_constants.CALL_STATE_IDLE,
- bt_constants.CALL_STATE_TIMEOUT_SEC)
- if not is_idle:
- raise signals.TestError(
- 'Timed out after %ds waiting for the phone call to be ended.' %
- bt_constants.CALL_STATE_TIMEOUT_SEC)
-
- # Checks if A2DP audio is resumed.
- self.assert_a2dp_expected_status(
- is_playing=True,
- fail_msg='A2DP audio is not resumed when the phone call is ended.')
-
- # Starts audio capture for Bluetooth audio stream.
- self.derived_bt_device.start_audio_capture()
-
- # Stops audio capture and generates an recorded audio file.
- recorded_audio_file = self.derived_bt_device.stop_audio_capture()
- pri_phone.sl4a.mediaPlayStop()
- pri_phone.sl4a.mediaPlayClose()
-
- # Measures MOS for the recorded audio.
- mos = bt_audio_utils.measure_audio_mos(recorded_audio_file,
- self.reference_audio_file)
-
- # Asserts that the measured MOS should be more than the threshold.
- asserts.assert_true(
- mos >= self.threshold,
- 'MOS of the recorded audio "%.3f" is lower than the threshold "%.3f".' %
- (mos, self.threshold))
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/audio_capture/bluetooth_audio_capture_test.py b/blueberry/tests/audio_capture/bluetooth_audio_capture_test.py
deleted file mode 100644
index 74e8705..0000000
--- a/blueberry/tests/audio_capture/bluetooth_audio_capture_test.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# Lint as: python3
-"""Tests for testing audio capture in android bt target controller.
-
- location of the controller:
- blueberry.controllers.android_bt_target_device
- Before the test, the music file should be copied to the location of the
- pri_phone. The a2dp sink phone should be with the android build that can
- support a2dp sink profile (for example, the git_master-bds-dev).
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import logging
-import time
-
-from mobly import asserts
-from mobly import test_runner
-from blueberry.utils import blueberry_base_test
-from blueberry.utils import bt_test_utils
-
-MUSIC_FILE = '1khz.wav'
-
-
-class BluetoothAudioCaptureTest(blueberry_base_test.BlueberryBaseTest):
-
- def setup_class(self):
- """Standard Mobly setup class."""
- super(BluetoothAudioCaptureTest, self).setup_class()
- self.derived_bt_device = self.derived_bt_devices[0]
- for device in self.android_devices:
- device.init_setup()
- device.sl4a_setup()
- self.pri_phone = self.android_devices[0]
- self.mac_address = self.derived_bt_device.get_bluetooth_mac_address()
- self.derived_bt_device.activate_pairing_mode()
- self.pri_phone.sl4a.bluetoothDiscoverAndBond(self.mac_address)
- self.pri_phone.wait_for_connection_success(self.mac_address)
- # Gives more time for the pairing between the pri_phone and the
- # derived_bt_device (the android bt target device)
- time.sleep(3)
- self.derived_bt_device.add_sec_ad_device(self.pri_phone)
- self.derived_bt_device.disconnect_all()
- self.duration = self.derived_bt_device.audio_params['duration']
- self.recorded_duration = 0
-
- def setup_test(self):
- """Setup for bluetooth latency test."""
- logging.info('Setup Test for audio capture test')
- super(BluetoothAudioCaptureTest, self).setup_test()
- asserts.assert_true(self.derived_bt_device.a2dp_sink_connect(),
- 'Failed to establish A2dp Sink connection')
-
- def test_audio_capture(self):
- """Tests the audio capture for the android bt target device."""
-
- music_file = self.derived_bt_device.audio_params.get(
- 'music_file', MUSIC_FILE)
- music_file = 'file:///sdcard/Music/{}'.format(music_file)
- self.pri_phone.sl4a.mediaPlayOpen(music_file)
- self.pri_phone.sl4a.mediaPlaySetLooping()
- self.pri_phone.sl4a.mediaPlayStart()
- time.sleep(3)
- self.pri_phone.log.info(self.pri_phone.sl4a.mediaPlayGetInfo())
- self.derived_bt_device.start_audio_capture()
- time.sleep(self.duration)
- audio_captured = self.derived_bt_device.stop_audio_capture()
- self.pri_phone.sl4a.mediaPlayStop()
- self.pri_phone.sl4a.mediaPlayClose()
- self.derived_bt_device.log.info('Audio play and record stopped')
- self.recorded_duration = bt_test_utils.get_duration_seconds(audio_captured)
- self.derived_bt_device.log.info(
- 'The capture duration is %s s and the recorded duration is %s s',
- self.duration, self.recorded_duration)
-
- def teardown_class(self):
- logging.info('Factory resetting Bluetooth on devices.')
- self.pri_phone.factory_reset_bluetooth()
- self.derived_bt_device.factory_reset_bluetooth()
- super(BluetoothAudioCaptureTest, self).teardown_class()
- self.derived_bt_device.stop_all_services()
- self.record_data({
- 'Test Name': 'test_audio_capture',
- 'sponge_properties': {
- 'duration': self.duration,
- 'recorded duration': self.recorded_duration
- }
- })
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/avrcp/bluetooth_avrcp_test.py b/blueberry/tests/avrcp/bluetooth_avrcp_test.py
deleted file mode 100644
index 484fcd9..0000000
--- a/blueberry/tests/avrcp/bluetooth_avrcp_test.py
+++ /dev/null
@@ -1,349 +0,0 @@
-# Lint as: python3
-"""Tests for AVRCP basic functionality."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import time
-
-from mobly import test_runner
-from mobly import signals
-from mobly.controllers.android_device_lib import adb
-from blueberry.controllers import android_bt_target_device
-from blueberry.utils import blueberry_base_test
-from blueberry.utils import bt_constants
-
-# The audio source path of BluetoothMediaPlayback in the SL4A app.
-ANDROID_MEDIA_PATH = '/sdcard/Music/test'
-
-# Timeout for track change and playback state update in second.
-MEDIA_UPDATE_TIMEOUT_SEC = 3
-
-
-class BluetoothAvrcpTest(blueberry_base_test.BlueberryBaseTest):
- """Test Class for Bluetooth AVRCP.
-
- This test requires two or more audio files exist in path "/sdcard/Music/test"
- on the primary device, and device controllers need to have the following APIs:
- 1. play()
- 2. pause()
- 3. track_previous()
- 4. track_next()
- """
-
- def setup_class(self):
- """Standard Mobly setup class."""
- super(BluetoothAvrcpTest, self).setup_class()
-
- for device in self.android_devices:
- device.init_setup()
- device.sl4a_setup()
-
- # The device which role is AVRCP Target (TG).
- self.pri_device = self.android_devices[0]
-
- if len(self.android_devices) > 1 and not self.derived_bt_devices:
- self.derived_bt_device = self.android_devices[1]
- else:
- self.derived_bt_device = self.derived_bt_devices[0]
-
- # Check if the derived bt device is android bt target device.
- self.is_android_bt_target_device = isinstance(
- self.derived_bt_device, android_bt_target_device.AndroidBtTargetDevice)
-
- # Check if the audio files exist on the primary device.
- try:
- self.audio_files = self.pri_device.adb.shell(
- 'ls %s' % ANDROID_MEDIA_PATH).decode().split('\n')[:-1]
- if len(self.audio_files) < 2:
- raise signals.TestError(
- 'Please push two or more audio files to %s on the primary device '
- '"%s".' % (ANDROID_MEDIA_PATH, self.pri_device.serial))
- except adb.AdbError as error:
- if 'No such file or directory' in str(error):
- raise signals.TestError(
- 'No directory "%s" found on the primary device "%s".' %
- (ANDROID_MEDIA_PATH, self.pri_device.serial))
- raise error
-
- self.mac_address = self.derived_bt_device.get_bluetooth_mac_address()
- self.derived_bt_device.activate_pairing_mode()
- self.pri_device.set_target(self.derived_bt_device)
- self.pri_device.pair_and_connect_bluetooth(self.mac_address)
- self.pri_device.allow_extra_permissions()
- # Gives more time for the pairing between two devices.
- time.sleep(3)
-
- if self.is_android_bt_target_device:
- self.derived_bt_device.add_sec_ad_device(self.pri_device)
-
- # Starts BluetoothSL4AAudioSrcMBS on the phone.
- if self.is_android_bt_target_device:
- self.derived_bt_device.init_ambs_for_avrcp()
- else:
- self.pri_device.sl4a.bluetoothMediaPhoneSL4AMBSStart()
- # Waits for BluetoothSL4AAudioSrcMBS to be active.
- time.sleep(1)
- # Changes the playback state to Playing in order to other Media passthrough
- # commands can work.
- self.pri_device.sl4a.bluetoothMediaHandleMediaCommandOnPhone(
- bt_constants.CMD_MEDIA_PLAY)
-
- # Collects media metadata of all tracks.
- self.tracks = []
- for _ in range(len(self.audio_files)):
- self.tracks.append(self.pri_device.get_current_track_info())
- self.pri_device.sl4a.bluetoothMediaHandleMediaCommandOnPhone(
- bt_constants.CMD_MEDIA_SKIP_NEXT)
- self.pri_device.log.info('Tracks: %s' % self.tracks)
-
- # Sets Playback state to Paused as default.
- self.pri_device.sl4a.bluetoothMediaHandleMediaCommandOnPhone(
- bt_constants.CMD_MEDIA_PAUSE)
-
- def teardown_class(self):
- """Teardown class for bluetooth avrcp media play test."""
- super(BluetoothAvrcpTest, self).teardown_class()
- # Stops BluetoothSL4AAudioSrcMBS after all test methods finish.
- if self.is_android_bt_target_device:
- self.derived_bt_device.stop_ambs_for_avrcp()
- else:
- self.pri_device.sl4a.bluetoothMediaPhoneSL4AMBSStop()
-
- def teardown_test(self):
- """Teardown test for bluetooth avrcp media play test."""
- super(BluetoothAvrcpTest, self).teardown_test()
- # Sets Playback state to Paused after a test method finishes.
- self.pri_device.sl4a.bluetoothMediaHandleMediaCommandOnPhone(
- bt_constants.CMD_MEDIA_PAUSE)
-
- def wait_for_media_info_sync(self):
- """Waits for sync Media information between two sides.
-
- Waits for sync the current playback state and Now playing track info from
- the android bt target device to the phone.
- """
- # Check if Playback state is sync.
- expected_state = self.pri_device.get_current_playback_state()
- self.derived_bt_device.verify_playback_state_changed(
- expected_state=expected_state,
- exception=signals.TestError(
- 'Playback state is not equivalent between two sides. '
- '"%s" != "%s"' %
- (self.derived_bt_device.get_current_playback_state(),
- expected_state)))
-
- # Check if Now Playing track is sync.
- expected_track = self.pri_device.get_current_track_info()
- self.derived_bt_device.verify_current_track_changed(
- expected_track=expected_track,
- exception=signals.TestError(
- 'Now Playing track is not equivalent between two sides. '
- '"%s" != "%s"' %
- (self.derived_bt_device.get_current_track_info(), expected_track)))
-
- def execute_media_play_pause_test_logic(self, command_sender, test_command):
- """Executes the test logic of the media command "play" or "pause".
-
- Steps:
- 1. Correct the playback state if needed.
- 2. Send a media passthrough command.
- 3. Verify that the playback state is changed from AVRCP TG and CT.
-
- Args:
- command_sender: a device controller sending the command.
- test_command: string, the media passthrough command for testing, either
- "play" or "pause".
-
- Raises:
- signals.TestError: raised if the test command is invalid.
- """
- # Checks if the test command is valid.
- if test_command not in [bt_constants.CMD_MEDIA_PLAY,
- bt_constants.CMD_MEDIA_PAUSE]:
- raise signals.TestError(
- 'Command "%s" is invalid. The test command should be "%s" or "%s".' %
- (test_command, bt_constants.CMD_MEDIA_PLAY,
- bt_constants.CMD_MEDIA_PAUSE))
-
- # Make sure the playback state is playing if testing the command "pause".
- if (self.pri_device.get_current_playback_state() !=
- bt_constants.STATE_PLAYING and
- test_command == bt_constants.CMD_MEDIA_PAUSE):
- self.pri_device.sl4a.bluetoothMediaHandleMediaCommandOnPhone(
- bt_constants.CMD_MEDIA_PLAY)
-
- # Makes sure Media info is the same between two sides.
- if self.is_android_bt_target_device:
- self.wait_for_media_info_sync()
- self.pri_device.log.info(
- 'Current playback state: %s' %
- self.pri_device.get_current_playback_state())
-
- expected_state = None
- if test_command == bt_constants.CMD_MEDIA_PLAY:
- command_sender.play()
- expected_state = bt_constants.STATE_PLAYING
- elif test_command == bt_constants.CMD_MEDIA_PAUSE:
- command_sender.pause()
- expected_state = bt_constants.STATE_PAUSED
-
- # Verify that the playback state is changed.
- self.pri_device.log.info('Expected playback state: %s' % expected_state)
- device_check_list = [self.pri_device]
- # Check the playback state from the android bt target device.
- if self.is_android_bt_target_device:
- device_check_list.append(self.derived_bt_device)
- for device in device_check_list:
- device.verify_playback_state_changed(
- expected_state=expected_state,
- exception=signals.TestFailure(
- 'Playback state is not changed to "%s" from the device "%s". '
- 'Current state: %s' %
- (expected_state, device.serial,
- device.get_current_playback_state())))
-
- def execute_skip_next_prev_test_logic(self, command_sender, test_command):
- """Executes the test logic of the media command "skipNext" or "skipPrev".
-
- Steps:
- 1. Correct the Now Playing track if needed.
- 2. Send a media passthrough command.
- 3. Verify that the Now Playing track is changed from AVRCP TG and CT.
-
- Args:
- command_sender: a device controller sending the command.
- test_command: string, the media passthrough command for testing, either
- "skipNext" or "skipPrev".
-
- Raises:
- signals.TestError: raised if the test command is invalid.
- """
- # Checks if the test command is valid.
- if test_command not in [bt_constants.CMD_MEDIA_SKIP_NEXT,
- bt_constants.CMD_MEDIA_SKIP_PREV]:
- raise signals.TestError(
- 'Command "%s" is invalid. The test command should be "%s" or "%s".' %
- (test_command, bt_constants.CMD_MEDIA_SKIP_NEXT,
- bt_constants.CMD_MEDIA_SKIP_PREV))
-
- # Make sure the track index is not 0 if testing the command "skipPrev".
- if (self.tracks.index(self.pri_device.get_current_track_info()) == 0
- and test_command == bt_constants.CMD_MEDIA_SKIP_PREV):
- self.pri_device.sl4a.bluetoothMediaHandleMediaCommandOnPhone(
- bt_constants.CMD_MEDIA_SKIP_NEXT)
-
- # Makes sure Media info is the same between two sides.
- if self.is_android_bt_target_device:
- self.wait_for_media_info_sync()
- current_track = self.pri_device.get_current_track_info()
- current_index = self.tracks.index(current_track)
- self.pri_device.log.info('Current track: %s' % current_track)
-
- expected_track = None
- if test_command == bt_constants.CMD_MEDIA_SKIP_NEXT:
- command_sender.track_next()
- # It will return to the first track by skipNext if now playing is the last
- # track.
- if current_index + 1 == len(self.tracks):
- expected_track = self.tracks[0]
- else:
- expected_track = self.tracks[current_index + 1]
- elif test_command == bt_constants.CMD_MEDIA_SKIP_PREV:
- command_sender.track_previous()
- expected_track = self.tracks[current_index - 1]
-
- # Verify that the now playing track is changed.
- self.pri_device.log.info('Expected track: %s' % expected_track)
- device_check_list = [self.pri_device]
- # Check the playback state from the android bt target device.
- if self.is_android_bt_target_device:
- device_check_list.append(self.derived_bt_device)
- for device in device_check_list:
- device.verify_current_track_changed(
- expected_track=expected_track,
- exception=signals.TestFailure(
- 'Now Playing track is not changed to "%s" from the device "%s". '
- 'Current track: %s' %
- (expected_track, device.serial, device.get_current_track_info())))
-
- def test_media_pause(self):
- """Tests the media pause from AVRCP Controller."""
- self.execute_media_play_pause_test_logic(
- command_sender=self.derived_bt_device,
- test_command=bt_constants.CMD_MEDIA_PAUSE)
-
- def test_media_play(self):
- """Tests the media play from AVRCP Controller."""
- self.execute_media_play_pause_test_logic(
- command_sender=self.derived_bt_device,
- test_command=bt_constants.CMD_MEDIA_PLAY)
-
- def test_media_skip_prev(self):
- """Tests the media skip prev from AVRCP Controller."""
- self.execute_skip_next_prev_test_logic(
- command_sender=self.derived_bt_device,
- test_command=bt_constants.CMD_MEDIA_SKIP_PREV)
-
- def test_media_skip_next(self):
- """Tests the media skip next from AVRCP Controller."""
- self.execute_skip_next_prev_test_logic(
- command_sender=self.derived_bt_device,
- test_command=bt_constants.CMD_MEDIA_SKIP_NEXT)
-
- def test_media_pause_from_phone(self):
- """Tests the media pause from AVRCP Target.
-
- Tests that Playback state of AVRCP Controller will be changed to paused when
- AVRCP Target sends the command "pause".
- """
- if not self.is_android_bt_target_device:
- signals.TestError('The test requires an android bt target device.')
-
- self.execute_media_play_pause_test_logic(
- command_sender=self.pri_device,
- test_command=bt_constants.CMD_MEDIA_PAUSE)
-
- def test_media_play_from_phone(self):
- """Tests the media play from AVRCP Target.
-
- Tests that Playback state of AVRCP Controller will be changed to playing
- when AVRCP Target sends the command "play".
- """
- if not self.is_android_bt_target_device:
- signals.TestError('The test requires an android bt target device.')
-
- self.execute_media_play_pause_test_logic(
- command_sender=self.pri_device,
- test_command=bt_constants.CMD_MEDIA_PLAY)
-
- def test_media_skip_prev_from_phone(self):
- """Tests the media skip prev from AVRCP Target.
-
- Tests that Now Playing track of AVRCP Controller will be changed to the
- previous track when AVRCP Target sends the command "skipPrev".
- """
- if not self.is_android_bt_target_device:
- signals.TestError('The test requires an android bt target device.')
-
- self.execute_skip_next_prev_test_logic(
- command_sender=self.pri_device,
- test_command=bt_constants.CMD_MEDIA_SKIP_PREV)
-
- def test_media_skip_next_from_phone(self):
- """Tests the media skip next from AVRCP Target.
-
- Tests that Now Playing track of AVRCP Controller will be changed to the next
- track when AVRCP Target sends the command "skipNext".
- """
- if not self.is_android_bt_target_device:
- signals.TestError('The test requires an android bt target device.')
-
- self.execute_skip_next_prev_test_logic(
- command_sender=self.pri_device,
- test_command=bt_constants.CMD_MEDIA_SKIP_NEXT)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/connectivity/bluetooth_connection_test.py b/blueberry/tests/connectivity/bluetooth_connection_test.py
deleted file mode 100644
index 767af38..0000000
--- a/blueberry/tests/connectivity/bluetooth_connection_test.py
+++ /dev/null
@@ -1,96 +0,0 @@
-"""Tests for Bluetooth connection with Android device and a Bluetooth device."""
-
-import time
-
-from mobly import test_runner
-from blueberry.utils import blueberry_base_test
-
-# Connection state change sleep time in seconds.
-CONNECTION_STATE_CHANGE_SLEEP_SEC = 5
-
-
-class BluetoothConnectionTest(blueberry_base_test.BlueberryBaseTest):
- """Test Class for Bluetooth connection testing.
-
- Attributes:
- primary_device: A primary device under test.
- derived_bt_device: A Bluetooth device which is used to connected to the
- primary device in the test.
- """
-
- def setup_class(self):
- super().setup_class()
- self.primary_device = self.android_devices[0]
- self.primary_device.init_setup()
-
- self.derived_bt_device = self.derived_bt_devices[0]
- self.derived_bt_device.factory_reset_bluetooth()
- self.mac_address = self.derived_bt_device.get_bluetooth_mac_address()
- self.derived_bt_device.activate_pairing_mode()
- self.primary_device.pair_and_connect_bluetooth(self.mac_address)
-
- def setup_test(self):
- super().setup_test()
- # Checks if A2DP and HSP profiles are connected.
- self.wait_for_a2dp_and_hsp_connection_state(connected=True)
- # Buffer between tests.
- time.sleep(CONNECTION_STATE_CHANGE_SLEEP_SEC)
-
- def wait_for_a2dp_and_hsp_connection_state(self, connected):
- """Asserts that A2DP and HSP connections are in the expected state.
-
- Args:
- connected: bool, True if the expected state is connected else False.
- """
- self.primary_device.wait_for_a2dp_connection_state(self.mac_address,
- connected)
- self.primary_device.wait_for_hsp_connection_state(self.mac_address,
- connected)
-
- def test_disconnect_and_connect(self):
- """Test for DUT disconnecting and then connecting to the remote device."""
- self.primary_device.log.info('Disconnecting the device "%s"...' %
- self.mac_address)
- self.primary_device.disconnect_bluetooth(self.mac_address)
- self.wait_for_a2dp_and_hsp_connection_state(connected=False)
- # Buffer time for connection state change.
- time.sleep(CONNECTION_STATE_CHANGE_SLEEP_SEC)
- self.primary_device.log.info('Connecting the device "%s"...' %
- self.mac_address)
- self.primary_device.connect_bluetooth(self.mac_address)
- self.wait_for_a2dp_and_hsp_connection_state(connected=True)
-
- def test_reconnect_when_enabling_bluetooth(self):
- """Test for DUT reconnecting to the remote device when Bluetooth enabled."""
- self.primary_device.log.info('Turning off Bluetooth...')
- self.primary_device.sl4a.bluetoothToggleState(False)
- self.primary_device.wait_for_bluetooth_toggle_state(enabled=False)
- self.primary_device.wait_for_disconnection_success(self.mac_address)
- time.sleep(CONNECTION_STATE_CHANGE_SLEEP_SEC)
- self.primary_device.log.info('Turning on Bluetooth...')
- self.primary_device.sl4a.bluetoothToggleState(True)
- self.primary_device.wait_for_bluetooth_toggle_state(enabled=True)
- self.primary_device.wait_for_connection_success(self.mac_address)
- self.wait_for_a2dp_and_hsp_connection_state(connected=True)
-
- def test_reconnect_when_connected_device_powered_on(self):
- """Test for the remote device reconnecting to DUT.
-
- Tests that DUT can be disconnected when the remoted device is powerd off,
- and then reconnected when the remote device is powered on.
- """
- self.primary_device.log.info(
- 'The connected device "%s" is being powered off...' % self.mac_address)
- self.derived_bt_device.power_off()
- self.primary_device.wait_for_disconnection_success(self.mac_address)
- self.wait_for_a2dp_and_hsp_connection_state(connected=False)
- time.sleep(CONNECTION_STATE_CHANGE_SLEEP_SEC)
- self.derived_bt_device.power_on()
- self.primary_device.log.info(
- 'The connected device "%s" is being powered on...' % self.mac_address)
- self.primary_device.wait_for_connection_success(self.mac_address)
- self.wait_for_a2dp_and_hsp_connection_state(connected=True)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/connectivity/bluetooth_latency_test.py b/blueberry/tests/connectivity/bluetooth_latency_test.py
deleted file mode 100644
index 0facbdc..0000000
--- a/blueberry/tests/connectivity/bluetooth_latency_test.py
+++ /dev/null
@@ -1,132 +0,0 @@
-# Lint as: python3
-"""Tests for blueberry.tests.bluetooth.bluetooth_latency."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import logging
-import math
-import random
-import string
-import time
-
-from mobly import asserts
-from mobly import test_runner
-from mobly.signals import TestAbortClass
-# Internal import
-from blueberry.utils import blueberry_base_test
-from blueberry.utils import bt_test_utils
-from blueberry.utils import metrics_utils
-# Internal import
-
-
-class BluetoothLatencyTest(blueberry_base_test.BlueberryBaseTest):
-
- @retry.logged_retry_on_exception(
- retry_intervals=retry.FuzzedExponentialIntervals(
- initial_delay_sec=2, factor=5, num_retries=5, max_delay_sec=300))
- def _measure_latency(self):
- """Measures the latency of data transfer over RFCOMM.
-
- Sends data from the client device that is read by the server device.
- Calculates the latency of the transfer.
-
- Returns:
- The latency of the transfer milliseconds.
- """
-
- # Generates a random message to transfer
- message = (''.join(
- random.choice(string.ascii_letters + string.digits) for _ in range(6)))
- start_time = time.time()
- write_read_successful = bt_test_utils.write_read_verify_data_sl4a(
- self.phone, self.derived_bt_device, message, False)
- end_time = time.time()
- asserts.assert_true(write_read_successful, 'Failed to send/receive message')
- return (end_time - start_time) * 1000
-
- def setup_class(self):
- """Standard Mobly setup class."""
- super(BluetoothLatencyTest, self).setup_class()
- if len(self.android_devices) < 2:
- raise TestAbortClass(
- 'Not enough android phones detected (need at least two)')
- self.phone = self.android_devices[0]
- self.phone.init_setup()
- self.phone.sl4a_setup()
-
- # We treat the secondary phone as a derived_bt_device in order for the
- # generic script to work with this android phone properly. Data will be sent
- # from first phone to the second phone.
- self.derived_bt_device = self.android_devices[1]
- self.derived_bt_device.init_setup()
- self.derived_bt_device.sl4a_setup()
- self.set_btsnooplogmode_full(self.phone)
- self.set_btsnooplogmode_full(self.derived_bt_device)
-
- self.metrics = (
- metrics_utils.BluetoothMetricLogger(
- metrics_pb2.BluetoothDataTestResult()))
- self.metrics.add_primary_device_metrics(self.phone)
- self.metrics.add_connected_device_metrics(self.derived_bt_device)
-
- self.data_transfer_type = metrics_pb2.BluetoothDataTestResult.RFCOMM
- self.iterations = int(self.user_params.get('iterations', 300))
- logging.info('Running Bluetooth latency test %s times.', self.iterations)
- logging.info('Successfully found required devices.')
-
- def setup_test(self):
- """Setup for bluetooth latency test."""
- logging.info('Setup Test for test_bluetooth_latency')
- super(BluetoothLatencyTest, self).setup_test()
- asserts.assert_true(self.phone.connect_with_rfcomm(self.derived_bt_device),
- 'Failed to establish RFCOMM connection')
-
- def test_bluetooth_latency(self):
- """Tests the latency for a data transfer over RFCOMM."""
-
- metrics = {}
- latency_list = []
-
- for _ in range(self.iterations):
- latency_list.append(self._measure_latency())
-
- metrics['data_transfer_protocol'] = self.data_transfer_type
- metrics['data_latency_min_millis'] = int(min(latency_list))
- metrics['data_latency_max_millis'] = int(max(latency_list))
- metrics['data_latency_avg_millis'] = int(
- math.fsum(latency_list) / float(len(latency_list)))
- logging.info('Latency: %s', metrics)
-
- asserts.assert_true(metrics['data_latency_min_millis'] > 0,
- 'Minimum latency must be greater than 0!')
- self.metrics.add_test_metrics(metrics)
- for metric in metrics:
- self.record_data({
- 'Test Name': 'test_bluetooth_latency',
- 'sponge_properties': {
- metric: metrics[metric],
- }
- })
-
- def teardown_class(self):
- logging.info('Factory resetting Bluetooth on devices.')
- self.phone.sl4a.bluetoothSocketConnStop()
- self.derived_bt_device.sl4a.bluetoothSocketConnStop()
- self.phone.factory_reset_bluetooth()
- self.derived_bt_device.factory_reset_bluetooth()
- super(BluetoothLatencyTest, self).teardown_class()
- self.record_data({
- 'Test Name': 'test_bluetooth_latency',
- 'sponge_properties': {
- 'proto_ascii':
- self.metrics.proto_message_to_ascii(),
- 'primary_device_build':
- self.phone.get_device_info()['android_release_id']
- }
- })
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/connectivity/bluetooth_pairing_test.py b/blueberry/tests/connectivity/bluetooth_pairing_test.py
deleted file mode 100644
index f3c1770..0000000
--- a/blueberry/tests/connectivity/bluetooth_pairing_test.py
+++ /dev/null
@@ -1,81 +0,0 @@
-"""Tests for blueberry.tests.bluetooth_pairing."""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import logging
-
-from mobly import test_runner
-from blueberry.utils import blueberry_base_test
-
-
-class BluetoothPairingTest(blueberry_base_test.BlueberryBaseTest):
- """Test Class for Bluetooth Pairing Test.
-
- Test will reset the bluetooth settings on the phone and attempt to pair
- with the derived_bt_device specified in the configuration file.
- """
-
- def setup_class(self):
- """Standard Mobly setup class."""
- super(BluetoothPairingTest, self).setup_class()
- # Adds a use case that derived_bt_device initiates a pairing request to
- # primary_device. Enable this case if allow_pairing_reverse is 1.
- self.allow_pairing_reverse = int(self.user_params.get(
- 'allow_pairing_reverse', 0))
-
- if self.android_devices:
- self.primary_device = self.android_devices[0]
- self.primary_device.init_setup()
- self.primary_device.sl4a_setup()
-
- if len(self.android_devices) > 1 and not self.derived_bt_devices:
- # In the case of pairing phone to phone, we need to treat the
- # secondary phone as a derived_bt_device in order for the generic script
- # to work with this android phone properly.
- self.derived_bt_device = self.android_devices[1]
- self.derived_bt_device.init_setup()
- self.derived_bt_device.sl4a_setup()
- else:
- self.derived_bt_device = self.derived_bt_devices[0]
- self.derived_bt_device.factory_reset_bluetooth()
- else:
- # In the case of pairing mock to mock, at least 2 derived_bt_device is
- # required. The first derived_bt_device is treated as primary_device.
- self.primary_device = self.derived_bt_devices[0]
- self.primary_device.init_setup()
- self.derived_bt_device = self.derived_bt_devices[1]
- self.derived_bt_device.factory_reset_bluetooth()
-
- def setup_test(self):
- """Setup for pairing test."""
- logging.info('Setup Test for test_pair_and_bond')
- super(BluetoothPairingTest, self).setup_test()
-
- def test_pair_and_bond(self):
- """Test for pairing and bonding a phone with a bluetooth device.
-
- Initiates pairing from the phone and checks for 20 seconds that
- the device is connected.
- """
- device_list = [(self.primary_device, self.derived_bt_device)]
- if self.allow_pairing_reverse:
- device_list.append((self.derived_bt_device, self.primary_device))
- for initiator, receiver in device_list:
- # get mac address of device to pair with
- mac_address = receiver.get_bluetooth_mac_address()
- logging.info('Receiver BT MAC Address: %s', mac_address)
- # put device into pairing mode
- receiver.activate_pairing_mode()
- # initiate pairing from initiator
- initiator.set_target(receiver)
- initiator.pair_and_connect_bluetooth(mac_address)
- if self.allow_pairing_reverse and initiator != self.derived_bt_device:
- logging.info('===== Reversing Pairing =====')
- # Resets Bluetooth status for two sides.
- initiator.factory_reset_bluetooth()
- receiver.factory_reset_bluetooth()
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/connectivity/bluetooth_throughput_test.py b/blueberry/tests/connectivity/bluetooth_throughput_test.py
deleted file mode 100644
index 79ac2e2..0000000
--- a/blueberry/tests/connectivity/bluetooth_throughput_test.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# Lint as: python3
-"""Tests for blueberry.tests.bluetooth.bluetooth_throughput."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import logging
-import math
-
-from mobly import asserts
-from mobly import test_runner
-from mobly.controllers.android_device_lib.jsonrpc_client_base import ApiError
-from mobly.signals import TestAbortClass
-# Internal import
-from blueberry.utils import blueberry_base_test
-from blueberry.utils import metrics_utils
-# Internal import
-
-
-class BluetoothThroughputTest(blueberry_base_test.BlueberryBaseTest):
-
- @retry.logged_retry_on_exception(
- retry_intervals=retry.FuzzedExponentialIntervals(
- initial_delay_sec=2, factor=5, num_retries=5, max_delay_sec=300))
- def _measure_throughput(self, num_of_buffers, buffer_size):
- """Measures the throughput of a data transfer.
-
- Sends data from the client device that is read by the server device.
- Calculates the throughput for the transfer.
-
- Args:
- num_of_buffers: An integer value designating the number of buffers
- to be sent.
- buffer_size: An integer value designating the size of each buffer,
- in bytes.
-
- Returns:
- The throughput of the transfer in bytes per second.
- """
-
- # TODO(user): Need to fix throughput send/receive methods
- (self.phone.sl4a
- .bluetoothConnectionThroughputSend(num_of_buffers, buffer_size))
-
- throughput = (self.derived_bt_device.sl4a
- .bluetoothConnectionThroughputRead(num_of_buffers,
- buffer_size))
- return throughput
-
- def _throughput_test(self, buffer_size, test_name):
- logging.info('throughput test with buffer_size: %d and testname: %s',
- buffer_size, test_name)
- metrics = {}
- throughput_list = []
- num_of_buffers = 1
- for _ in range(self.iterations):
- throughput = self._measure_throughput(num_of_buffers, buffer_size)
- logging.info('Throughput: %d bytes-per-sec', throughput)
- throughput_list.append(throughput)
-
- metrics['data_transfer_protocol'] = self.data_transfer_type
- metrics['data_packet_size'] = buffer_size
- metrics['data_throughput_min_bytes_per_second'] = int(
- min(throughput_list))
- metrics['data_throughput_max_bytes_per_second'] = int(
- max(throughput_list))
- metrics['data_throughput_avg_bytes_per_second'] = int(
- math.fsum(throughput_list) / float(len(throughput_list)))
-
- logging.info('Throughput at large buffer: %s', metrics)
-
- asserts.assert_true(metrics['data_throughput_min_bytes_per_second'] > 0,
- 'Minimum throughput must be greater than 0!')
-
- self.metrics.add_test_metrics(metrics)
- for metric in metrics:
- self.record_data({
- 'Test Name': test_name,
- 'sponge_properties': {
- metric: metrics[metric],
- }
- })
- self.record_data({
- 'Test Name': test_name,
- 'sponge_properties': {
- 'proto_ascii':
- self.metrics.proto_message_to_ascii(),
- 'primary_device_build':
- self.phone.get_device_info()['android_release_id']
- }
- })
-
- def setup_class(self):
- """Standard Mobly setup class."""
- super(BluetoothThroughputTest, self).setup_class()
- if len(self.android_devices) < 2:
- raise TestAbortClass(
- 'Not enough android phones detected (need at least two)')
- self.phone = self.android_devices[0]
-
- # We treat the secondary phone as a derived_bt_device in order for the
- # generic script to work with this android phone properly. Data will be sent
- # from first phone to the second phone.
- self.derived_bt_device = self.android_devices[1]
- self.phone.init_setup()
- self.derived_bt_device.init_setup()
- self.phone.sl4a_setup()
- self.derived_bt_device.sl4a_setup()
- self.set_btsnooplogmode_full(self.phone)
- self.set_btsnooplogmode_full(self.derived_bt_device)
-
- self.metrics = (
- metrics_utils.BluetoothMetricLogger(
- metrics_pb2.BluetoothDataTestResult()))
- self.metrics.add_primary_device_metrics(self.phone)
- self.metrics.add_connected_device_metrics(self.derived_bt_device)
-
- self.data_transfer_type = metrics_pb2.BluetoothDataTestResult.RFCOMM
- self.iterations = int(self.user_params.get('iterations', 300))
- logging.info('Running Bluetooth throughput test %s times.', self.iterations)
- logging.info('Successfully found required devices.')
-
- def setup_test(self):
- """Setup for bluetooth latency test."""
- logging.info('Setup Test for test_bluetooth_throughput')
- super(BluetoothThroughputTest, self).setup_test()
- asserts.assert_true(self.phone.connect_with_rfcomm(self.derived_bt_device),
- 'Failed to establish RFCOMM connection')
-
- def test_bluetooth_throughput_large_buffer(self):
- """Tests the throughput with large buffer size.
-
- Tests the throughput over a series of data transfers with large buffer size.
- """
- large_buffer_size = 300
- test_name = 'test_bluetooth_throughput_large_buffer'
- self._throughput_test(large_buffer_size, test_name)
-
- def test_bluetooth_throughput_medium_buffer(self):
- """Tests the throughput with medium buffer size.
-
- Tests the throughput over a series of data transfers with medium buffer
- size.
- """
- medium_buffer_size = 100
- test_name = 'test_bluetooth_throughput_medium_buffer'
- self._throughput_test(medium_buffer_size, test_name)
-
- def test_bluetooth_throughput_small_buffer(self):
- """Tests the throughput with small buffer size.
-
- Tests the throughput over a series of data transfers with small buffer size.
- """
- small_buffer_size = 10
- test_name = 'test_bluetooth_throughput_small_buffer'
- self._throughput_test(small_buffer_size, test_name)
-
- def test_maximum_buffer_size(self):
- """Calculates the maximum allowed buffer size for one packet."""
- current_buffer_size = 300
- throughput = -1
- num_of_buffers = 1
- while True:
- logging.info('Trying buffer size %d', current_buffer_size)
- try:
- throughput = self._measure_throughput(
- num_of_buffers, current_buffer_size)
- logging.info('The throughput is %d at buffer size of %d', throughput,
- current_buffer_size)
- except ApiError:
- maximum_buffer_size = current_buffer_size - 1
- logging.info('Max buffer size: %d bytes', maximum_buffer_size)
- logging.info('Max throughput: %d bytes-per-second', throughput)
- self.record_data({
- 'Test Name': 'test_maximum_buffer_size',
- 'sponge_properties': {
- 'maximum_buffer_size': maximum_buffer_size
- }
- })
- return True
- current_buffer_size += 1
-
- def teardown_test(self):
- self.phone.sl4a.bluetoothSocketConnStop()
- self.derived_bt_device.sl4a.bluetoothSocketConnStop()
-
- def teardown_class(self):
- self.phone.factory_reset_bluetooth()
- self.derived_bt_device.factory_reset_bluetooth()
- logging.info('Factory resetting Bluetooth on devices.')
- super(BluetoothThroughputTest, self).teardown_class()
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/cert/adb.py b/blueberry/tests/gd/cert/adb.py
deleted file mode 100644
index 10d0110..0000000
--- a/blueberry/tests/gd/cert/adb.py
+++ /dev/null
@@ -1,156 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-import encodings
-import logging
-import re
-import shlex
-import shutil
-
-from mobly.controllers.android_device_lib.adb import AdbProxy
-
-ROOT_USER_ID = '0'
-SHELL_USER_ID = '2000'
-UTF_8 = encodings.utf_8.getregentry().name
-
-
-class BlueberryAdbProxy(AdbProxy):
- """Proxy class for ADB.
-
- For syntactic reasons, the '-' in adb commands need to be replaced with
- '_'. Can directly execute adb commands on an object:
- >> adb = BlueberryAdbProxy(<serial>)
- >> adb.start_server()
- >> adb.devices() # will return the console output of "adb devices".
- """
-
- def __init__(self, serial="", ssh_connection=None):
- """Construct an instance of AdbProxy.
-
- Args:
- serial: str serial number of Android device from `adb devices`
- ssh_connection: SshConnection instance if the Android device is
- connected to a remote host that we can reach via SSH.
- """
- super().__init__(serial)
- self._server_local_port = None
- adb_path = shutil.which('adb')
- adb_cmd = [shlex.quote(adb_path)]
- if serial:
- adb_cmd.append("-s %s" % serial)
- if ssh_connection is not None:
- # Kill all existing adb processes on the remote host (if any)
- # Note that if there are none, then pkill exits with non-zero status
- ssh_connection.run("pkill adb", ignore_status=True)
- # Copy over the adb binary to a temp dir
- temp_dir = ssh_connection.run("mktemp -d").stdout.strip()
- ssh_connection.send_file(adb_path, temp_dir)
- # Start up a new adb server running as root from the copied binary.
- remote_adb_cmd = "%s/adb %s root" % (temp_dir, "-s %s" % serial if serial else "")
- ssh_connection.run(remote_adb_cmd)
- # Proxy a local port to the adb server port
- local_port = ssh_connection.create_ssh_tunnel(5037)
- self._server_local_port = local_port
-
- if self._server_local_port:
- adb_cmd.append("-P %d" % local_port)
- self.adb_str = " ".join(adb_cmd)
- self._ssh_connection = ssh_connection
-
- def get_user_id(self):
- """Returns the adb user. Either 2000 (shell) or 0 (root)."""
- return self.shell('id -u').decode(UTF_8).rstrip()
-
- def is_root(self, user_id=None):
- """Checks if the user is root.
-
- Args:
- user_id: if supplied, the id to check against.
- Returns:
- True if the user is root. False otherwise.
- """
- if not user_id:
- user_id = self.get_user_id()
- return user_id == ROOT_USER_ID
-
- def ensure_root(self):
- """Ensures the user is root after making this call.
-
- Note that this will still fail if the device is a user build, as root
- is not accessible from a user build.
-
- Returns:
- False if the device is a user build. True otherwise.
- """
- self.ensure_user(ROOT_USER_ID)
- return self.is_root()
-
- def ensure_user(self, user_id=SHELL_USER_ID):
- """Ensures the user is set to the given user.
-
- Args:
- user_id: The id of the user.
- """
- if self.is_root(user_id):
- self.root()
- else:
- self.unroot()
- self.wait_for_device()
- return self.get_user_id() == user_id
-
- def tcp_forward(self, host_port, device_port):
- """Starts tcp forwarding from localhost to this android device.
-
- Args:
- host_port: Port number to use on localhost
- device_port: Port number to use on the android device.
-
- Returns:
- Forwarded port on host as int or command output string on error
- """
- if self._ssh_connection:
- # We have to hop through a remote host first.
- # 1) Find some free port on the remote host's localhost
- # 2) Setup forwarding between that remote port and the requested
- # device port
- remote_port = self._ssh_connection.find_free_port()
- host_port = self._ssh_connection.create_ssh_tunnel(remote_port, local_port=host_port)
- output = self.forward(["tcp:%d" % host_port, "tcp:%d" % device_port])
- # If hinted_port is 0, the output will be the selected port.
- # Otherwise, there will be no output upon successfully
- # forwarding the hinted port.
- if not output:
- return host_port
- try:
- output_int = int(output)
- except ValueError:
- return output
- return output_int
-
- def remove_tcp_forward(self, host_port):
- """Stop tcp forwarding a port from localhost to this android device.
-
- Args:
- host_port: Port number to use on localhost
- """
- if self._ssh_connection:
- remote_port = self._ssh_connection.close_ssh_tunnel(host_port)
- if remote_port is None:
- logging.warning("Cannot close unknown forwarded tcp port: %d", host_port)
- return
- # The actual port we need to disable via adb is on the remote host.
- host_port = remote_port
- self.forward(["--remove", "tcp:%d" % host_port])
diff --git a/blueberry/tests/gd/cert/asserts.py b/blueberry/tests/gd/cert/asserts.py
deleted file mode 100644
index 0be8849..0000000
--- a/blueberry/tests/gd/cert/asserts.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2018 - 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.
-
-from mobly.asserts import *
-
-
-# Have an instance of unittest.TestCase so we could reuse some logic from
-# python's own unittest.
-# _ProxyTest is required because py2 does not allow instantiating
-# unittest.TestCase directly.
-class _ProxyTest(unittest.TestCase):
-
- def runTest(self):
- pass
-
-
-_pyunit_proxy = _ProxyTest()
-
-
-def assert_almost_equal(first, second, places=7, msg=None, delta=None, extras=None):
- """
- Assert FIRST to be within +/- DELTA to SECOND, otherwise fail the
- test.
- :param first: The first argument, LHS
- :param second: The second argument, RHS
- :param places: For floating points, how many decimal places to look into
- :param msg: Message to display on failure
- :param delta: The +/- first and second could be apart from each other
- :param extras: Extra object passed to test failure handler
- :return:
- """
- my_msg = None
- try:
- if delta:
- _pyunit_proxy.assertAlmostEqual(first, second, msg=msg, delta=delta)
- else:
- _pyunit_proxy.assertAlmostEqual(first, second, places=places, msg=msg)
- except Exception as e:
- my_msg = str(e)
- if msg:
- my_msg = "%s %s" % (my_msg, msg)
- # This is a hack to remove the stacktrace produced by the above exception.
- if my_msg is not None:
- fail(my_msg, extras=extras)
diff --git a/blueberry/tests/gd/cert/cert_self_test_blueberry.py b/blueberry/tests/gd/cert/cert_self_test_blueberry.py
deleted file mode 100644
index 5a0a1cf..0000000
--- a/blueberry/tests/gd/cert/cert_self_test_blueberry.py
+++ /dev/null
@@ -1,281 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert.metadata import metadata
-
-from mobly import asserts
-from mobly import signals
-from mobly import test_runner
-from mobly import base_test
-
-from cert.cert_self_test_lib import *
-
-
-class CertSelfTestBb(base_test.BaseTestClass):
-
- def setup_test(self):
- return True
-
- def teardown_test(self):
- return True
-
- def test_assert_occurs_at_least_passes(self):
- test_assert_occurs_at_least_passes_core()
-
- def test_assert_occurs_passes(self):
- test_assert_occurs_passes_core()
-
- def test_assert_occurs_fails(self):
- test_assert_occurs_fails_core()
-
- def test_assert_occurs_at_most_passes(self):
- test_assert_occurs_at_most_passes_core()
-
- def test_assert_occurs_at_most_fails(self):
- test_assert_occurs_at_most_fails_core()
-
- def test_skip_a_test(self):
- test_skip_a_test_core()
-
- def test_nested_packets(self):
- test_nested_packets_core()
-
- def test_l2cap_config_options(self):
- test_l2cap_config_options_core()
-
- def test_assertThat_boolean_success(self):
- test_assertThat_boolean_success_core()
-
- def test_assertThat_boolean_falseIsTrue(self):
- test_assertThat_boolean_falseIsTrue_core()
-
- def test_assertThat_boolean_trueIsFalse(self):
- test_assertThat_boolean_trueIsFalse_core()
-
- def test_assertThat_object_success(self):
- test_assertThat_object_success_core()
-
- def test_assertThat_object_isEqualToFails(self):
- test_assertThat_object_isEqualToFails_core()
-
- def test_assertThat_object_isNotEqualToFails(self):
- test_assertThat_object_isNotEqualToFails_core()
-
- def test_assertThat_object_isNoneFails(self):
- test_assertThat_object_isNoneFails_core()
-
- def test_assertThat_object_isNotNoneFails(self):
- test_assertThat_object_isNotNoneFails_core()
-
- def test_assertThat_eventStream_emits_passes(self):
- test_assertThat_eventStream_emits_passes_core()
-
- def test_assertThat_eventStream_emits_then_passes(self):
- test_assertThat_eventStream_emits_then_passes_core()
-
- def test_assertThat_eventStream_emits_fails(self):
- test_assertThat_eventStream_emits_fails_core()
-
- def test_assertThat_eventStream_emits_then_fails(self):
- test_assertThat_eventStream_emits_then_fails_core()
-
- def test_assertThat_eventStream_emitsInOrder_passes(self):
- test_assertThat_eventStream_emitsInOrder_passes_core()
-
- def test_assertThat_eventStream_emitsInAnyOrder_passes(self):
- test_assertThat_eventStream_emitsInAnyOrder_passes_core()
-
- def test_assertThat_eventStream_emitsInOrder_fails(self):
- test_assertThat_eventStream_emitsInOrder_fails_core()
-
- def test_assertThat_eventStream_emitsInAnyOrder_fails(self):
- test_assertThat_eventStream_emitsInAnyOrder_fails_core()
-
- def test_assertThat_emitsNone_passes(self):
- test_assertThat_emitsNone_passes_core()
-
- def test_assertThat_emitsNone_passes_after_1_second(self):
- test_assertThat_emitsNone_passes_after_1_second_core()
-
- def test_assertThat_emitsNone_fails(self):
- test_assertThat_emitsNone_fails_core()
-
- def test_assertThat_emitsNone_zero_passes(self):
- test_assertThat_emitsNone_zero_passes_core()
-
- def test_assertThat_emitsNone_zero_passes_after_one_second(self):
- test_assertThat_emitsNone_zero_passes_after_one_second_core()
-
- def test_assertThat_emitsNone_zero_fails(self):
- test_assertThat_emitsNone_zero_fails_core()
-
- def test_filtering_event_stream_none_filter_function(self):
- test_filtering_event_stream_none_filter_function_core()
-
- def test_metadata_empty(self):
-
- @metadata()
- def simple_pass_test(arg):
- pass
-
- try:
- simple_pass_test(1)
- except signals.TestFailure:
- pass
- except Exception as e:
- asserts.fail("@metadata() should only raise signals.TestFailure, "
- "but raised %s with msg %s instead" % (e.__class__.__name__, str(e)))
- else:
- asserts.fail("@metadata() should not work")
-
- def test_metadata_empty_no_function_call(self):
-
- @metadata
- def simple_pass_test(arg):
- pass
-
- try:
- simple_pass_test(1)
- except signals.TestFailure:
- pass
- except Exception as e:
- asserts.fail("@metadata should only raise signals.TestFailure, "
- "but raised %s with msg %s instead" % (e.__class__.__name__, str(e)))
- else:
- asserts.fail("@metadata should not work")
-
- def test_metadata_pts_missing_id(self):
-
- @metadata(pts_test_name="Hello world")
- def simple_pass_test(arg):
- pass
-
- try:
- simple_pass_test(1)
- except signals.TestFailure:
- pass
- except Exception as e:
- asserts.fail("should only raise signals.TestFailure, "
- "but raised %s with msg %s instead" % (e.__class__.__name__, str(e)))
- else:
- asserts.fail("missing pts_test_id should not work")
-
- def test_metadata_pts_missing_name(self):
-
- @metadata(pts_test_id="A/B/C")
- def simple_pass_test(arg):
- pass
-
- try:
- simple_pass_test(1)
- except signals.TestFailure:
- pass
- except Exception as e:
- asserts.fail("should only raise signals.TestFailure, "
- "but raised %s with msg %s instead" % (e.__class__.__name__, str(e)))
- else:
- asserts.fail("missing pts_test_name should not work")
-
- def test_metadata_pts_test_id_and_description(self):
-
- @metadata(pts_test_id="A/B/C", pts_test_name="Hello world")
- def simple_pass_test(arg):
- pass
-
- try:
- simple_pass_test(1)
- except signals.TestPass as e:
- asserts.assert_true("pts_test_id" in e.extras, msg=("pts_test_id not in extra: %s" % str(e.extras)))
- asserts.assert_equal(e.extras["pts_test_id"], "A/B/C")
- asserts.assert_true("pts_test_name" in e.extras, msg=("pts_test_name not in extra: %s" % str(e.extras)))
- asserts.assert_equal(e.extras["pts_test_name"], "Hello world")
- else:
- asserts.fail("Must throw an exception using @metadata decorator")
-
- def test_metadata_test_with_exception_stacktrace(self):
-
- @metadata(pts_test_id="A/B/C", pts_test_name="Hello world")
- def simple_fail_test(failure_argument):
- raise ValueError(failure_argument)
-
- try:
- simple_fail_test("BEEFBEEF")
- except signals.TestError as e:
- asserts.assert_true("pts_test_id" in e.extras, msg=("pts_test_id not in extra: %s" % str(e.extras)))
- asserts.assert_equal(e.extras["pts_test_id"], "A/B/C")
- asserts.assert_true("pts_test_name" in e.extras, msg=("pts_test_name not in extra: %s" % str(e.extras)))
- asserts.assert_equal(e.extras["pts_test_name"], "Hello world")
- trace_str = traceback.format_exc()
- asserts.assert_true(
- "raise ValueError(failure_argument)" in trace_str,
- msg="Failed test method not in error stack trace: %s" % trace_str)
- else:
- asserts.fail("Must throw an exception using @metadata decorator")
-
- def test_fluent_behavior_simple(self):
- test_fluent_behavior_simple_core()
-
- def test_fluent_behavior__then_single__captures_one(self):
- test_fluent_behavior__then_single__captures_one_core()
-
- def test_fluent_behavior__then_times__captures_all(self):
- test_fluent_behavior__then_times__captures_all_core()
-
- def test_fluent_behavior__always__captures_all(self):
- test_fluent_behavior__always__captures_all_core()
-
- def test_fluent_behavior__matcher__captures_relevant(self):
- test_fluent_behavior__matcher__captures_relevant_core()
-
- def test_fluent_behavior__then_repeated__captures_relevant(self):
- test_fluent_behavior__then_repeated__captures_relevant_core()
-
- def test_fluent_behavior__fallback__captures_relevant(self):
- test_fluent_behavior__fallback__captures_relevant_core()
-
- def test_fluent_behavior__default_unhandled_crash(self):
- test_fluent_behavior__default_unhandled_crash_core()
-
- def test_fluent_behavior__set_default_works(self):
- test_fluent_behavior__set_default_works_core()
-
- def test_fluent_behavior__wait_until_done(self):
- test_fluent_behavior__wait_until_done_core()
-
- def test_fluent_behavior__wait_until_done_different_lambda(self):
- test_fluent_behavior__wait_until_done_different_lambda_core()
-
- def test_fluent_behavior__wait_until_done_anything(self):
- test_fluent_behavior__wait_until_done_anything_core()
-
- def test_fluent_behavior__wait_until_done_not_happened(self):
- test_fluent_behavior__wait_until_done_not_happened_core()
-
- def test_fluent_behavior__wait_until_done_with_default(self):
- test_fluent_behavior__wait_until_done_with_default_core()
-
- def test_fluent_behavior__wait_until_done_two_events_AA(self):
- test_fluent_behavior__wait_until_done_two_events_AA_core()
-
- def test_fluent_behavior__wait_until_done_two_events_AB(self):
- test_fluent_behavior__wait_until_done_two_events_AB_core()
-
- def test_fluent_behavior__wait_until_done_only_one_event_is_done(self):
- test_fluent_behavior__wait_until_done_only_one_event_is_done_core()
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/cert/context.py b/blueberry/tests/gd/cert/context.py
deleted file mode 100644
index 1e592ab..0000000
--- a/blueberry/tests/gd/cert/context.py
+++ /dev/null
@@ -1,224 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2018 - 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.
-
-import enum
-import logging
-import os
-
-
-class ContextLevel(enum.IntEnum):
- ROOT = 0
- TESTCLASS = 1
- TESTCASE = 2
-
-
-def get_current_context(depth=None):
- """Get the current test context at the specified depth.
- Pulls the most recently created context, with a level at or below the given
- depth, from the _contexts stack.
-
- Args:
- depth: The desired context level. For example, the TESTCLASS level would
- yield the current test class context, even if the test is currently
- within a test case.
-
- Returns: An instance of TestContext.
- """
- if depth is None:
- return _contexts[-1]
- return _contexts[min(depth, len(_contexts) - 1)]
-
-
-def append_test_context(test_class_name, test_name):
- """Add test-specific context to the _contexts stack.
- A test should should call append_test_context() at test start and
- pop_test_context() upon test end.
-
- Args:
- test_class_name: name of the test class.
- test_name: name of the test.
- """
- if _contexts:
- _contexts.append(TestCaseContext(test_class_name, test_name))
-
-
-def pop_test_context():
- """Remove the latest test-specific context from the _contexts stack.
- A test should should call append_test_context() at test start and
- pop_test_context() upon test end.
- """
- if _contexts:
- _contexts.pop()
-
-
-class TestContext(object):
- """An object representing the current context in which a test is executing.
-
- The context encodes the current state of the test runner with respect to a
- particular scenario in which code is being executed. For example, if some
- code is being executed as part of a test case, then the context should
- encode information about that test case such as its name or enclosing
- class.
-
- The subcontext specifies a relative path in which certain outputs,
- e.g. logcat, should be kept for the given context.
-
- The full output path is given by
- <base_output_path>/<context_dir>/<subcontext>.
-
- Attributes:
- _base_output_paths: a dictionary mapping a logger's name to its base
- output path
- _subcontexts: a dictionary mapping a logger's name to its
- subcontext-level output directory
- """
-
- _base_output_paths = {}
- _subcontexts = {}
-
- def get_base_output_path(self, log_name=None):
- """Gets the base output path for this logger.
-
- The base output path is interpreted as the reporting root for the
- entire test runner.
-
- If a path has been added with add_base_output_path, it is returned.
- Otherwise, a default is determined by _get_default_base_output_path().
-
- Args:
- log_name: The name of the logger.
-
- Returns:
- The output path.
- """
- if log_name in self._base_output_paths:
- return self._base_output_paths[log_name]
- return self._get_default_base_output_path()
-
- def get_subcontext(self, log_name=None):
- """Gets the subcontext for this logger.
-
- The subcontext is interpreted as the directory, relative to the
- context-level path, where all outputs of the given logger are stored.
-
- If a path has been added with add_subcontext, it is returned.
- Otherwise, the empty string is returned.
-
- Args:
- log_name: The name of the logger.
-
- Returns:
- The output path.
- """
- return self._subcontexts.get(log_name, '')
-
- def get_full_output_path(self, log_name=None):
- """Gets the full output path for this context.
-
- The full path represents the absolute path to the output directory,
- as given by <base_output_path>/<context_dir>/<subcontext>
-
- Args:
- log_name: The name of the logger. Used to specify the base output
- path and the subcontext.
-
- Returns:
- The output path.
- """
-
- path = os.path.join(
- self.get_base_output_path(log_name), self._get_default_context_dir(), self.get_subcontext(log_name))
- os.makedirs(path, exist_ok=True)
- return path
-
- def _get_default_base_output_path(self):
- """Gets the default base output path.
-
- This will attempt to use logging path set up in the global
- logger.
-
- Returns:
- The logging path.
-
- Raises:
- EnvironmentError: If logger has not been initialized.
- """
- try:
- return logging.log_path
- except AttributeError as e:
- raise EnvironmentError('The Mobly logger has not been set up and'
- ' "base_output_path" has not been set.') from e
-
- def _get_default_context_dir(self):
- """Gets the default output directory for this context."""
- raise NotImplementedError()
-
-
-class RootContext(TestContext):
- """A TestContext that represents a test run."""
-
- @property
- def identifier(self):
- return 'root'
-
- def _get_default_context_dir(self):
- """Gets the default output directory for this context.
-
- Logs at the root level context are placed directly in the base level
- directory, so no context-level path exists."""
- return ''
-
-
-class TestCaseContext(TestContext):
- """A TestContext that represents a test case.
-
- Attributes:
- test_case: the name of the test case.
- test_class: the name of the test class.
- """
-
- def __init__(self, test_class, test_case):
- """Initializes a TestCaseContext for the given test case.
-
- Args:
- test_class: test-class name.
- test_case: test name.
- """
- self.test_class = test_class
- self.test_case = test_case
-
- @property
- def test_case_name(self):
- return self.test_case
-
- @property
- def test_class_name(self):
- return self.test_class
-
- @property
- def identifier(self):
- return '%s.%s' % (self.test_class_name, self.test_case_name)
-
- def _get_default_context_dir(self):
- """Gets the default output directory for this context.
-
- For TestCaseContexts, this will be the name of the test itself.
- """
- return self.test_case_name
-
-
-# stack for keeping track of the current test context
-_contexts = [RootContext()]
diff --git a/blueberry/tests/gd/cert/gd_base_test.py b/blueberry/tests/gd/cert/gd_base_test.py
deleted file mode 100644
index ee1f6be..0000000
--- a/blueberry/tests/gd/cert/gd_base_test.py
+++ /dev/null
@@ -1,223 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-import importlib
-import logging
-import os
-import traceback
-
-from functools import wraps
-from grpc import RpcError
-
-from cert.gd_base_test_lib import setup_rootcanal
-from cert.gd_base_test_lib import teardown_rootcanal
-from cert.gd_base_test_lib import dump_crashes_core
-from cert.gd_device_lib import generate_coverage_report_for_host
-
-from facade import rootservice_pb2 as facade_rootservice
-
-from blueberry.tests.gd.cert.context import append_test_context, get_current_context, pop_test_context, ContextLevel
-from blueberry.tests.gd.cert.gd_device import MOBLY_CONTROLLER_CONFIG_NAME as CONTROLLER_CONFIG_NAME
-from blueberry.tests.gd.cert.tracelogger import TraceLogger
-
-from mobly import asserts, signals
-from mobly import base_test
-
-
-class GdBaseTestClass(base_test.BaseTestClass):
-
- SUBPROCESS_WAIT_TIMEOUT_SECONDS = 10
-
- def setup_class(self, dut_module, cert_module):
- self.dut_module = dut_module
- self.cert_module = cert_module
- self.log = TraceLogger(logging.getLogger())
- self.dut_coverage_info = None
- self.cert_coverage_info = None
-
- def teardown_class(self):
- # assume each test runs the same binary for dut and cert
- # generate coverage report after running all tests in a class
- if self.dut_coverage_info:
- generate_coverage_report_for_host(self.dut_coverage_info)
- self.dut_coverage_info = None
- if self.cert_coverage_info:
- generate_coverage_report_for_host(self.cert_coverage_info)
- self.cert_coverage_info = None
-
- def set_controller_properties_path(self, path):
- GD_DIR = os.path.join(os.getcwd(), os.pardir)
- self.controller_properties_file = os.path.join(GD_DIR, path)
-
- def setup_test(self):
- append_test_context(test_class_name=self.TAG, test_name=self.current_test_info.name)
- self.log_path_base = get_current_context().get_full_output_path()
- self.verbose_mode = bool(self.user_params.get('verbose_mode', False))
- for config in self.controller_configs[CONTROLLER_CONFIG_NAME]:
- config['verbose_mode'] = self.verbose_mode
-
- try:
- controller_properties_file = self.controller_properties_file
- except AttributeError:
- controller_properties_file = ''
-
- self.info = setup_rootcanal(
- dut_module=self.dut_module,
- cert_module=self.cert_module,
- verbose_mode=self.verbose_mode,
- log_path_base=self.log_path_base,
- controller_configs=self.controller_configs,
- controller_properties_file=controller_properties_file)
- self.rootcanal_running = self.info['rootcanal_running']
- self.rootcanal_logpath = self.info['rootcanal_logpath']
- self.rootcanal_process = self.info['rootcanal_process']
- self.rootcanal_logger = self.info['rootcanal_logger']
-
- if 'rootcanal' in self.controller_configs:
- asserts.assert_true(self.info['rootcanal_exist'],
- "Root canal does not exist at %s" % self.info['rootcanal'])
- asserts.assert_true(self.info['make_rootcanal_ports_available'],
- "Failed to make root canal ports available")
-
- self.log.debug("Running %s" % " ".join(self.info['rootcanal_cmd']))
- asserts.assert_true(
- self.info['is_rootcanal_process_started'],
- msg="Cannot start root-canal at " + str(self.info['rootcanal']))
- asserts.assert_true(self.info['is_subprocess_alive'], msg="root-canal stopped immediately after running")
-
- self.controller_configs = self.info['controller_configs']
-
- # Parse and construct GD device objects
- self.register_controller(importlib.import_module('blueberry.tests.gd.cert.gd_device'), builtin=True)
- self.dut = self.gd_device[1]
- self.cert = self.gd_device[0]
- if self.dut.host_only_device:
- new_dut_coverage_info = self.dut.get_coverage_info()
- if self.dut_coverage_info:
- asserts.assert_true(
- self.dut_coverage_info == new_dut_coverage_info,
- msg="DUT coverage info must be the same for each test run, old: {}, new: {}".format(
- self.dut_coverage_info, new_dut_coverage_info))
- self.dut_coverage_info = new_dut_coverage_info
- if self.cert.host_only_device:
- new_cert_coverage_info = self.cert.get_coverage_info()
- if self.cert_coverage_info:
- asserts.assert_true(
- self.cert_coverage_info == new_cert_coverage_info,
- msg="CERT coverage info must be the same for each test run, old: {}, new: {}".format(
- self.cert_coverage_info, new_cert_coverage_info))
- self.cert_coverage_info = new_cert_coverage_info
-
- try:
- self.dut.rootservice.StartStack(
- facade_rootservice.StartStackRequest(
- module_under_test=facade_rootservice.BluetoothModule.Value(self.dut_module)))
- except RpcError as rpc_error:
- asserts.fail("Failed to start DUT stack, RpcError={!r}".format(rpc_error))
- try:
- self.cert.rootservice.StartStack(
- facade_rootservice.StartStackRequest(
- module_under_test=facade_rootservice.BluetoothModule.Value(self.cert_module)))
- except RpcError as rpc_error:
- asserts.fail("Failed to start CERT stack, RpcError={!r}".format(rpc_error))
- self.dut.wait_channel_ready()
- self.cert.wait_channel_ready()
-
- def teardown_test(self):
- stack = ""
- try:
- stack = "CERT"
- self.cert.rootservice.StopStack(facade_rootservice.StopStackRequest())
- stack = "DUT"
- self.dut.rootservice.StopStack(facade_rootservice.StopStackRequest())
- except RpcError as rpc_error:
- asserts.fail("Failed to stop {} stack, RpcError={!r}".format(stack, rpc_error))
- finally:
- # Destroy GD device objects
- self._controller_manager.unregister_controllers()
- teardown_rootcanal(
- rootcanal_running=self.rootcanal_running,
- rootcanal_process=self.rootcanal_process,
- rootcanal_logger=self.rootcanal_logger,
- subprocess_wait_timeout_seconds=self.SUBPROCESS_WAIT_TIMEOUT_SECONDS)
- pop_test_context()
-
- @staticmethod
- def get_module_reference_name(a_module):
- """Returns the module's module's submodule name as reference name.
-
- Args:
- a_module: Any module. Ideally, a controller module.
- Returns:
- A string corresponding to the module's name.
- """
- return a_module.__name__.split('.')[-1]
-
- def register_controller(self, controller_module, required=True, builtin=False):
- """Registers an controller module for a test class. Invokes Mobly's
- implementation of register_controller.
- """
- module_ref_name = self.get_module_reference_name(controller_module)
- module_config_name = controller_module.MOBLY_CONTROLLER_CONFIG_NAME
-
- # Get controller objects from Mobly's register_controller
- controllers = self._controller_manager.register_controller(controller_module, required=required)
- if not controllers:
- return None
-
- # Log controller information
- # Implementation of "get_info" is optional for a controller module.
- if hasattr(controller_module, "get_info"):
- controller_info = controller_module.get_info(controllers)
- self.log.info("Controller %s: %s", module_config_name, controller_info)
-
- if builtin:
- setattr(self, module_ref_name, controllers)
- return controllers
-
- def __getattribute__(self, name):
- attr = super().__getattribute__(name)
- if not callable(attr) or not GdBaseTestClass.__is_entry_function(name):
- return attr
-
- @wraps(attr)
- def __wrapped(*args, **kwargs):
- try:
- return attr(*args, **kwargs)
- except RpcError as e:
- exception_info = "".join(traceback.format_exception(e.__class__, e, e.__traceback__))
- raise signals.TestFailure(
- "RpcError during test\n\nRpcError:\n\n%s\n%s" % (exception_info, self.__dump_crashes()))
-
- return __wrapped
-
- __ENTRY_METHODS = {"setup_class", "teardown_class", "setup_test", "teardown_test"}
-
- @staticmethod
- def __is_entry_function(name):
- return name.startswith("test_") or name in GdBaseTestClass.__ENTRY_METHODS
-
- def __dump_crashes(self):
- """
- return: formatted stack traces if found, or last few lines of log
- """
- crash_detail = dump_crashes_core(
- dut=self.dut,
- cert=self.cert,
- rootcanal_running=self.rootcanal_running,
- rootcanal_process=self.rootcanal_process,
- rootcanal_logpath=self.rootcanal_logpath)
- return crash_detail
diff --git a/blueberry/tests/gd/cert/gd_device.py b/blueberry/tests/gd/cert/gd_device.py
deleted file mode 100644
index 4dc8b27..0000000
--- a/blueberry/tests/gd/cert/gd_device.py
+++ /dev/null
@@ -1,549 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from abc import ABC
-from datetime import datetime
-import inspect
-import logging
-import os
-import pathlib
-import shutil
-import signal
-import socket
-import subprocess
-import time
-from typing import List
-
-import grpc
-
-from cert.async_subprocess_logger import AsyncSubprocessLogger
-from cert.gd_device_lib import create_core
-from cert.gd_device_lib import destroy_core
-from cert.gd_device_lib import get_info
-from cert.gd_device_lib import replace_vars
-from cert.gd_device_lib import GdDeviceBaseCore
-from cert.gd_device_lib import get_coverage_profdata_path_for_host
-from cert.gd_device_lib import merge_coverage_profdata_for_host
-from cert.gd_device_lib import MOBLY_CONTROLLER_CONFIG_NAME
-from cert.logging_client_interceptor import LoggingClientInterceptor
-from cert.os_utils import get_gd_root
-from cert.os_utils import read_crash_snippet_and_log_tail
-from cert.os_utils import is_subprocess_alive
-from cert.os_utils import make_ports_available
-from cert.os_utils import TerminalColor
-
-from blueberry.tests.gd.cert import asserts
-from blueberry.tests.gd.cert.adb import BlueberryAdbProxy
-from blueberry.tests.gd.cert.adb import UTF_8
-from blueberry.tests.gd.cert.context import get_current_context
-
-from mobly import utils
-from mobly.controllers.android_device_lib.adb import AdbError
-
-ADB_FILE_NOT_EXIST_ERROR = "No such file or directory"
-PORT_FORWARDING_ERROR_MSG_PREFIX = "During port forwarding cleanup: "
-PULL_LOG_FILE_ERROR_MSG_PREFIX = "While trying to pull log files"
-
-
-def create(configs):
- create_core(configs)
- return get_instances_with_configs(configs)
-
-
-def destroy(devices):
- destroy_core(devices)
-
-
-def get_instances_with_configs(configs):
- print(configs)
- devices = []
- for config in configs:
- resolved_cmd = []
- for arg in config["cmd"]:
- logging.debug(arg)
- resolved_cmd.append(replace_vars(arg, config))
- verbose_mode = bool(config.get('verbose_mode', False))
- if config.get("serial_number"):
- device = GdAndroidDevice(config["grpc_port"], config["grpc_root_server_port"], config["signal_port"],
- resolved_cmd, config["label"], MOBLY_CONTROLLER_CONFIG_NAME, config["name"],
- config["serial_number"], verbose_mode)
- else:
- device = GdHostOnlyDevice(config["grpc_port"], config["grpc_root_server_port"], config["signal_port"],
- resolved_cmd, config["label"], MOBLY_CONTROLLER_CONFIG_NAME, config["name"],
- verbose_mode)
- device.setup()
- devices.append(device)
- return devices
-
-
-class GdDeviceBase(GdDeviceBaseCore):
- """
- Base GD device class that covers common traits which assumes that the
- device must be driven by a driver-like backing process that takes following
- command line arguments:
- --grpc-port: main entry port for facade services
- --root-server-port: management port for starting and stopping services
- --btsnoop: path to btsnoop HCI log
- --signal-port: signaling port to indicate that backing process is started
- --rootcanal-port: root-canal HCI port, optional
- """
-
- def __init__(self, grpc_port: str, grpc_root_server_port: str, signal_port: str, cmd: List[str], label: str,
- type_identifier: str, name: str, verbose_mode: bool):
- """Verify arguments and log path, initialize Base GD device, common traits
- for both device based and host only GD cert tests
- :param grpc_port: main gRPC service port
- :param grpc_root_server_port: gRPC root server port
- :param signal_port: signaling port for backing process start up
- :param cmd: list of arguments to run in backing process
- :param label: device label used in logs
- :param type_identifier: device type identifier used in logs
- :param name: name of device used in logs
- """
- # Must be at the first line of __init__ method
- values = locals()
- arguments = [values[arg] for arg in inspect.getfullargspec(GdDeviceBase.__init__).args if arg != "verbose_mode"]
- asserts.assert_true(all(arguments), "All arguments to GdDeviceBase must not be None nor empty")
- asserts.assert_true(all(cmd), "cmd list should not have None nor empty component")
-
- self.log_path_base = get_current_context().get_full_output_path()
- self.test_runner_base_path = \
- get_current_context().get_base_output_path()
-
- GdDeviceBaseCore.__init__(self, grpc_port, grpc_root_server_port, signal_port, cmd, label, type_identifier,
- name, verbose_mode, self.log_path_base, self.test_runner_base_path)
-
- def setup(self):
- """Inherited setup method from base class to set up this device for test,
- ensure signal port is available and backing process is started and alive,
- must run before using this device
- - After calling this, teardown() must be called when test finishes
- - Should be executed after children classes' setup() methods
- :return:
- """
- GdDeviceBaseCore.setup(self)
-
- # Ensure backing process is started and alive
- asserts.assert_true(self.backing_process, msg="Cannot start backing_process at " + " ".join(self.cmd))
- asserts.assert_true(
- self.is_backing_process_alive,
- msg="backing_process stopped immediately after running " + " ".join(self.cmd))
- asserts.assert_true(
- self.grpc_root_server_ready, msg="gRPC root server did not start after running " + " ".join(self.cmd))
-
- def get_crash_snippet_and_log_tail(self):
- GdDeviceBaseCore.get_crash_snippet_and_log_tail(self)
-
- def teardown(self):
- """Inherited teardown method from base class to tear down this device
- and clean up any resources.
- - Must be called after setup()
- - Should be executed before children classes' teardown()
- :return:
- """
- GdDeviceBaseCore.teardown(self)
-
- def wait_channel_ready(self):
- try:
- GdDeviceBaseCore.wait_channel_ready(self)
- except grpc.FutureTimeoutError:
- asserts.fail("[%s] wait channel ready timeout" % self.label)
-
-
-class GdHostOnlyDevice(GdDeviceBase):
- """
- Host only device where the backing process is running on the host machine
- """
-
- def __init__(self, grpc_port: str, grpc_root_server_port: str, signal_port: str, cmd: List[str], label: str,
- type_identifier: str, name: str, verbose_mode: bool):
- super().__init__(grpc_port, grpc_root_server_port, signal_port, cmd, label, MOBLY_CONTROLLER_CONFIG_NAME, name,
- verbose_mode)
- self.host_only_device = True
- # Enable LLVM code coverage output for host only tests
- self.backing_process_profraw_path = pathlib.Path(self.log_path_base).joinpath(
- "%s_%s_backing_coverage.profraw" % (self.type_identifier, self.label))
- self.environment["LLVM_PROFILE_FILE"] = str(self.backing_process_profraw_path)
- llvm_binutils = pathlib.Path(get_gd_root()).joinpath("llvm_binutils").joinpath("bin")
- llvm_symbolizer = llvm_binutils.joinpath("llvm-symbolizer")
- if llvm_symbolizer.is_file():
- self.environment["ASAN_SYMBOLIZER_PATH"] = llvm_symbolizer
- else:
- logging.warning("[%s] Cannot find LLVM symbolizer at %s" % (self.label, str(llvm_symbolizer)))
- self.profdata_path = get_coverage_profdata_path_for_host(self.test_runner_base_path, self.type_identifier,
- self.label)
-
- def teardown(self):
- super().teardown()
- merge_coverage_profdata_for_host(self.backing_process_profraw_path, self.profdata_path, self.label)
-
- def get_coverage_info(self):
- """
- Get information needed for coverage reporting
- :return: a dictionary with all information needed for coverage reporting
- """
- return {
- "profdata_path": self.profdata_path,
- "label": self.label,
- "test_runner_base_path": self.test_runner_base_path,
- "type_identifier": self.type_identifier,
- "stack_bin": self.cmd[0]
- }
-
- def setup(self):
- # Ensure ports are available
- # Only check on host only test, for Android devices, these ports will
- # be opened on Android device and host machine ports will be occupied
- # by sshd or adb forwarding
- asserts.assert_true(
- make_ports_available((self.grpc_port, self.grpc_root_server_port)),
- "[%s] Failed to make backing process ports available" % self.label)
- super().setup()
-
-
-class GdAndroidDevice(GdDeviceBase):
- """Real Android device where the backing process is running on it
- """
-
- WAIT_FOR_DEVICE_TIMEOUT_SECONDS = 180
-
- def __init__(self, grpc_port: str, grpc_root_server_port: str, signal_port: str, cmd: List[str], label: str,
- type_identifier: str, name: str, serial_number: str, verbose_mode: bool):
- super().__init__(grpc_port, grpc_root_server_port, signal_port, cmd, label, type_identifier, name, verbose_mode)
- asserts.assert_true(serial_number, "serial_number must not be None nor empty")
- self.serial_number = serial_number
- self.adb = BlueberryAdbProxy(serial_number)
-
- def setup(self):
- logging.info("Setting up device %s %s" % (self.label, self.serial_number))
- asserts.assert_true(self.adb.ensure_root(), "device %s cannot run as root", self.serial_number)
- self.ensure_verity_disabled()
-
- # Try freeing ports and ignore results
- self.cleanup_port_forwarding()
- self.sync_device_time()
-
- # Set up port forwarding or reverse or die
- self.tcp_forward_or_die(self.grpc_port, self.grpc_port)
- self.tcp_forward_or_die(self.grpc_root_server_port, self.grpc_root_server_port)
- self.tcp_reverse_or_die(self.signal_port, self.signal_port)
-
- # Push test binaries
- self.push_or_die(os.path.join(get_gd_root(), "target", "bluetooth_stack_with_facade"), "system/bin")
- self.push_or_die(
- os.path.join(get_gd_root(), "target", "android.system.suspend.control-V1-ndk.so"), "system/lib64")
- self.push_or_die(os.path.join(get_gd_root(), "target", "libbluetooth_gd.so"), "system/lib64")
- self.push_or_die(os.path.join(get_gd_root(), "target", "libgrpc++_unsecure.so"), "system/lib64")
- self.push_or_die(os.path.join(get_gd_root(), "target", "libgrpc++.so"), "system/lib64")
- self.push_or_die(os.path.join(get_gd_root(), "target", "libgrpc_wrap.so"), "system/lib64")
- self.push_or_die(os.path.join(get_gd_root(), "target", "libstatslog_bt.so"), "system/lib64")
-
- try:
- self.adb.shell("rm /data/misc/bluetooth/logs/btsnoop_hci.log")
- except AdbError as error:
- if ADB_FILE_NOT_EXIST_ERROR not in str(error):
- logging.error("Error during setup: " + str(error))
-
- try:
- self.adb.shell("rm /data/misc/bluetooth/logs/btsnooz_hci.log")
- except AdbError as error:
- if ADB_FILE_NOT_EXIST_ERROR not in str(error):
- logging.error("Error during setup: " + str(error))
-
- try:
- self.adb.shell("rm /data/misc/bluedroid/bt_config.conf")
- except AdbError as error:
- if ADB_FILE_NOT_EXIST_ERROR not in str(error):
- logging.error("Error during setup: " + str(error))
-
- try:
- self.adb.shell("rm /data/misc/bluedroid/bt_config.bak")
- except AdbError as error:
- if ADB_FILE_NOT_EXIST_ERROR not in str(error):
- logging.error("Error during setup: " + str(error))
-
- self.ensure_no_output(self.adb.shell("svc bluetooth disable"))
-
- # Start logcat logging
- self.logcat_output_path = os.path.join(
- self.log_path_base, '%s_%s_%s_logcat_logs.txt' % (self.type_identifier, self.label, self.serial_number))
- self.logcat_cmd = ["adb", "-s", self.serial_number, "logcat", "-T", "1", "-v", "year", "-v", "uid"]
- logging.debug("Running %s", " ".join(self.logcat_cmd))
- self.logcat_process = subprocess.Popen(
- self.logcat_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
- asserts.assert_true(self.logcat_process, msg="Cannot start logcat_process at " + " ".join(self.logcat_cmd))
- asserts.assert_true(
- is_subprocess_alive(self.logcat_process),
- msg="logcat_process stopped immediately after running " + " ".join(self.logcat_cmd))
- self.logcat_logger = AsyncSubprocessLogger(
- self.logcat_process, [self.logcat_output_path],
- log_to_stdout=self.verbose_mode,
- tag="%s_%s" % (self.label, self.serial_number),
- color=self.terminal_color)
-
- # Done run parent setup
- logging.info("Done preparation for %s, starting backing process" % self.serial_number)
- super().setup()
-
- def teardown(self):
- super().teardown()
- stop_signal = signal.SIGINT
- self.logcat_process.send_signal(stop_signal)
- try:
- return_code = self.logcat_process.wait(timeout=self.WAIT_CHANNEL_READY_TIMEOUT_SECONDS)
- except subprocess.TimeoutExpired:
- logging.error("[%s_%s] Failed to interrupt logcat process via SIGINT, sending SIGKILL" %
- (self.label, self.serial_number))
- stop_signal = signal.SIGKILL
- self.logcat_process.kill()
- try:
- return_code = self.logcat_process.wait(timeout=self.WAIT_CHANNEL_READY_TIMEOUT_SECONDS)
- except subprocess.TimeoutExpired:
- logging.error("Failed to kill logcat_process %s %s" % (self.label, self.serial_number))
- return_code = -65536
- if return_code not in [-stop_signal, 0]:
- logging.error("logcat_process %s_%s stopped with code: %d" % (self.label, self.serial_number, return_code))
- self.logcat_logger.stop()
- self.cleanup_port_forwarding()
- try:
- self.adb.pull([
- "/data/misc/bluetooth/logs/btsnoop_hci.log",
- str(os.path.join(self.log_path_base, "%s_btsnoop_hci.log" % self.label))
- ])
- except AdbError as error:
- # Some tests have no snoop logs, and that's OK
- if ADB_FILE_NOT_EXIST_ERROR not in str(error):
- logging.error(PULL_LOG_FILE_ERROR_MSG_PREFIX + str(error))
- try:
- self.adb.pull([
- "/data/misc/bluedroid/bt_config.conf",
- str(os.path.join(self.log_path_base, "%s_bt_config.conf" % self.label))
- ])
- except AdbError as error:
- # Some tests have no config file, and that's OK
- if ADB_FILE_NOT_EXIST_ERROR not in str(error):
- logging.error(PULL_LOG_FILE_ERROR_MSG_PREFIX + str(error))
- try:
- self.adb.pull([
- "/data/misc/bluedroid/bt_config.bak",
- str(os.path.join(self.log_path_base, "%s_bt_config.bak" % self.label))
- ])
- except AdbError as error:
- # Some tests have no config.bak file, and that's OK
- if ADB_FILE_NOT_EXIST_ERROR not in str(error):
- logging.error(PULL_LOG_FILE_ERROR_MSG_PREFIX + str(error))
-
- def cleanup_port_forwarding(self):
- try:
- self.adb.remove_tcp_forward(self.grpc_port)
- except AdbError as error:
- msg = PORT_FORWARDING_ERROR_MSG_PREFIX + str(error)
- if "not found" in msg:
- logging.info(msg)
- else:
- logging.error(msg)
-
- try:
- self.adb.remove_tcp_forward(self.grpc_root_server_port)
- except AdbError as error:
- msg = PORT_FORWARDING_ERROR_MSG_PREFIX + str(error)
- if "not found" in msg:
- logging.info(msg)
- else:
- logging.error(msg)
-
- try:
- self.adb.reverse(["--remove", "tcp:%d" % self.signal_port])
- except AdbError as error:
- msg = PORT_FORWARDING_ERROR_MSG_PREFIX + str(error)
- if "not found" in msg:
- logging.info(msg)
- else:
- logging.error(msg)
-
- @staticmethod
- def ensure_no_output(result):
- """
- Ensure a command has not output
- """
- asserts.assert_true(
- result is None or len(result) == 0, msg="command returned something when it shouldn't: %s" % result)
-
- def sync_device_time(self):
- self.adb.shell("settings put global auto_time 0")
- self.adb.shell("settings put global auto_time_zone 0")
- device_tz = self.adb.shell("date +%z").decode(UTF_8).rstrip()
- asserts.assert_true(device_tz, "date +%z must return device timezone, "
- "but returned {} instead".format(device_tz))
- host_tz = time.strftime("%z")
- if device_tz != host_tz:
- target_timezone = utils.get_timezone_olson_id()
- logging.debug("Device timezone %s does not match host timezone %s, "
- "syncing them by setting timezone to %s" % (device_tz, host_tz, target_timezone))
- self.adb.shell("setprop persist.sys.timezone %s" % target_timezone)
- self.reboot()
- self.adb.remount()
- device_tz = self.adb.shell("date +%z")
- asserts.assert_equal(
- host_tz, device_tz, "Device timezone %s still does not match host "
- "timezone %s after reset" % (device_tz, host_tz))
- self.adb.shell("date %s" % time.strftime("%m%d%H%M%Y.%S"))
- datetime_format = "%Y-%m-%dT%H:%M:%S%z"
- try:
- device_time = datetime.strptime(
- self.adb.shell("date +'%s'" % datetime_format).decode(UTF_8).rstrip(), datetime_format)
- except ValueError:
- asserts.fail("Failed to get time after sync")
- return
- # Include ADB delay that might be longer in SSH environment
- max_delta_seconds = 3
- host_time = datetime.now(tz=device_time.tzinfo)
- asserts.assert_almost_equal(
- (device_time - host_time).total_seconds(),
- 0,
- msg="Device time %s and host time %s off by >%dms after sync" %
- (device_time.isoformat(), host_time.isoformat(), int(max_delta_seconds * 1000)),
- delta=max_delta_seconds)
-
- def push_or_die(self, src_file_path, dst_file_path, push_timeout=300):
- """Pushes a file to the Android device
-
- Args:
- src_file_path: The path to the file to install.
- dst_file_path: The destination of the file.
- push_timeout: How long to wait for the push to finish in seconds
- """
- out = self.adb.push([src_file_path, dst_file_path], timeout=push_timeout).decode(UTF_8).rstrip()
- if 'error' in out:
- asserts.fail('Unable to push file %s to %s due to %s' % (src_file_path, dst_file_path, out))
-
- def tcp_forward_or_die(self, host_port, device_port, num_retry=1):
- """
- Forward a TCP port from host to device or fail
- :param host_port: host port, int, 0 for adb to assign one
- :param device_port: device port, int
- :param num_retry: number of times to reboot and retry this before dying
- :return: host port int
- """
- error_or_port = self.adb.tcp_forward(host_port, device_port)
- if not error_or_port:
- logging.debug("host port %d was already forwarded" % host_port)
- return host_port
- if not isinstance(error_or_port, int):
- if num_retry > 0:
- # If requested, reboot an retry
- num_retry -= 1
- logging.warning(
- "[%s] Failed to TCP forward host port %d to "
- "device port %d, num_retries left is %d" % (self.label, host_port, device_port, num_retry))
- self.reboot()
- self.adb.remount()
- return self.tcp_forward_or_die(host_port, device_port, num_retry=num_retry)
- asserts.fail(
- 'Unable to forward host port %d to device port %d, error %s' % (host_port, device_port, error_or_port))
- return error_or_port
-
- def tcp_reverse_or_die(self, device_port, host_port, num_retry=1):
- """
- Forward a TCP port from device to host or fail
- :param device_port: device port, int, 0 for adb to assign one
- :param host_port: host port, int
- :param num_retry: number of times to reboot and retry this before dying
- :return: device port int
- """
- error_or_port = self.adb.reverse(["tcp:%d" % device_port, "tcp:%d" % host_port])
- if not error_or_port:
- logging.debug("device port %d was already reversed" % device_port)
- return device_port
- try:
- error_or_port = int(error_or_port)
- except ValueError:
- if num_retry > 0:
- # If requested, reboot an retry
- num_retry -= 1
- logging.warning(
- "[%s] Failed to TCP reverse device port %d to "
- "host port %d, num_retries left is %d" % (self.label, device_port, host_port, num_retry))
- self.reboot()
- self.adb.remount()
- return self.tcp_reverse_or_die(device_port, host_port, num_retry=num_retry)
- asserts.fail(
- 'Unable to reverse device port %d to host port %d, error %s' % (device_port, host_port, error_or_port))
- return error_or_port
-
- def ensure_verity_disabled(self):
- """Ensures that verity is enabled.
-
- If verity is not enabled, this call will reboot the phone. Note that
- this only works on debuggable builds.
- """
- logging.debug("Disabling verity and remount for %s", self.serial_number)
- # The below properties will only exist if verity has been enabled.
- system_verity = self.adb.getprop('partition.system.verified')
- vendor_verity = self.adb.getprop('partition.vendor.verified')
- if system_verity or vendor_verity:
- self.adb.disable_verity()
- self.reboot()
- self.adb.remount()
- self.adb.wait_for_device(timeout=self.WAIT_FOR_DEVICE_TIMEOUT_SECONDS)
-
- def reboot(self, timeout_minutes=15.0):
- """Reboots the device.
-
- Reboot the device, wait for device to complete booting.
- """
- logging.debug("Rebooting %s", self.serial_number)
- self.adb.reboot()
-
- timeout_start = time.time()
- timeout = timeout_minutes * 60
- # Android sometimes return early after `adb reboot` is called. This
- # means subsequent calls may make it to the device before the reboot
- # goes through, return false positives for getprops such as
- # sys.boot_completed.
- while time.time() < timeout_start + timeout:
- try:
- self.adb.get_state()
- time.sleep(.1)
- except AdbError:
- # get_state will raise an error if the device is not found. We
- # want the device to be missing to prove the device has kicked
- # off the reboot.
- break
- minutes_left = timeout_minutes - (time.time() - timeout_start) / 60.0
- self.wait_for_boot_completion(timeout_minutes=minutes_left)
- asserts.assert_true(self.adb.ensure_root(), "device %s cannot run as root after reboot" % self.serial_number)
-
- def wait_for_boot_completion(self, timeout_minutes=15.0):
- """
- Waits for Android framework to broadcast ACTION_BOOT_COMPLETED.
- :param timeout_minutes: number of minutes to wait
- """
- timeout_start = time.time()
- timeout = timeout_minutes * 60
-
- self.adb.wait_for_device(timeout=self.WAIT_FOR_DEVICE_TIMEOUT_SECONDS)
- while time.time() < timeout_start + timeout:
- try:
- completed = self.adb.getprop("sys.boot_completed")
- if completed == '1':
- return
- except AdbError:
- # adb shell calls may fail during certain period of booting
- # process, which is normal. Ignoring these errors.
- pass
- time.sleep(5)
- asserts.fail(msg='Device %s booting process timed out.' % self.serial_number)
diff --git a/blueberry/tests/gd/cert/metadata.py b/blueberry/tests/gd/cert/metadata.py
deleted file mode 100644
index aa1bc9a..0000000
--- a/blueberry/tests/gd/cert/metadata.py
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-import functools
-import inspect
-
-from mobly import asserts
-
-from blueberry.tests.gd.cert.test_decorators import test_info
-
-
-def _fail_decorator(msg):
-
- def fail_decorator(func):
-
- @functools.wraps(func)
- def fail(*args, **kwargs):
- asserts.fail(msg)
-
- return fail
-
- return fail_decorator
-
-
-def metadata(_do_not_use=None, pts_test_id=None, pts_test_name=None):
- """
- Record a piece of test metadata in the Extra section of the test Record in
- the test summary file. The metadata will come with a timestamp, but there
- is no guarantee on the order of when the metadata will be written
-
- Note:
- - Metadata is recorded per test case as key-value pairs.
- - Metadata is only guaranteed to be written when the test result is PASS,
- FAIL or SKIPPED. When there are test infrastructural errors, metadata
- might not be written successfully
- :param _do_not_use: a positional argument with default value. This argument
- is to ensure that @metadata(key=value) is used in a
- functional form instead of @metadata or @metadata(a)
- :param pts_test_id: A fully qualified PTS test ID such as
- L2CAP/COS/IEX/BV-01-C
- :param pts_test_name: A human readable test name such as
- "Request Connection" for the above example
- :return: decorated test case function object
- """
- if _do_not_use is not None:
-
- def fail(*args, **kwargs):
- asserts.fail("@metadata must be used in functional form such " "as @metadta(key=value)")
-
- return fail
-
- # Create a dictionary of optional parameters
- values = locals()
- args = {arg: values[arg] for arg in inspect.getfullargspec(metadata).args}
- del args["_do_not_use"]
-
- # Check if at least one optional parameter is valid
- if not any(args.values()):
- return _fail_decorator("at least one optional argument should be valid")
-
- # Validate pts_test_id and pts_test_name
- if any((pts_test_id, pts_test_name)) and \
- not all((pts_test_id, pts_test_name)):
- return _fail_decorator("pts_test_id and pts_test_name must both " "be valid if one of them is valid")
-
- return test_info(**args)
diff --git a/blueberry/tests/gd/cert/pts_base_test.py b/blueberry/tests/gd/cert/pts_base_test.py
deleted file mode 100644
index 0e8b99a..0000000
--- a/blueberry/tests/gd/cert/pts_base_test.py
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from mobly import base_test
-
-import importlib
-
-
-class PTSBaseTestClass(base_test.BaseTestClass):
-
- def __init__(self, configs):
- BaseTestClass.__init__(self, configs)
-
- gd_devices = self.controller_configs.get("GdDevice")
-
- self.register_controller(importlib.import_module('cert.gd_device'), builtin=True)
diff --git a/blueberry/tests/gd/cert/test_decorators.py b/blueberry/tests/gd/cert/test_decorators.py
deleted file mode 100644
index 453062e..0000000
--- a/blueberry/tests/gd/cert/test_decorators.py
+++ /dev/null
@@ -1,267 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from mobly import signals
-
-
-def test_info(predicate=None, **keyed_info):
- """Adds info about test.
-
- Extra info to include about the test. This info will be available in the
- test output. Note that if a key is given multiple times it will be added
- as a list of all values. If multiples of these are stacked their results
- will be merged.
-
- Example:
- # This test will have a variable my_var
- @test_info(my_var='THIS IS MY TEST')
- def my_test(self):
- return False
-
- Args:
- predicate: A func to call that if false will skip adding this test
- info. Function signature is bool(test_obj, args, kwargs)
- **keyed_info: The key, value info to include in the extras for this
- test.
- """
-
- def test_info_decorator(func):
- return _TestInfoDecoratorFunc(func, predicate, keyed_info)
-
- return test_info_decorator
-
-
-def __select_last(test_signals, _):
- return test_signals[-1]
-
-
-def repeated_test(num_passes, acceptable_failures=0, result_selector=__select_last):
- """A decorator that runs a test case multiple times.
-
- This decorator can be used to run a test multiple times and aggregate the
- data into a single test result. By setting `result_selector`, the user can
- access the returned result of each run, allowing them to average results,
- return the median, or gather and return standard deviation values.
-
- This decorator should be used on test cases, and should not be used on
- static or class methods. The test case must take in an additional argument,
- `attempt_number`, which returns the current attempt number, starting from
- 1.
-
- Note that any TestSignal intended to abort or skip the test will take
- abort or skip immediately.
-
- Args:
- num_passes: The number of times the test needs to pass to report the
- test case as passing.
- acceptable_failures: The number of failures accepted. If the failures
- exceeds this number, the test will stop repeating. The maximum
- number of runs is `num_passes + acceptable_failures`. If the test
- does fail, result_selector will still be called.
- result_selector: A lambda that takes in the list of TestSignals and
- returns the test signal to report the test case as. Note that the
- list also contains any uncaught exceptions from the test execution.
- """
-
- def decorator(func):
- if not func.__name__.startswith('test_'):
- raise ValueError('Tests must start with "test_".')
-
- def test_wrapper(self):
- num_failures = 0
- num_seen_passes = 0
- test_signals_received = []
- for i in range(num_passes + acceptable_failures):
- try:
- func(self, i + 1)
- except (signals.TestFailure, signals.TestError, AssertionError) as signal:
- test_signals_received.append(signal)
- num_failures += 1
- except signals.TestPass as signal:
- test_signals_received.append(signal)
- num_seen_passes += 1
- except (signals.TestSignal, KeyboardInterrupt):
- raise
- except Exception as signal:
- test_signals_received.append(signal)
- num_failures += 1
- else:
- num_seen_passes += 1
- test_signals_received.append(
- signals.TestPass('Test iteration %s of %s passed without details.' % (i, func.__name__)))
-
- if num_failures > acceptable_failures:
- break
- elif num_seen_passes == num_passes:
- break
- else:
- self.teardown_test()
- self.setup_test()
-
- raise result_selector(test_signals_received, self)
-
- return test_wrapper
-
- return decorator
-
-
-def test_tracker_info(uuid, extra_environment_info=None, predicate=None):
- """Decorator for adding test tracker info to tests results.
-
- Will add test tracker info inside of Extras/test_tracker_info.
-
- Example:
- # This test will be linked to test tracker uuid abcd
- @test_tracker_info(uuid='abcd')
- def my_test(self):
- return False
-
- Args:
- uuid: The uuid of the test case in test tracker.
- extra_environment_info: Extra info about the test tracker environment.
- predicate: A func that if false when called will ignore this info.
- """
- return test_info(test_tracker_uuid=uuid, test_tracker_environment_info=extra_environment_info, predicate=predicate)
-
-
-class _TestInfoDecoratorFunc(object):
- """Object that acts as a function decorator test info."""
-
- def __init__(self, func, predicate, keyed_info):
- self.func = func
- self.predicate = predicate
- self.keyed_info = keyed_info
- self.__name__ = func.__name__
- self.__doc__ = func.__doc__
- self.__module__ = func.__module__
-
- def __get__(self, instance, owner):
- """Called by Python to create a binding for an instance closure.
-
- When called by Python this object will create a special binding for
- that instance. That binding will know how to interact with this
- specific decorator.
- """
- return _TestInfoBinding(self, instance)
-
- def __call__(self, *args, **kwargs):
- """
- When called runs the underlying func and then attaches test info
- to a signal.
- """
- cause = None
- try:
- result = self.func(*args, **kwargs)
-
- if result or result is None:
- new_signal = signals.TestPass('')
- else:
- new_signal = signals.TestFailure('')
- except signals.TestSignal as signal:
- new_signal = signal
- except Exception as ex:
- cause = ex
- new_signal = signals.TestError(cause)
-
- if new_signal.extras is None:
- new_signal.extras = {}
- if not isinstance(new_signal.extras, dict):
- raise ValueError('test_info can only append to signal data that has a dict as the extra value.')
-
- gathered_extras = self._gather_local_info(None, *args, **kwargs)
- for k, v in gathered_extras.items():
- if k not in new_signal.extras:
- new_signal.extras[k] = v
- else:
- if not isinstance(new_signal.extras[k], list):
- new_signal.extras[k] = [new_signal.extras[k]]
-
- new_signal.extras[k].insert(0, v)
-
- raise new_signal from cause
-
- def gather(self, *args, **kwargs):
- """
- Gathers the info from this decorator without invoking the underlying
- function. This will also gather all child info if the underlying func
- has that ability.
-
- Returns: A dictionary of info.
- """
- if hasattr(self.func, 'gather'):
- extras = self.func.gather(*args, **kwargs)
- else:
- extras = {}
-
- self._gather_local_info(extras, *args, **kwargs)
-
- return extras
-
- def _gather_local_info(self, gather_into, *args, **kwargs):
- """Gathers info from this decorator and ignores children.
-
- Args:
- gather_into: Gathers into a dictionary that already exists.
-
- Returns: The dictionary with gathered info in it.
- """
- if gather_into is None:
- extras = {}
- else:
- extras = gather_into
- if not self.predicate or self.predicate(args, kwargs):
- for k, v in self.keyed_info.items():
- if v and k not in extras:
- extras[k] = v
- elif v and k in extras:
- if not isinstance(extras[k], list):
- extras[k] = [extras[k]]
- extras[k].insert(0, v)
-
- return extras
-
-
-class _TestInfoBinding(object):
- """
- When Python creates an instance of an object it creates a binding object
- for each closure that contains what the instance variable should be when
- called. This object is a similar binding for _TestInfoDecoratorFunc.
- When Python tries to create a binding of a _TestInfoDecoratorFunc it
- will return one of these objects to hold the instance for that closure.
- """
-
- def __init__(self, target, instance):
- """
- Args:
- target: The target for creating a binding to.
- instance: The instance to bind the target with.
- """
- self.target = target
- self.instance = instance
- self.__name__ = target.__name__
-
- def __call__(self, *args, **kwargs):
- """
- When this object is called it will call the target with the bound
- instance.
- """
- return self.target(self.instance, *args, **kwargs)
-
- def gather(self, *args, **kwargs):
- """
- Will gather the target with the bound instance.
- """
- return self.target.gather(self.instance, *args, **kwargs)
diff --git a/blueberry/tests/gd/cert/tracelogger.py b/blueberry/tests/gd/cert/tracelogger.py
deleted file mode 100644
index a4e5a22..0000000
--- a/blueberry/tests/gd/cert/tracelogger.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-import inspect
-import os
-
-
-class TraceLogger(object):
-
- def __init__(self, logger):
- self._logger = logger
-
- @staticmethod
- def _get_trace_info(level=1, offset=2):
- # We want the stack frame above this and above the error/warning/info
- inspect_stack = inspect.stack()
- trace_info = ''
- for i in range(level):
- try:
- stack_frames = inspect_stack[offset + i]
- info = inspect.getframeinfo(stack_frames[0])
- trace_info = '%s[%s:%s:%s]' % (trace_info, os.path.basename(info.filename), info.function, info.lineno)
- except IndexError:
- break
- return trace_info
-
- def _log_with(self, logging_lambda, trace_level, msg, *args, **kwargs):
- trace_info = TraceLogger._get_trace_info(level=trace_level, offset=3)
- logging_lambda('%s %s' % (msg, trace_info), *args, **kwargs)
-
- def exception(self, msg, *args, **kwargs):
- self._log_with(self._logger.exception, 5, msg, *args, **kwargs)
-
- def debug(self, msg, *args, **kwargs):
- self._log_with(self._logger.debug, 3, msg, *args, **kwargs)
-
- def error(self, msg, *args, **kwargs):
- self._log_with(self._logger.error, 3, msg, *args, **kwargs)
-
- def warn(self, msg, *args, **kwargs):
- self._log_with(self._logger.warn, 3, msg, *args, **kwargs)
-
- def warning(self, msg, *args, **kwargs):
- self._log_with(self._logger.warning, 3, msg, *args, **kwargs)
-
- def info(self, msg, *args, **kwargs):
- self._log_with(self._logger.info, 1, msg, *args, **kwargs)
-
- def __getattr__(self, name):
- return getattr(self._logger, name)
diff --git a/blueberry/tests/gd/devices_config.yaml b/blueberry/tests/gd/devices_config.yaml
deleted file mode 100644
index 2f8bbc8..0000000
--- a/blueberry/tests/gd/devices_config.yaml
+++ /dev/null
@@ -1,44 +0,0 @@
-_description: Bluetooth cert testing
-TestBeds:
- - Name: AndroidDeviceCert
- Controllers:
- GdDevice:
- - grpc_port: '8898'
- grpc_root_server_port: '8896'
- signal_port: '8894'
- label: cert
- serial_number: 'CERT'
- name: Cert Device
- cmd:
- - "adb"
- - "-s"
- - "$(serial_number)"
- - "shell"
- - "ASAN_OPTIONS=detect_container_overflow=0"
- - "/system/bin/bluetooth_stack_with_facade"
- - "--grpc-port=$(grpc_port)"
- - "--root-server-port=$(grpc_root_server_port)"
- - "--btsnoop=/data/misc/bluetooth/logs/btsnoop_hci.log"
- - "--btsnooz=/data/misc/bluetooth/logs/btsnooz_hci.log"
- - "--btconfig=/data/misc/bluedroid/bt_config.conf"
- - "--signal-port=$(signal_port)"
- - grpc_port: '8899'
- grpc_root_server_port: '8897'
- signal_port: '8895'
- label: dut
- serial_number: 'DUT'
- name: DUT Device
- cmd:
- - "adb"
- - "-s"
- - "$(serial_number)"
- - "shell"
- - "ASAN_OPTIONS=detect_container_overflow=0"
- - "/system/bin/bluetooth_stack_with_facade"
- - "--grpc-port=$(grpc_port)"
- - "--root-server-port=$(grpc_root_server_port)"
- - "--btsnoop=/data/misc/bluetooth/logs/btsnoop_hci.log"
- - "--btsnooz=/data/misc/bluetooth/logs/btsnooz_hci.log"
- - "--btconfig=/data/misc/bluedroid/bt_config.conf"
- - "--signal-port=$(signal_port)"
-logpath: "/tmp/logs"
\ No newline at end of file
diff --git a/blueberry/tests/gd/gd_all_tests.py b/blueberry/tests/gd/gd_all_tests.py
deleted file mode 100644
index 988e8c1..0000000
--- a/blueberry/tests/gd/gd_all_tests.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert.cert_self_test_blueberry import CertSelfTestBb
-from blueberry.tests.gd.hal.simple_hal_test_blueberry import SimpleHalTestBb
-from blueberry.tests.gd.hci.acl_manager_test_blueberry import AclManagerTestBb
-from blueberry.tests.gd.hci.controller_test_blueberry import ControllerTestBb
-from blueberry.tests.gd.hci.direct_hci_test_blueberry import DirectHciTestBb
-from blueberry.tests.gd.hci.le_acl_manager_test_blueberry import LeAclManagerTestBb
-from blueberry.tests.gd.hci.le_advertising_manager_test_blueberry import LeAdvertisingManagerTestBb
-from blueberry.tests.gd.hci.le_scanning_manager_test_blueberry import LeScanningManagerTestBb
-from blueberry.tests.gd.hci.le_scanning_with_security_test_blueberry import LeScanningWithSecurityTestBb
-from blueberry.tests.gd.iso.le_iso_test_blueberry import LeIsoTestBb
-from blueberry.tests.gd.l2cap.classic.l2cap_performance_test_blueberry import L2capPerformanceTestBb
-from blueberry.tests.gd.l2cap.classic.l2cap_test_blueberry import L2capTestBb
-from blueberry.tests.gd.l2cap.le.dual_l2cap_test_blueberry import DualL2capTestBb
-from blueberry.tests.gd.l2cap.le.le_l2cap_test_blueberry import LeL2capTestBb
-from blueberry.tests.gd.neighbor.neighbor_test_blueberry import NeighborTestBb
-from blueberry.tests.gd.security.le_security_test_blueberry import LeSecurityTestBb
-from blueberry.tests.gd.security.security_test_blueberry import SecurityTestBb
-from blueberry.tests.gd.shim.shim_test_blueberry import ShimTestBb
-from blueberry.tests.gd.shim.stack_test_blueberry import StackTestBb
-
-from mobly import suite_runner
-
-ALL_TESTS = {
- CertSelfTestBb, SimpleHalTestBb, AclManagerTestBb, ControllerTestBb, DirectHciTestBb, LeAclManagerTestBb,
- LeAdvertisingManagerTestBb, LeScanningManagerTestBb, LeScanningWithSecurityTestBb, LeIsoTestBb,
- L2capPerformanceTestBb, L2capTestBb, DualL2capTestBb, LeL2capTestBb, NeighborTestBb, LeSecurityTestBb,
- SecurityTestBb, ShimTestBb, StackTestBb
-}
-
-DISABLED_TESTS = set()
-
-ENABLED_TESTS = list(ALL_TESTS - DISABLED_TESTS)
-
-if __name__ == '__main__':
- suite_runner.run_suite(ENABLED_TESTS)
diff --git a/blueberry/tests/gd/gd_postsubmit_tests.py b/blueberry/tests/gd/gd_postsubmit_tests.py
deleted file mode 100644
index 17c8a6c..0000000
--- a/blueberry/tests/gd/gd_postsubmit_tests.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from blueberry.tests.gd.gd_all_tests import ALL_TESTS
-
-from mobly import suite_runner
-
-DISABLED_TESTS = set()
-
-ENABLED_TESTS = list(ALL_TESTS - DISABLED_TESTS)
-
-if __name__ == '__main__':
- suite_runner.run_suite(ENABLED_TESTS)
diff --git a/blueberry/tests/gd/gd_presubmit_tests.py b/blueberry/tests/gd/gd_presubmit_tests.py
deleted file mode 100644
index a5cf60a..0000000
--- a/blueberry/tests/gd/gd_presubmit_tests.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from blueberry.tests.gd.gd_all_tests import ALL_TESTS
-
-from mobly import suite_runner
-
-# TODO(b/194723246): Investigate failures to re-activate the test class.
-from blueberry.tests.gd.hci.le_scanning_manager_test_blueberry import LeScanningManagerTestBb
-
-# TODO(b/194723246): Investigate failures to re-activate the test class.
-from blueberry.tests.gd.l2cap.classic.l2cap_test_blueberry import L2capTestBb
-
-# TODO(b/194723246): Investigate failures to re-activate the test class.
-from blueberry.tests.gd.l2cap.le.le_l2cap_test_blueberry import LeL2capTestBb
-
-# TODO(b/194723246): Investigate failures to re-activate the test class.
-from blueberry.tests.gd.security.le_security_test_blueberry import LeSecurityTestBb
-
-# TODO(b/194723246): Investigate failures to re-activate the test class.
-from blueberry.tests.gd.security.security_test_blueberry import SecurityTestBb
-
-DISABLED_TESTS = {LeScanningManagerTestBb, L2capTestBb, LeL2capTestBb, LeSecurityTestBb, SecurityTestBb}
-
-ENABLED_TESTS = list(ALL_TESTS - DISABLED_TESTS)
-
-if __name__ == '__main__':
- suite_runner.run_suite(ENABLED_TESTS)
diff --git a/blueberry/tests/gd/hal/simple_hal_test_blueberry.py b/blueberry/tests/gd/hal/simple_hal_test_blueberry.py
deleted file mode 100644
index 506c44e..0000000
--- a/blueberry/tests/gd/hal/simple_hal_test_blueberry.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from hal.cert.simple_hal_test_lib import SimpleHalTestBase
-from mobly import test_runner
-
-_GRPC_TIMEOUT = 10
-
-
-class SimpleHalTestBb(gd_base_test.GdBaseTestClass, SimpleHalTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='HAL', cert_module='HAL')
-
- def setup_test(self):
- gd_base_test.GdBaseTestClass.setup_test(self)
- SimpleHalTestBase.setup_test(self, self.dut, self.cert)
-
- def teardown_test(self):
- SimpleHalTestBase.teardown_test(self)
- gd_base_test.GdBaseTestClass.teardown_test(self)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/hci/acl_manager_test_blueberry.py b/blueberry/tests/gd/hci/acl_manager_test_blueberry.py
deleted file mode 100644
index 9081f1c..0000000
--- a/blueberry/tests/gd/hci/acl_manager_test_blueberry.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from hci.cert.acl_manager_test_lib import AclManagerTestBase
-from mobly import test_runner
-
-
-class AclManagerTestBb(gd_base_test.GdBaseTestClass, AclManagerTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='HCI_INTERFACES', cert_module='HCI')
-
- # todo: move into GdBaseTestClass, based on modules inited
- def setup_test(self):
- gd_base_test.GdBaseTestClass.setup_test(self)
- AclManagerTestBase.setup_test(self, self.dut, self.cert)
-
- def teardown_test(self):
- AclManagerTestBase.teardown_test(self)
- gd_base_test.GdBaseTestClass.teardown_test(self)
-
- def test_dut_connects(self):
- AclManagerTestBase.test_dut_connects(self)
-
- def test_cert_connects(self):
- AclManagerTestBase.test_cert_connects(self)
-
- def test_reject_broadcast(self):
- AclManagerTestBase.test_reject_broadcast(self)
-
- def test_cert_connects_disconnects(self):
- AclManagerTestBase.test_cert_connects_disconnects(self)
-
- def test_recombination_l2cap_packet(self):
- AclManagerTestBase.test_recombination_l2cap_packet(self)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/hci/controller_test_blueberry.py b/blueberry/tests/gd/hci/controller_test_blueberry.py
deleted file mode 100644
index 4ada6e3..0000000
--- a/blueberry/tests/gd/hci/controller_test_blueberry.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from hci.cert.controller_test_lib import ControllerTestBase
-from mobly import test_runner
-
-
-class ControllerTestBb(gd_base_test.GdBaseTestClass, ControllerTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='HCI_INTERFACES', cert_module='HCI_INTERFACES')
-
- def test_get_addresses(self):
- ControllerTestBase.test_get_addresses(self, self.dut, self.cert)
-
- def test_write_local_name(self):
- ControllerTestBase.test_write_local_name(self, self.dut, self.cert)
-
- def test_extended_advertising_support(self):
- ControllerTestBase.test_extended_advertising_support(self, self.dut, self.cert)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/hci/direct_hci_test_blueberry.py b/blueberry/tests/gd/hci/direct_hci_test_blueberry.py
deleted file mode 100644
index dfba5b0..0000000
--- a/blueberry/tests/gd/hci/direct_hci_test_blueberry.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from hci.cert.direct_hci_test_lib import DirectHciTestBase
-from mobly import test_runner
-
-
-class DirectHciTestBb(gd_base_test.GdBaseTestClass, DirectHciTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='HCI', cert_module='HAL')
-
- def setup_test(self):
- gd_base_test.GdBaseTestClass.setup_test(self)
- DirectHciTestBase.setup_test(self, self.dut, self.cert)
-
- def teardown_test(self):
- DirectHciTestBase.teardown_test(self)
- gd_base_test.GdBaseTestClass.teardown_test(self)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/hci/le_acl_manager_test_blueberry.py b/blueberry/tests/gd/hci/le_acl_manager_test_blueberry.py
deleted file mode 100644
index 4aa823b..0000000
--- a/blueberry/tests/gd/hci/le_acl_manager_test_blueberry.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from hci.cert.le_acl_manager_test_lib import LeAclManagerTestBase
-from mobly import test_runner
-
-
-class LeAclManagerTestBb(gd_base_test.GdBaseTestClass, LeAclManagerTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='HCI_INTERFACES', cert_module='HCI')
-
- def setup_test(self):
- gd_base_test.GdBaseTestClass.setup_test(self)
- LeAclManagerTestBase.setup_test(self, self.dut, self.cert)
-
- def teardown_test(self):
- LeAclManagerTestBase.teardown_test(self)
- gd_base_test.GdBaseTestClass.teardown_test(self)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/hci/le_advertising_manager_test_blueberry.py b/blueberry/tests/gd/hci/le_advertising_manager_test_blueberry.py
deleted file mode 100644
index 19c0f5b..0000000
--- a/blueberry/tests/gd/hci/le_advertising_manager_test_blueberry.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from hci.cert.le_advertising_manager_test_lib import LeAdvertisingManagerTestBase
-from mobly import test_runner
-
-
-class LeAdvertisingManagerTestBb(gd_base_test.GdBaseTestClass, LeAdvertisingManagerTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='HCI_INTERFACES', cert_module='HCI')
-
- def setup_test(self):
- gd_base_test.GdBaseTestClass.setup_test(self)
- LeAdvertisingManagerTestBase.setup_test(self, self.cert)
-
- def teardown_test(self):
- LeAdvertisingManagerTestBase.teardown_test(self)
- gd_base_test.GdBaseTestClass.teardown_test(self)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/hci/le_extended_scanning_manager_test_blueberry.py b/blueberry/tests/gd/hci/le_extended_scanning_manager_test_blueberry.py
deleted file mode 100644
index 8d502a4..0000000
--- a/blueberry/tests/gd/hci/le_extended_scanning_manager_test_blueberry.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from hci.cert.le_scanning_manager_test_lib import LeScanningManagerTestBase
-from mobly import test_runner
-
-
-class LeExtendedScanningManagerTest(gd_base_test.GdBaseTestClass, LeScanningManagerTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='HCI_INTERFACES', cert_module='HCI_INTERFACES')
-
- def setup_test(self):
- gd_base_test.GdBaseTestClass.set_controller_properties_path(self, 'hci/cert/le_extended_config.json')
- gd_base_test.GdBaseTestClass.setup_test(self)
- LeScanningManagerTestBase.setup_test(self, self.cert)
-
- def teardown_test(self):
- LeScanningManagerTestBase.teardown_test(self)
- gd_base_test.GdBaseTestClass.teardown_test(self)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/hci/le_scanning_manager_test_blueberry.py b/blueberry/tests/gd/hci/le_scanning_manager_test_blueberry.py
deleted file mode 100644
index 929e29a..0000000
--- a/blueberry/tests/gd/hci/le_scanning_manager_test_blueberry.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from hci.cert.le_scanning_manager_test_lib import LeScanningManagerTestBase
-from mobly import test_runner
-
-
-class LeScanningManagerTestBb(gd_base_test.GdBaseTestClass, LeScanningManagerTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='HCI_INTERFACES', cert_module='HCI_INTERFACES')
-
- def setup_test(self):
- gd_base_test.GdBaseTestClass.set_controller_properties_path(self, 'hci/cert/le_legacy_config.json')
- gd_base_test.GdBaseTestClass.setup_test(self)
- LeScanningManagerTestBase.setup_test(self, self.cert)
-
- def teardown_test(self):
- LeScanningManagerTestBase.teardown_test(self)
- gd_base_test.GdBaseTestClass.teardown_test(self)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/hci/le_scanning_with_security_test_blueberry.py b/blueberry/tests/gd/hci/le_scanning_with_security_test_blueberry.py
deleted file mode 100644
index 7d1b3f6..0000000
--- a/blueberry/tests/gd/hci/le_scanning_with_security_test_blueberry.py
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from hci.cert.le_scanning_with_security_test_lib import LeScanningWithSecurityTestBase
-from mobly import test_runner
-
-
-class LeScanningWithSecurityTestBb(gd_base_test.GdBaseTestClass, LeScanningWithSecurityTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='SECURITY', cert_module='HCI_INTERFACES')
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/host_config.yaml b/blueberry/tests/gd/host_config.yaml
deleted file mode 100644
index 15155db..0000000
--- a/blueberry/tests/gd/host_config.yaml
+++ /dev/null
@@ -1,32 +0,0 @@
-_description: Bluetooth cert testing
-TestBeds:
- - Name: HostOnlyCert
- Controllers:
- rootcanal:
- test_port: '6401'
- hci_port: '6402'
- link_layer_port: '6403'
- GdDevice:
- - grpc_port: '8998'
- grpc_root_server_port: '8996'
- signal_port: '8994'
- label: cert
- name: Cert Device
- cmd:
- - "$GD_ROOT/bluetooth_stack_with_facade"
- - "--grpc-port=$(grpc_port)"
- - "--root-server-port=$(grpc_root_server_port)"
- - "--rootcanal-port=$(rootcanal_port)"
- - "--signal-port=$(signal_port)"
- - grpc_port: '8999'
- grpc_root_server_port: '8997'
- signal_port: '8995'
- label: dut
- name: DUT Device
- cmd:
- - "$GD_ROOT/bluetooth_stack_with_facade"
- - "--grpc-port=$(grpc_port)"
- - "--root-server-port=$(grpc_root_server_port)"
- - "--rootcanal-port=$(rootcanal_port)"
- - "--signal-port=$(signal_port)"
-logpath: "/tmp/logs"
diff --git a/blueberry/tests/gd/iso/le_iso_test_blueberry.py b/blueberry/tests/gd/iso/le_iso_test_blueberry.py
deleted file mode 100644
index ab493ac..0000000
--- a/blueberry/tests/gd/iso/le_iso_test_blueberry.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from iso.cert.le_iso_test_lib import LeIsoTestBase
-from mobly import test_runner
-
-
-class LeIsoTestBb(gd_base_test.GdBaseTestClass, LeIsoTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='L2CAP', cert_module='HCI_INTERFACES')
-
- def setup_test(self):
- gd_base_test.GdBaseTestClass.setup_test(self)
- LeIsoTestBase.setup_test(self, self.dut, self.cert)
-
- def teardown_test(self):
- LeIsoTestBase.teardown_test(self)
- gd_base_test.GdBaseTestClass.teardown_test(self)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/l2cap/classic/l2cap_performance_test_blueberry.py b/blueberry/tests/gd/l2cap/classic/l2cap_performance_test_blueberry.py
deleted file mode 100644
index 1466805..0000000
--- a/blueberry/tests/gd/l2cap/classic/l2cap_performance_test_blueberry.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from l2cap.classic.cert.l2cap_performance_test_lib import L2capPerformanceTestBase
-from mobly import test_runner
-
-
-class L2capPerformanceTestBb(gd_base_test.GdBaseTestClass, L2capPerformanceTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='L2CAP', cert_module='HCI_INTERFACES')
-
- def setup_test(self):
- gd_base_test.GdBaseTestClass.setup_test(self)
- L2capPerformanceTestBase.setup_test(self, self.dut, self.cert)
-
- def teardown_test(self):
- L2capPerformanceTestBase.teardown_test(self)
- gd_base_test.GdBaseTestClass.teardown_test(self)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/l2cap/classic/l2cap_test_blueberry.py b/blueberry/tests/gd/l2cap/classic/l2cap_test_blueberry.py
deleted file mode 100644
index d157fe4..0000000
--- a/blueberry/tests/gd/l2cap/classic/l2cap_test_blueberry.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from l2cap.classic.cert.l2cap_test_lib import L2capTestBase
-from mobly import test_runner
-
-
-class L2capTestBb(gd_base_test.GdBaseTestClass, L2capTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='L2CAP', cert_module='HCI_INTERFACES')
-
- def setup_test(self):
- gd_base_test.GdBaseTestClass.setup_test(self)
- L2capTestBase.setup_test(self, self.dut, self.cert)
-
- def teardown_test(self):
- L2capTestBase.teardown_test(self)
- gd_base_test.GdBaseTestClass.teardown_test(self)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/l2cap/le/dual_l2cap_test_blueberry.py b/blueberry/tests/gd/l2cap/le/dual_l2cap_test_blueberry.py
deleted file mode 100644
index 131d324..0000000
--- a/blueberry/tests/gd/l2cap/le/dual_l2cap_test_blueberry.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from l2cap.le.cert.dual_l2cap_test_lib import DualL2capTestBase
-from mobly import test_runner
-
-
-class DualL2capTestBb(gd_base_test.GdBaseTestClass, DualL2capTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='L2CAP', cert_module='HCI_INTERFACES')
-
- def setup_test(self):
- gd_base_test.GdBaseTestClass.setup_test(self)
- DualL2capTestBase.setup_test(self, self.dut, self.cert)
-
- def teardown_test(self):
- DualL2capTestBase.teardown_test(self)
- gd_base_test.GdBaseTestClass.teardown_test(self)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/l2cap/le/le_l2cap_test_blueberry.py b/blueberry/tests/gd/l2cap/le/le_l2cap_test_blueberry.py
deleted file mode 100644
index 2a7e9f4..0000000
--- a/blueberry/tests/gd/l2cap/le/le_l2cap_test_blueberry.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from l2cap.le.cert.le_l2cap_test_lib import LeL2capTestBase
-from mobly import test_runner
-
-
-class LeL2capTestBb(gd_base_test.GdBaseTestClass, LeL2capTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='L2CAP', cert_module='HCI_INTERFACES')
-
- def setup_test(self):
- gd_base_test.GdBaseTestClass.setup_test(self)
- LeL2capTestBase.setup_test(self, self.dut, self.cert)
-
- def teardown_test(self):
- LeL2capTestBase.teardown_test(self)
- gd_base_test.GdBaseTestClass.teardown_test(self)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/neighbor/neighbor_test_blueberry.py b/blueberry/tests/gd/neighbor/neighbor_test_blueberry.py
deleted file mode 100644
index 6ada99e..0000000
--- a/blueberry/tests/gd/neighbor/neighbor_test_blueberry.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from neighbor.cert.neighbor_test_lib import NeighborTestBase
-from mobly import test_runner
-
-
-class NeighborTestBb(gd_base_test.GdBaseTestClass, NeighborTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='HCI_INTERFACES', cert_module='HCI')
-
- def setup_test(self):
- gd_base_test.GdBaseTestClass.setup_test(self)
- NeighborTestBase.setup_test(self, self.dut, self.cert)
-
- def teardown_test(self):
- NeighborTestBase.teardown_test(self)
- gd_base_test.GdBaseTestClass.teardown_test(self)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/rust/topshim/facade/adapter_test_blueberry.py b/blueberry/tests/gd/rust/topshim/facade/adapter_test_blueberry.py
deleted file mode 100644
index a4a361d..0000000
--- a/blueberry/tests/gd/rust/topshim/facade/adapter_test_blueberry.py
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from rust.topshim.facade import adapter_test
-from mobly import test_runner
-
-class AdapterTestBb(adapter_test.AdapterTest):
- pass
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/security/le_security_test_blueberry.py b/blueberry/tests/gd/security/le_security_test_blueberry.py
deleted file mode 100644
index 8605aa4..0000000
--- a/blueberry/tests/gd/security/le_security_test_blueberry.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from security.cert.le_security_test_lib import LeSecurityTestBase
-
-from mobly import asserts
-from mobly import test_runner
-
-
-class LeSecurityTestBb(gd_base_test.GdBaseTestClass, LeSecurityTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='SECURITY', cert_module='SECURITY')
-
- def setup_test(self):
- asserts.skip("Unhandled race condition - Flaky test")
- gd_base_test.GdBaseTestClass.setup_test(self)
- LeSecurityTestBase.setup_test(self, self.dut, self.cert)
-
- def teardown_test(self):
- return # test skipped
- LeSecurityTestBase.teardown_test(self)
- gd_base_test.GdBaseTestClass.teardown_test(self)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/security/security_test_blueberry.py b/blueberry/tests/gd/security/security_test_blueberry.py
deleted file mode 100644
index 0a2ec9d..0000000
--- a/blueberry/tests/gd/security/security_test_blueberry.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from security.cert.security_test_lib import SecurityTestBase
-from mobly import test_runner
-
-
-class SecurityTestBb(gd_base_test.GdBaseTestClass, SecurityTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='SECURITY', cert_module='L2CAP')
-
- def setup_test(self):
- gd_base_test.GdBaseTestClass.setup_test(self)
- SecurityTestBase.setup_test(self, self.dut, self.cert)
-
- def teardown_test(self):
- SecurityTestBase.teardown_test(self)
- gd_base_test.GdBaseTestClass.teardown_test(self)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/shim/shim_test_blueberry.py b/blueberry/tests/gd/shim/shim_test_blueberry.py
deleted file mode 100644
index e679855..0000000
--- a/blueberry/tests/gd/shim/shim_test_blueberry.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from shim.cert.shim_test_lib import ShimTestBase
-from mobly import test_runner
-
-
-class ShimTestBb(gd_base_test.GdBaseTestClass, ShimTestBase):
-
- def setup_class(self):
- gd_base_test.GdBaseTestClass.setup_class(self, dut_module='SHIM', cert_module='SHIM')
-
- def test_dumpsys(self):
- ShimTestBase.test_dumpsys(self, self.dut, self.cert)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/gd/shim/stack_test_blueberry.py b/blueberry/tests/gd/shim/stack_test_blueberry.py
deleted file mode 100644
index bb9c045..0000000
--- a/blueberry/tests/gd/shim/stack_test_blueberry.py
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-from blueberry.tests.gd.cert import gd_base_test
-from shim.cert.stack_test_lib import StackTestBase
-from mobly import test_runner
-
-
-class StackTestBb(gd_base_test.GdBaseTestClass, StackTestBase):
-
- def setup_class(self):
- super().setup_class(dut_module='SHIM', cert_module='SHIM')
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/map/bluetooth_map_test.py b/blueberry/tests/map/bluetooth_map_test.py
deleted file mode 100644
index 11bee4e..0000000
--- a/blueberry/tests/map/bluetooth_map_test.py
+++ /dev/null
@@ -1,148 +0,0 @@
-"""Tests for blueberry.map.bluetooth_map."""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import queue
-import time
-
-from mobly import test_runner
-from mobly import signals
-from mobly import utils
-
-from blueberry.controllers import android_bt_target_device
-from blueberry.utils import blueberry_base_test
-
-_SMS_MSG_EVENT = 'SmsReceived'
-_MAP_MSG_EVENT = 'MapMessageReceived'
-
-_EVENT_TIMEOUT_SEC = 180
-_TEXT_LENGTH = 10
-_TEXT_COUNT = 5
-
-
-class BluetoothMapTest(blueberry_base_test.BlueberryBaseTest):
- """Test Class for Bluetooth MAP Test."""
-
- def setup_class(self):
- """Standard Mobly setup class."""
- super().setup_class()
- for device in self.android_devices:
- device.init_setup()
- device.sl4a_setup()
-
- # Primary phone which role is Message Server Equipment (MSE).
- self.pri_phone = self.android_devices[0]
- self.pri_phone.sl4a.smsStartTrackingIncomingSmsMessage()
- self.pri_number = self.pri_phone.dimensions['phone_number']
-
- # Secondary phone which is used to send SMS messages to primary phone.
- self.sec_phone = self.android_devices[1]
-
- # Bluetooth carkit which role is Message Client Equipment (MCE).
- self.derived_bt_device = self.derived_bt_devices[0]
-
- mac_address = self.derived_bt_device.get_bluetooth_mac_address()
- self.derived_bt_device.activate_pairing_mode()
- self.pri_phone.pair_and_connect_bluetooth(mac_address)
- # Sleep to make the connection to be steady.
- time.sleep(5)
-
- if isinstance(
- self.derived_bt_device, android_bt_target_device.AndroidBtTargetDevice):
- # Allow sl4a to receive the intent with ACTION_MESSAGE_RECEIVED.
- self.derived_bt_device.adb.shell(
- 'pm grant com.googlecode.android_scripting '
- 'android.permission.RECEIVE_SMS')
- # Connect derived bt device to primary phone via MAP MCE profile.
- self.derived_bt_device.add_sec_ad_device(self.pri_phone)
-
- def teardown_test(self):
- """Standard Mobly teardown test.
-
- Disconnects the MAP connection after a test completes.
- """
- super().teardown_test()
- self.derived_bt_device.map_disconnect()
-
- def _wait_for_message_on_mce(self, text):
- """Waits for that MCE gets an event with specific message.
-
- Args:
- text: String, Text of the message.
-
- Raises:
- TestFailure: Raised if timed out.
- """
- try:
- self.derived_bt_device.ed.wait_for_event(
- _MAP_MSG_EVENT, lambda e: e['data'] == text, _EVENT_TIMEOUT_SEC)
- self.derived_bt_device.log.info(
- 'Successfully got the unread message: %s' % text)
- except queue.Empty:
- raise signals.TestFailure(
- 'Timed out after %ds waiting for "%s" event with the message: %s' %
- (_EVENT_TIMEOUT_SEC, _MAP_MSG_EVENT, text))
-
- def _wait_for_message_on_mse(self, text):
- """Waits for that MSE gets an event with specific message.
-
- This method is used to make sure that MSE has received the test message.
-
- Args:
- text: String, Text of the message.
-
- Raises:
- TestError: Raised if timed out.
- """
- try:
- self.pri_phone.ed.wait_for_event(
- _SMS_MSG_EVENT, lambda e: e['data']['Text'] == text,
- _EVENT_TIMEOUT_SEC)
- self.pri_phone.log.info(
- 'Successfully received the incoming message: %s' % text)
- except queue.Empty:
- raise signals.TestError(
- 'Timed out after %ds waiting for "%s" event with the message: %s' %
- (_EVENT_TIMEOUT_SEC, _SMS_MSG_EVENT, text))
-
- def _create_message_on_mse(self, text):
- """Creates a new incoming message on MSE.
-
- Args:
- text: String, Text of the message.
- """
- self.sec_phone.sl4a.smsSendTextMessage(self.pri_number, text, False)
- self._wait_for_message_on_mse(text)
-
- def test_get_existing_unread_messages(self):
- """Test for the feature of getting existing unread messages on MCE.
-
- Tests MCE can list existing messages of MSE.
- """
- text_list = []
- # Creates 5 SMS messages on MSE before establishing connection.
- for _ in range(_TEXT_COUNT):
- text = utils.rand_ascii_str(_TEXT_LENGTH)
- self._create_message_on_mse(text)
- text_list.append(text)
- self.derived_bt_device.map_connect()
- # Gets the unread messages of MSE and checks if they are downloaded
- # successfully on MCE.
- self.derived_bt_device.get_unread_messages()
- for text in text_list:
- self._wait_for_message_on_mce(text)
-
- def test_receive_unread_message(self):
- """Test for the feature of receiving unread message on MCE.
-
- Tests MCE can get an unread message when MSE receives an incoming message.
- """
- self.derived_bt_device.map_connect()
- text = utils.rand_ascii_str(_TEXT_LENGTH)
- self._create_message_on_mse(text)
- self._wait_for_message_on_mce(text)
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/pan/bluetooth_pan_test.py b/blueberry/tests/pan/bluetooth_pan_test.py
deleted file mode 100644
index 062da8e..0000000
--- a/blueberry/tests/pan/bluetooth_pan_test.py
+++ /dev/null
@@ -1,325 +0,0 @@
-"""Tests for Bluetooth PAN profile functionalities."""
-
-import contextlib
-import time
-
-from mobly import test_runner
-from mobly import signals
-from mobly.controllers.android_device_lib import jsonrpc_client_base
-from blueberry.utils import blueberry_base_test
-from blueberry.utils import bt_test_utils
-
-# Timeout to wait for NAP service connection to be specific state in second.
-CONNECTION_TIMEOUT_SECS = 20
-
-# Interval time between ping requests in second.
-PING_INTERVAL_TIME_SEC = 2
-
-# Timeout to wait for ping success in second.
-PING_TIMEOUT_SEC = 60
-
-# A URL is used to verify internet by ping request.
-TEST_URL = 'http://www.google.com'
-
-# A string representing SIM State is ready.
-SIM_STATE_READY = 'READY'
-
-
-class BluetoothPanTest(blueberry_base_test.BlueberryBaseTest):
- """Test class for Bluetooth PAN(Personal Area Networking) profile.
-
- Test internet connection sharing via Bluetooth between two Android devices.
- One device which is referred to as NAP(Network Access Point) uses Bluetooth
- tethering to share internet connection with another device which is referred
- to as PANU(Personal Area Networking User).
- """
-
- def setup_class(self):
- """Standard Mobly setup class."""
- super(BluetoothPanTest, self).setup_class()
- # Number of attempts to initiate connection. 5 attempts as default.
- self.pan_connect_attempts = self.user_params.get('pan_connect_attempts', 5)
-
- for device in self.android_devices:
- device.init_setup()
- device.sl4a_setup()
- device.mac_address = device.get_bluetooth_mac_address()
-
- # Check if the device has inserted a SIM card.
- if device.sl4a.telephonyGetSimState() != SIM_STATE_READY:
- raise signals.TestError('SIM card is not ready on Device "%s".' %
- device.serial)
-
- self.primary_device = self.android_devices[0]
- self.secondary_device = self.android_devices[1]
-
- def teardown_test(self):
- """Standard Mobly teardown test.
-
- Reset every devices when a test finished.
- """
- super(BluetoothPanTest, self).teardown_test()
- # Revert debug tags.
- for device in self.android_devices:
- device.debug_tag = device.serial
- device.factory_reset_bluetooth()
-
- def wait_for_nap_service_connection(
- self,
- device,
- connected_mac_addr,
- state_connected=True):
- """Waits for NAP service connection to be expected state.
-
- Args:
- device: AndroidDevice, A device is used to check this connection.
- connected_mac_addr: String, Bluetooth Mac address is needed to be checked.
- state_connected: Bool, NAP service connection is established as expected
- if True, else terminated as expected.
-
- Raises:
- TestFailure: Raised if NAP service connection is not expected state.
- """
- def is_device_connected():
- """Returns True if connected else False."""
- connected_devices = (device.sl4a.
- bluetoothPanGetConnectedDevices())
- # Check if the Bluetooth mac address is in the connected device list.
- return connected_mac_addr in [d['address'] for d in connected_devices]
-
- bt_test_utils.wait_until(
- timeout_sec=CONNECTION_TIMEOUT_SECS,
- condition_func=is_device_connected,
- func_args=[],
- expected_value=state_connected,
- exception=signals.TestFailure(
- 'NAP service connection failed to be %s in %ds.' %
- ('established' if state_connected else 'terminated',
- CONNECTION_TIMEOUT_SECS)))
-
- def initiate_nap_service_connection(
- self,
- initiator_device,
- connected_mac_addr):
- """Initiates NAP service connection.
-
- Args:
- initiator_device: AndroidDevice, A device intiating connection.
- connected_mac_addr: String, Bluetooth Mac address of connected device.
-
- Raises:
- TestFailure: Raised if NAP service connection fails to be established.
- """
- count = 0
- for _ in range(self.pan_connect_attempts):
- count += 1
- try:
- initiator_device.sl4a.bluetoothConnectBonded(connected_mac_addr)
- self.wait_for_nap_service_connection(
- device=initiator_device,
- connected_mac_addr=connected_mac_addr,
- state_connected=True)
- return
- except signals.TestFailure:
- if count == self.pan_connect_attempts:
- raise signals.TestFailure(
- 'NAP service connection still failed to be established '
- 'after retried %d times.' %
- self.pan_connect_attempts)
-
- def terminate_nap_service_connection(
- self,
- initiator_device,
- connected_mac_addr):
- """Terminates NAP service connection.
-
- Args:
- initiator_device: AndroidDevice, A device intiating disconnection.
- connected_mac_addr: String, Bluetooth Mac address of connected device.
- """
- initiator_device.log.info('Terminate NAP service connection.')
- initiator_device.sl4a.bluetoothDisconnectConnected(connected_mac_addr)
- self.wait_for_nap_service_connection(
- device=initiator_device,
- connected_mac_addr=connected_mac_addr,
- state_connected=False)
-
- @contextlib.contextmanager
- def establish_nap_service_connection(self, nap_device, panu_device):
- """Establishes NAP service connection between both Android devices.
-
- The context is used to form a basic network connection between devices
- before executing a test.
-
- Steps:
- 1. Disable Mobile data to avoid internet access on PANU device.
- 2. Make sure Mobile data available on NAP device.
- 3. Enable Bluetooth from PANU device.
- 4. Enable Bluetooth tethering on NAP device.
- 5. Initiate a connection from PANU device.
- 6. Check if PANU device has internet access via the connection.
-
- Args:
- nap_device: AndroidDevice, A device sharing internet connection via
- Bluetooth tethering.
- panu_device: AndroidDevice, A device gaining internet access via
- Bluetooth tethering.
-
- Yields:
- None, the context just execute a pre procedure for PAN testing.
-
- Raises:
- signals.TestError: raised if a step fails.
- signals.TestFailure: raised if PANU device fails to access internet.
- """
- nap_device.debug_tag = 'NAP'
- panu_device.debug_tag = 'PANU'
- try:
- # Disable Mobile data to avoid internet access on PANU device.
- panu_device.log.info('Disabling Mobile data...')
- panu_device.sl4a.setMobileDataEnabled(False)
- self.verify_internet(
- allow_access=False,
- device=panu_device,
- exception=signals.TestError(
- 'PANU device "%s" still connected to internet when Mobile data '
- 'had been disabled.' % panu_device.serial))
-
- # Make sure NAP device has Mobile data for internet sharing.
- nap_device.log.info('Enabling Mobile data...')
- nap_device.sl4a.setMobileDataEnabled(True)
- self.verify_internet(
- allow_access=True,
- device=nap_device,
- exception=signals.TestError(
- 'NAP device "%s" did not have internet access when Mobile data '
- 'had been enabled.' % nap_device.serial))
-
- # Enable Bluetooth tethering from NAP device.
- nap_device.set_bluetooth_tethering(status_enabled=True)
- # Wait until Bluetooth tethering stabilizes. This waiting time avoids PANU
- # device initiates a connection to NAP device immediately when NAP device
- # enables Bluetooth tethering.
- time.sleep(5)
-
- nap_device.activate_pairing_mode()
- panu_device.log.info('Pair to NAP device "%s".' % nap_device.serial)
- panu_device.pair_and_connect_bluetooth(nap_device.mac_address)
-
- # Initiate a connection to NAP device.
- panu_device.log.info('Initiate a connection to NAP device "%s".' %
- nap_device.serial)
- self.initiate_nap_service_connection(
- initiator_device=panu_device,
- connected_mac_addr=nap_device.mac_address)
-
- # Check if PANU device can access internet via NAP service connection.
- self.verify_internet(
- allow_access=True,
- device=panu_device,
- exception=signals.TestFailure(
- 'PANU device "%s" failed to access internet via NAP service '
- 'connection.' % panu_device.serial))
- yield
- finally:
- # Disable Bluetooth tethering from NAP device.
- nap_device.set_bluetooth_tethering(status_enabled=False)
- panu_device.sl4a.setMobileDataEnabled(True)
-
- def verify_internet(self, allow_access, device, exception):
- """Verifies that internet is in expected state.
-
- Continuously make ping request to a URL for internet verification.
-
- Args:
- allow_access: Bool, Device can have internet access as expected if True,
- else no internet access as expected.
- device: AndroidDevice, Device to be check internet state.
- exception: Exception, Raised if internet is not in expected state.
- """
- device.log.info('Verify that internet %s be used.' %
- ('can' if allow_access else 'can not'))
-
- def http_ping():
- """Returns True if http ping success else False."""
- try:
- return bool(device.sl4a.httpPing(TEST_URL))
- except jsonrpc_client_base.ApiError as e:
- # ApiError is raised by httpPing() when no internet.
- device.log.debug(str(e))
- return False
-
- bt_test_utils.wait_until(
- timeout_sec=PING_TIMEOUT_SEC,
- condition_func=http_ping,
- func_args=[],
- expected_value=allow_access,
- exception=exception,
- interval_sec=PING_INTERVAL_TIME_SEC)
-
- def test_gain_internet_and_terminate_nap_connection(self):
- """Test that DUT can access internet and terminate NAP service connection.
-
- In this test case, primary device is PANU and secondary device is NAP. While
- a connection has established between both devices, PANU should be able to
- use internet and terminate the connection to disable internet access.
-
- Steps:
- 1. Establish NAP service connection between both devices.
- 2. Terminal the connection from PANU device.
- 3. Verify that PANU device cannot access internet.
- """
- with self.establish_nap_service_connection(
- nap_device=self.secondary_device,
- panu_device=self.primary_device):
-
- # Terminate the connection from DUT.
- self.terminate_nap_service_connection(
- initiator_device=self.primary_device,
- connected_mac_addr=self.secondary_device.mac_address)
-
- # Verify that PANU device cannot access internet.
- self.verify_internet(
- allow_access=False,
- device=self.primary_device,
- exception=signals.TestFailure(
- 'PANU device "%s" can still access internet when it had '
- 'terminated NAP service connection.' %
- self.primary_device.serial))
-
- def test_share_internet_and_disable_bluetooth_tethering(self):
- """Test that DUT can share internet and stop internet sharing.
-
- In this test case, primary device is NAP and secondary device is PANU. While
- a connection has established between both devices, NAP should be able to
- share internet and disable Bluetooth thethering to stop internet sharing.
-
- Steps:
- 1. Establish NAP service connection between both devices.
- 3. Disable Bluetooth tethering from NAP device.
- 4. Verify that PANU device cannot access internet.
- """
- with self.establish_nap_service_connection(
- nap_device=self.primary_device,
- panu_device=self.secondary_device):
-
- # Disable Bluetooth tethering from DUT and check if the nap connection is
- # terminated.
- self.primary_device.set_bluetooth_tethering(status_enabled=False)
- self.wait_for_nap_service_connection(
- device=self.primary_device,
- connected_mac_addr=self.secondary_device.mac_address,
- state_connected=False)
-
- # Verify that PANU device cannot access internet.
- self.verify_internet(
- allow_access=False,
- device=self.secondary_device,
- exception=signals.TestFailure(
- 'PANU device "%s" can still access internet when it had '
- 'terminated NAP service connection.' %
- self.secondary_device.serial))
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/pbap/bluetooth_pbap_test.py b/blueberry/tests/pbap/bluetooth_pbap_test.py
deleted file mode 100644
index 9c7c032..0000000
--- a/blueberry/tests/pbap/bluetooth_pbap_test.py
+++ /dev/null
@@ -1,401 +0,0 @@
-"""Tests for blueberry.pbap.bluetooth_pbap."""
-
-import os
-import random
-import time
-
-from mobly import asserts
-from mobly import test_runner
-from mobly import signals
-from mobly import utils
-
-from mobly.controllers import android_device
-
-from blueberry.utils import blueberry_base_test
-from blueberry.utils import bt_constants
-from blueberry.utils import bt_test_utils
-
-# The path is used to place the created vcf files.
-STORAGE_PATH = '/storage/emulated/0'
-
-# URI for contacts database.
-CONTACTS_URI = 'content://com.android.contacts/data/phones'
-
-# Number of seconds to wait for contacts and call logs update.
-WAITING_TIMEOUT_SEC = 60
-
-# Number of contacts and call logs to be tested.
-TEST_DATA_COUNT = 1000
-
-# Permissions for Contacts app.
-PERMISSION_LIST = [
- 'android.permission.READ_CONTACTS',
- 'android.permission.WRITE_CONTACTS',
-]
-
-
-class BluetoothPbapTest(blueberry_base_test.BlueberryBaseTest):
- """Test Class for Bluetooth PBAP Test."""
-
- def setup_class(self):
- """Standard Mobly setup class."""
- super(BluetoothPbapTest, self).setup_class()
-
- # Bluetooth carkit which role is Phone Book Client Equipment (PCE).
- self.derived_bt_device = self.derived_bt_devices[0]
-
- # Primary phone which role is Phone Book Server Equipment (PSE).
- self.pri_phone = self.android_devices[0]
- self.pri_phone.init_setup()
- self.pri_phone.sl4a_setup()
- self.derived_bt_device.add_sec_ad_device(self.pri_phone)
-
- # Grant the permissions to Contacts app.
- for device in [self.pri_phone, self.derived_bt_device]:
- required_permissions = PERMISSION_LIST
- # App requires READ_EXTERNAL_STORAGE to read contacts if SDK < 30.
- if int(device.build_info['build_version_sdk']) < 30:
- required_permissions.append('android.permission.READ_EXTERNAL_STORAGE')
- for permission in required_permissions:
- device.adb.shell('pm grant com.google.android.contacts %s' % permission)
- self.pse_mac_address = self.pri_phone.get_bluetooth_mac_address()
- mac_address = self.derived_bt_device.get_bluetooth_mac_address()
- self.derived_bt_device.activate_pairing_mode()
- self.pri_phone.pair_and_connect_bluetooth(mac_address)
- # Sleep until the connection stabilizes.
- time.sleep(5)
-
- # Allow permission access for PBAP profile.
- self.pri_phone.sl4a.bluetoothChangeProfileAccessPermission(
- mac_address,
- bt_constants.BluetoothProfile.PBAP.value,
- bt_constants.BluetoothAccessLevel.ACCESS_ALLOWED.value)
-
- def setup_test(self):
- super(BluetoothPbapTest, self).setup_test()
- # Make sure PBAP is not connected before running tests.
- self._terminate_pbap_connection()
-
- def _import_vcf_to_pse(self, file_name, expected_contact_count):
- """Imports the vcf file to PSE."""
- # Open ImportVcardActivity and click "OK" in the pop-up dialog, then
- # PickActivity will be launched and browses the existing vcf files.
- self.pri_phone.adb.shell(
- 'am start com.google.android.contacts/'
- 'com.google.android.apps.contacts.vcard.ImportVCardActivity')
- self.pri_phone.aud(text='OK').click()
-
- # Check if the vcf file appears in the PickActivity.
- if not self.pri_phone.aud(text=file_name).exists():
- raise android_device.DeviceError(
- self.pri_phone,
- 'No file name matches "%s" in PickActivity.' % file_name)
-
- # TODO(user): Remove the check of code name for S build.
- if (self.pri_phone.build_info['build_version_codename'] != 'S' and
- int(self.pri_phone.build_info['build_version_sdk']) <= 30):
- # Since `adb shell input tap` cannot work in PickActivity before R build,
- # send TAB and ENETER Key events to select and import the vcf file.
- if self.pri_phone.aud(content_desc='Grid view').exists():
- # Switch Grid mode since ENTER Key event cannot work in List mode on
- # git_rvc-d2-release branch.
- self.pri_phone.aud(content_desc='Grid view').click()
- self.pri_phone.aud.send_key_code('KEYCODE_TAB')
- self.pri_phone.aud.send_key_code('KEYCODE_ENTER')
- else:
- self.pri_phone.aud(text=file_name).click()
- self.pri_phone.log.info('Importing "%s"...' % file_name)
- current_count = self._wait_and_get_contact_count(
- self.pri_phone, expected_contact_count, WAITING_TIMEOUT_SEC)
- if current_count != expected_contact_count:
- raise android_device.DeviceError(
- self.pri_phone,
- 'Failed to import %d contact(s) within %ds. Actual count: %d' %
- (expected_contact_count, WAITING_TIMEOUT_SEC, current_count))
- self.pri_phone.log.info(
- 'Successfully added %d contact(s).' % current_count)
-
- def _generate_contacts_on_pse(self,
- num_of_contacts,
- first_name=None,
- last_name=None,
- phone_number=None):
- """Generates contacts to be tested on PSE."""
- vcf_file = bt_test_utils.create_vcf_from_vcard(
- output_path=self.pri_phone.log_path,
- num_of_contacts=num_of_contacts,
- first_name=first_name,
- last_name=last_name,
- phone_number=phone_number)
- self.pri_phone.adb.push([vcf_file, STORAGE_PATH])
- # For R build, since the pushed vcf file probably not found when importing
- # contacts, do a media scan to recognize the file.
- if int(self.pri_phone.build_info['build_version_sdk']) > 29:
- self.pri_phone.adb.shell('content call --uri content://media/ --method '
- 'scan_volume --arg external_primary')
- file_name = vcf_file.split('/')[-1]
- self._import_vcf_to_pse(file_name, num_of_contacts)
- self.pri_phone.adb.shell(
- 'rm -rf %s' % os.path.join(STORAGE_PATH, file_name))
-
- def _generate_call_logs_on_pse(self, call_log_type, num_of_call_logs):
- """Generates call logs to be tested on PSE."""
- self.pri_phone.log.info('Putting %d call log(s) which type are "%s"...' %
- (num_of_call_logs, call_log_type))
- for _ in range(num_of_call_logs):
- self.pri_phone.sl4a.callLogsPut(dict(
- type=call_log_type,
- number='8809%d' % random.randrange(int(10e8)),
- time=int(1000 * float(self.pri_phone.adb.shell('date +%s.%N')))))
- current_count = self._wait_and_get_call_log_count(
- self.pri_phone,
- call_log_type,
- num_of_call_logs,
- WAITING_TIMEOUT_SEC)
- if current_count != num_of_call_logs:
- raise android_device.DeviceError(
- self.pri_phone,
- 'Failed to generate %d call log(s) within %ds. '
- 'Actual count: %d, Call log type: %s' %
- (num_of_call_logs, WAITING_TIMEOUT_SEC, current_count, call_log_type))
- self.pri_phone.log.info(
- 'Successfully added %d call log(s).' % current_count)
-
- def _wait_and_get_contact_count(self,
- device,
- expected_contact_count,
- timeout_sec):
- """Waits for contact update for a period time and returns contact count.
-
- This method should be used when a device imports some new contacts. It can
- wait some time for contact update until expectation or timeout and then
- return contact count.
-
- Args:
- device: AndroidDevice, Mobly Android controller class.
- expected_contact_count: Int, Number of contacts as expected.
- timeout_sec: Int, Number of seconds to wait for contact update.
-
- Returns:
- current_count: Int, number of the existing contacts on the device.
- """
- start_time = time.time()
- end_time = start_time + timeout_sec
- current_count = 0
- while time.time() < end_time:
- current_count = device.sl4a.contactsGetCount()
- if current_count == expected_contact_count:
- break
- # Interval between attempts to get contacts.
- time.sleep(1)
- if current_count != expected_contact_count:
- device.log.warning(
- 'Failed to get expected contact count: %d. '
- 'Actual contact count: %d.' %
- (expected_contact_count, current_count))
- return current_count
-
- def _wait_and_get_call_log_count(self,
- device,
- call_log_type,
- expected_call_log_count,
- timeout_sec):
- """Waits for call log update for a period time and returns call log count.
-
- This method should be used when a device adds some new call logs. It can
- wait some time for call log update until expectation or timeout and then
- return call log count.
-
- Args:
- device: AndroidDevice, Mobly Android controller class.
- call_log_type: String, Type of the call logs.
- expected_call_log_count: Int, Number of call logs as expected.
- timeout_sec: Int, Number of seconds to wait for call log update.
-
- Returns:
- current_count: Int, number of the existing call logs on the device.
- """
- start_time = time.time()
- end_time = start_time + timeout_sec
- current_count = 0
- while time.time() < end_time:
- current_count = len(device.sl4a.callLogsGet(call_log_type))
- if current_count == expected_call_log_count:
- break
- # Interval between attempts to get call logs.
- time.sleep(1)
- if current_count != expected_call_log_count:
- device.log.warning(
- 'Failed to get expected call log count: %d. '
- 'Actual call log count: %d.' %
- (expected_call_log_count, current_count))
- return current_count
-
- def _terminate_pbap_connection(self):
- status = self.derived_bt_device.sl4a.bluetoothPbapClientGetConnectionStatus(
- self.pse_mac_address)
- if status == bt_constants.BluetoothConnectionStatus.STATE_DISCONNECTED:
- return
- self.derived_bt_device.log.info('Disconnecting PBAP...')
- self.derived_bt_device.sl4a.bluetoothPbapClientDisconnect(
- self.pse_mac_address)
- # Buffer for the connection status check.
- time.sleep(3)
- status = self.derived_bt_device.sl4a.bluetoothPbapClientGetConnectionStatus(
- self.pse_mac_address)
- if status != bt_constants.BluetoothConnectionStatus.STATE_DISCONNECTED:
- raise signals.TestError('PBAP connection failed to be terminated.')
- self.derived_bt_device.log.info('Successfully disconnected PBAP.')
-
- def test_download_contacts(self):
- """Test for the feature of downloading contacts.
-
- Tests that PCE can download contacts from PSE.
- """
- # Make sure no any contacts exist on the devices.
- for device in [self.pri_phone, self.derived_bt_device]:
- device.sl4a.contactsEraseAll()
-
- # Add contacts to PSE.
- self._generate_contacts_on_pse(TEST_DATA_COUNT)
-
- # When PCE is connected to PSE, it will download PSE's contacts.
- self.derived_bt_device.pbap_connect()
- self.derived_bt_device.log.info('Downloading contacts from PSE...')
- current_count = self._wait_and_get_contact_count(
- self.derived_bt_device, TEST_DATA_COUNT, WAITING_TIMEOUT_SEC)
- self.derived_bt_device.log.info(
- 'Successfully downloaded %d contact(s).' % current_count)
-
- asserts.assert_true(
- current_count == TEST_DATA_COUNT,
- 'PCE failed to download %d contact(s) within %ds, '
- 'actually downloaded %d contact(s).' %
- (TEST_DATA_COUNT, WAITING_TIMEOUT_SEC, current_count))
-
- def test_download_call_logs(self):
- """Test for the feature of downloading call logs.
-
- Tests that PCE can download incoming/outgoing/missed call logs from PSE.
- """
- # Make sure no any call logs exist on the devices.
- for device in [self.pri_phone, self.derived_bt_device]:
- device.sl4a.callLogsEraseAll()
-
- call_log_types = [
- bt_constants.INCOMING_CALL_LOG_TYPE,
- bt_constants.OUTGOING_CALL_LOG_TYPE,
- bt_constants.MISSED_CALL_LOG_TYPE,
- ]
- for call_log_type in call_log_types:
- # Add call logs to PSE.
- self._generate_call_logs_on_pse(call_log_type, TEST_DATA_COUNT)
-
- # When PCE is connected to PSE, it will download PSE's contacts.
- self.derived_bt_device.pbap_connect()
- self.derived_bt_device.log.info('Downloading call logs...')
-
- for call_log_type in call_log_types:
- current_count = self._wait_and_get_call_log_count(
- self.derived_bt_device,
- call_log_type,
- TEST_DATA_COUNT,
- WAITING_TIMEOUT_SEC)
- self.derived_bt_device.log.info(
- 'Successfully downloaded %d call log(s) which type are "%s".' %
- (current_count, call_log_type))
-
- asserts.assert_true(
- current_count == TEST_DATA_COUNT,
- 'PCE failed to download %d call log(s) which type are "%s" within %ds'
- ', actually downloaded %d call log(s).' %
- (TEST_DATA_COUNT, call_log_type, WAITING_TIMEOUT_SEC, current_count))
-
- def test_show_caller_name(self):
- """Test for caller name of the incoming phone call is correct on PCE.
-
- Tests that caller name matches contact name which is downloaded via PBAP.
- """
- # Checks if two android devices exist.
- if len(self.android_devices) < 2:
- raise signals.TestError('This test requires two Android devices.')
- primary_phone = self.pri_phone
- secondary_phone = self.android_devices[1]
- secondary_phone.init_setup()
- for phone in [primary_phone, secondary_phone]:
- # Checks if SIM state is loaded for every devices.
- if not phone.is_sim_state_loaded():
- raise signals.TestError(f'Please insert a SIM Card to the phone '
- f'"{phone.serial}".')
- # Checks if phone_number is provided in the support dimensions.
- phone.phone_number = phone.dimensions.get('phone_number')
- if not phone.phone_number:
- raise signals.TestError(f'Please add "phone_number" to support '
- f'dimensions of the phone "{phone.serial}".')
- # Make sure no any contacts exist on the devices.
- for device in [primary_phone, self.derived_bt_device]:
- device.sl4a.contactsEraseAll()
- # Generate a contact name randomly.
- first_name = utils.rand_ascii_str(4)
- last_name = utils.rand_ascii_str(4)
- full_name = f'{first_name} {last_name}'
- primary_phone.log.info('Creating a contact "%s"...', full_name)
- self._generate_contacts_on_pse(
- num_of_contacts=1,
- first_name=first_name,
- last_name=last_name,
- phone_number=secondary_phone.phone_number)
- self.derived_bt_device.log.info('Connecting to PSE...')
- self.derived_bt_device.pbap_connect()
- self.derived_bt_device.log.info('Downloading contacts from PSE...')
- current_count = self._wait_and_get_contact_count(
- device=self.derived_bt_device,
- expected_contact_count=1,
- timeout_sec=WAITING_TIMEOUT_SEC)
- self.derived_bt_device.log.info('Successfully downloaded %d contact(s).',
- current_count)
- asserts.assert_equal(
- first=current_count,
- second=1,
- msg=f'Failed to download the contact "{full_name}".')
- secondary_phone.sl4a.telecomCallNumber(primary_phone.phone_number)
- secondary_phone.log.info('Made a phone call to device "%s".',
- primary_phone.serial)
- primary_phone.log.info('Waiting for the incoming call from device "%s"...',
- secondary_phone.serial)
- is_ringing = primary_phone.wait_for_call_state(
- bt_constants.CALL_STATE_RINGING,
- bt_constants.CALL_STATE_TIMEOUT_SEC)
- if not is_ringing:
- raise signals.TestError(
- f'Timed out after {bt_constants.CALL_STATE_TIMEOUT_SEC}s waiting for '
- f'the incoming call from device "{secondary_phone.serial}".')
- try:
- self.derived_bt_device.aud.open_notification()
- target_node_match_dict = {
- 'resource_id': 'android:id/line1',
- 'child': {
- 'resource_id': 'android:id/title'
- }
- }
- hfp_address = primary_phone.get_bluetooth_mac_address()
- target_node = self.derived_bt_device.aud(
- sibling=target_node_match_dict,
- text=f'Incoming call via HFP {hfp_address}')
- caller_name = target_node.get_attribute_value('text')
- message = (f'Caller name is incorrect. Actual: {caller_name}, '
- f'Correct: {full_name}')
- # Asserts that caller name of the incoming phone call is correct in the
- # notification bar.
- asserts.assert_equal(
- first=caller_name,
- second=full_name,
- msg=message)
- finally:
- # Recovery actions.
- self.derived_bt_device.aud.close_notification()
- secondary_phone.sl4a.telecomEndCall()
-
-
-if __name__ == '__main__':
- test_runner.main()
diff --git a/blueberry/tests/pbat/bluetooth_acceptance_suite.py b/blueberry/tests/pbat/bluetooth_acceptance_suite.py
deleted file mode 100644
index faa1151..0000000
--- a/blueberry/tests/pbat/bluetooth_acceptance_suite.py
+++ /dev/null
@@ -1,71 +0,0 @@
-"""Suite collecting bluetooth test classes for acceptance testing."""
-
-import logging
-
-from mobly import test_runner_suite
-
-from blueberry.tests.a2dp import bluetooth_a2dp_test
-from blueberry.tests.avrcp import bluetooth_avrcp_test
-from blueberry.tests.connectivity import ble_pairing_test
-from blueberry.tests.connectivity import bluetooth_pairing_test
-from blueberry.tests.hfp import bluetooth_hfp_test
-from blueberry.tests.map import bluetooth_map_test
-from blueberry.tests.opp import bluetooth_opp_test
-from blueberry.tests.pan import bluetooth_pan_test
-from blueberry.tests.pbap import bluetooth_pbap_test
-
-# Test classes for the Bluetooth acceptance suite.
-TEST_CLASSES = [
- bluetooth_pairing_test.BluetoothPairingTest,
- ble_pairing_test.BlePairingTest,
- bluetooth_a2dp_test.BluetoothA2dpTest,
- bluetooth_avrcp_test.BluetoothAvrcpTest,
- bluetooth_hfp_test.BluetoothHfpTest,
- bluetooth_map_test.BluetoothMapTest,
- bluetooth_pbap_test.BluetoothPbapTest,
- bluetooth_opp_test.BluetoothOppTest,
- bluetooth_pan_test.BluetoothPanTest
-]
-
-
-class BluetoothAcceptanceSuite(mobly_g3_suite.BaseSuite):
- """Bluetooth Acceptance Suite.
-
- Usage of Test selector:
- Add the parameter "acceptance_test_selector" in the Mobly configuration, it's
- value is like "test_method_1,test_method_2,...". If this parameter is not
- used, all tests will be running.
- """
-
- def setup_suite(self, config):
- selected_tests = None
- selector = config.user_params.get('acceptance_test_selector')
- if selector:
- selected_tests = selector.split(',')
- logging.info('Selected tests: %s', ' '.join(selected_tests))
- # Enable all Bluetooth logging in the first test.
- first_test_config = config.copy()
- first_test_config.user_params.update({
- 'enable_all_bluetooth_logging': 1,
- })
- for index, clazz in enumerate(TEST_CLASSES):
- if selected_tests:
- matched_tests = None
- # Gets the same elements between selected_tests and dir(clazz).
- matched_tests = list(set(selected_tests) & set(dir(clazz)))
- # Adds the test class if it contains the selected tests.
- if matched_tests:
- self.add_test_class(
- clazz=clazz,
- config=first_test_config if index == 0 else config,
- tests=matched_tests)
- logging.info('Added the tests of "%s": %s', clazz.__name__,
- ' '.join(matched_tests))
- else:
- self.add_test_class(
- clazz=clazz,
- config=first_test_config if index == 0 else config)
-
-
-if __name__ == '__main__':
- mobly_g3_suite.main()
diff --git a/blueberry/utils/android_bluetooth_decorator.py b/blueberry/utils/android_bluetooth_decorator.py
deleted file mode 100644
index c570897..0000000
--- a/blueberry/utils/android_bluetooth_decorator.py
+++ /dev/null
@@ -1,1729 +0,0 @@
-# Lint as: python3
-"""AndroidBluetoothDecorator class.
-
-This decorator is used for giving an AndroidDevice Bluetooth-specific
-functionality.
-"""
-
-import datetime
-import logging
-import os
-import queue
-import random
-import re
-import string
-import time
-from typing import Dict, Any, Text, Optional, Tuple, Sequence, Union
-from mobly import asserts
-from mobly import logger as mobly_logger
-from mobly import signals
-from mobly import utils
-from mobly.controllers.android_device import AndroidDevice
-from mobly.controllers.android_device_lib import adb
-from mobly.controllers.android_device_lib import jsonrpc_client_base
-from mobly.controllers.android_device_lib.services import sl4a_service
-# Internal import
-from blueberry.controllers.derived_bt_device import BtDevice
-from blueberry.utils import bt_constants
-from blueberry.utils import bt_test_utils
-from blueberry.utils.bt_constants import AvrcpEvent
-from blueberry.utils.bt_constants import BluetoothConnectionPolicy
-from blueberry.utils.bt_constants import BluetoothConnectionStatus
-from blueberry.utils.bt_constants import BluetoothProfile
-from blueberry.utils.bt_constants import CallLogType
-from blueberry.utils.bt_constants import CallState
-
-
-# Map for media passthrough commands and the corresponding events.
-MEDIA_CMD_MAP = {
- bt_constants.CMD_MEDIA_PAUSE: bt_constants.EVENT_PAUSE_RECEIVED,
- bt_constants.CMD_MEDIA_PLAY: bt_constants.EVENT_PLAY_RECEIVED,
- bt_constants.CMD_MEDIA_SKIP_PREV: bt_constants.EVENT_SKIP_PREV_RECEIVED,
- bt_constants.CMD_MEDIA_SKIP_NEXT: bt_constants.EVENT_SKIP_NEXT_RECEIVED
-}
-
-# Timeout for track change and playback state update in second.
-MEDIA_UPDATE_TIMEOUT_SEC = 3
-
-# Timeout for the event of Media passthrough commands in second.
-MEDIA_EVENT_TIMEOUT_SEC = 1
-
-BT_CONNECTION_WAITING_TIME_SECONDS = 10
-
-ADB_WAITING_TIME_SECONDS = 1
-
-# Common timeout for toggle status in seconds.
-COMMON_TIMEOUT_SECONDS = 5
-
-# Local constant
-_DATETIME_FMT = '%m-%d %H:%M:%S.%f'
-
-# Interval time between ping requests in second.
-PING_INTERVAL_TIME_SEC = 2
-
-# Timeout to wait for ping success in second.
-PING_TIMEOUT_SEC = 60
-
-# A URL is used to verify internet by ping request.
-TEST_URL = 'http://www.google.com'
-
-
-class DiscoveryError(signals.ControllerError):
- """Exception raised for Bluetooth device discovery failures."""
- pass
-
-
-class AndroidBluetoothDecorator(AndroidDevice):
- """Decorates an AndroidDevice with Bluetooth-specific functionality."""
-
- def __init__(self, ad: AndroidDevice):
- self._ad = ad
- self._user_params = None
- if not self._ad or not isinstance(self._ad, AndroidDevice):
- raise TypeError('Must apply AndroidBluetoothDecorator to an '
- 'AndroidDevice')
- self.ble_advertise_callback = None
- self.regex_logcat_time = re.compile(
- r'(?P<datetime>[\d]{2}-[\d]{2} [\d]{2}:[\d]{2}:[\d]{2}.[\d]{3})'
- r'[ ]+\d+.*')
- self._regex_bt_crash = re.compile(
- r'Bluetooth crashed (?P<num_bt_crashes>\d+) times')
-
- def __getattr__(self, name: Any) -> Any:
- return getattr(self._ad, name)
-
- def _is_device_connected(self, mac_address):
- """Wrapper method to help with unit testability of this class."""
- return self._ad.sl4a.bluetoothIsDeviceConnected(mac_address)
-
- def _is_profile_connected(self, mac_address, profile):
- """Checks if the profile is connected."""
- status = None
- pri_ad = self._ad
- if profile == BluetoothProfile.HEADSET_CLIENT:
- status = pri_ad.sl4a.bluetoothHfpClientGetConnectionStatus(mac_address)
- elif profile == BluetoothProfile.A2DP_SINK:
- status = pri_ad.sl4a.bluetoothA2dpSinkGetConnectionStatus(mac_address)
- elif profile == BluetoothProfile.PBAP_CLIENT:
- status = pri_ad.sl4a.bluetoothPbapClientGetConnectionStatus(mac_address)
- elif profile == BluetoothProfile.MAP_MCE:
- connected_devices = self._ad.sl4a.bluetoothMapClientGetConnectedDevices()
- return any(
- mac_address in device['address'] for device in connected_devices)
- else:
- pri_ad.log.warning(
- 'The connection check for profile %s is not supported '
- 'yet', profile)
- return False
- return status == BluetoothConnectionStatus.STATE_CONNECTED
-
- def _get_bluetooth_le_state(self):
- """Wrapper method to help with unit testability of this class."""
- return self._ad.sl4a.bluetoothGetLeState
-
- def _generate_id_by_size(self, size):
- """Generate string of random ascii letters and digits.
-
- Args:
- size: required size of string.
-
- Returns:
- String of random chars.
- """
- return ''.join(
- random.choice(string.ascii_letters + string.digits)
- for _ in range(size))
-
- def _wait_for_bluetooth_manager_state(self,
- state=None,
- timeout=10,
- threshold=5):
- """Waits for Bluetooth normalized state or normalized explicit state.
-
- Args:
- state: expected Bluetooth state
- timeout: max timeout threshold
- threshold: list len of bt state
- Returns:
- True if successful, false if unsuccessful.
- """
- all_states = []
- start_time = time.time()
- while time.time() < start_time + timeout:
- all_states.append(self._get_bluetooth_le_state())
- if len(all_states) >= threshold:
- # for any normalized state
- if state is None:
- if len(all_states[-threshold:]) == 1:
- logging.info('State normalized %s', all_states[-threshold:])
- return True
- else:
- # explicit check against normalized state
- if state in all_states[-threshold:]:
- return True
- time.sleep(0.5)
- logging.error(
- 'Bluetooth state fails to normalize' if state is None else
- 'Failed to match bluetooth state, current state {} expected state {}'
- .format(self._get_bluetooth_le_state(), state))
- return False
-
- def init_setup(self) -> None:
- """Sets up android device for bluetooth tests."""
- self._ad.services.register('sl4a', sl4a_service.Sl4aService)
- self._ad.load_snippet('mbs', 'com.google.android.mobly.snippet.bundled')
- self._ad.adb.shell('setenforce 0')
-
- # Adds 2 seconds waiting time to see it can fix the NullPointerException
- # when executing the following sl4a.bluetoothStartPairingHelper method.
- time.sleep(2)
- self._ad.sl4a.bluetoothStartPairingHelper()
- self.factory_reset_bluetooth()
-
- def sl4a_setup(self) -> None:
- """A common setup routine for android device sl4a function.
-
- Things this method setup:
- 1. Set Bluetooth local name to random string of size 4
- 2. Disable BLE background scanning.
- """
-
- sl4a = self._ad.sl4a
- sl4a.bluetoothStartConnectionStateChangeMonitor('')
- setup_result = sl4a.bluetoothSetLocalName(self._generate_id_by_size(4))
- if not setup_result:
- self.log.error('Failed to set device name.')
- return
- sl4a.bluetoothDisableBLE()
- bonded_devices = sl4a.bluetoothGetBondedDevices()
- for b in bonded_devices:
- self.log.info('Removing bond for device {}'.format(b['address']))
- sl4a.bluetoothUnbond(b['address'])
-
- def set_user_params(self, params: Dict[str, Any]) -> None:
- self._user_params = params
-
- def get_user_params(self) -> Dict[str, Any]:
- return self._user_params
-
- def is_sim_state_loaded(self) -> bool:
- """Checks if SIM state is loaded.
-
- Returns:
- True if SIM state is loaded else False.
- """
- state = self._ad.adb.shell('getprop gsm.sim.state').decode().strip()
- return state == 'LOADED'
-
- def is_package_installed(self, package_name: str) -> bool:
- """Checks if a package is installed.
-
- Args:
- package_name: string, a package to be checked.
-
- Returns:
- True if the package is installed else False.
- """
- # The package is installed if result is 1, not installed if result is 0.
- result = int(self._ad.adb.shell('pm list packages | grep -i %s$ | wc -l' %
- package_name))
- return bool(result)
-
- def connect_with_rfcomm(self, other_ad: AndroidDevice) -> bool:
- """Establishes an RFCOMM connection with other android device.
-
- Connects this android device (as a client) to the other android device
- (as a server).
-
- Args:
- other_ad: the Android device accepting the connection from this device.
-
- Returns:
- True if connection was successful, False if unsuccessful.
- """
- server_address = other_ad.sl4a.bluetoothGetLocalAddress()
- logging.info('Pairing and connecting devices')
- if not self._ad.sl4a.bluetoothDiscoverAndBond(server_address):
- logging.info('Failed to pair and connect devices')
- return False
-
- # Create RFCOMM connection
- logging.info('establishing RFCOMM connection')
- return self.orchestrate_rfcomm_connection(other_ad)
-
- def orchestrate_rfcomm_connection(
- self,
- other_ad: AndroidDevice,
- accept_timeout_ms: int = bt_constants.DEFAULT_RFCOMM_TIMEOUT_MS,
- uuid: Optional[Text] = None) -> bool:
- """Sets up the RFCOMM connection to another android device.
-
- It sets up the connection with a Bluetooth Socket connection with other
- device.
-
- Args:
- other_ad: the Android device accepting the connection from this device.
- accept_timeout_ms: the timeout in ms for the connection.
- uuid: universally unique identifier.
-
- Returns:
- True if connection was successful, False if unsuccessful.
- """
- if uuid is None:
- uuid = bt_constants.BT_RFCOMM_UUIDS['default_uuid']
- other_ad.sl4a.bluetoothStartPairingHelper()
- self._ad.sl4a.bluetoothStartPairingHelper()
- other_ad.sl4a.bluetoothSocketConnBeginAcceptThreadUuid(uuid,
- accept_timeout_ms)
- self._ad.sl4a.bluetoothSocketConnBeginConnectThreadUuid(
- other_ad.sl4a.bluetoothGetLocalAddress(), uuid)
-
- end_time = time.time() + bt_constants.BT_DEFAULT_TIMEOUT_SECONDS
- test_result = True
-
- while time.time() < end_time:
- number_socket_connections = len(
- other_ad.sl4a.bluetoothSocketConnActiveConnections())
- connected = number_socket_connections > 0
- if connected:
- test_result = True
- other_ad.log.info('Bluetooth socket Client Connection Active')
- break
- else:
- test_result = False
- time.sleep(1)
- if not test_result:
- other_ad.log.error('Failed to establish a Bluetooth socket connection')
- return False
- return True
-
- def wait_for_discovery_success(
- self,
- mac_address: str,
- timeout: float = 30) -> float:
- """Waits for a device to be discovered by AndroidDevice.
-
- Args:
- mac_address: The Bluetooth mac address of the peripheral device.
- timeout: Number of seconds to wait for device discovery.
-
- Returns:
- discovery_time: The time it takes to pair in seconds.
-
- Raises:
- DiscoveryError
- """
- start_time = time.time()
- try:
- self._ad.ed.wait_for_event('Discovery%s' % mac_address,
- lambda x: x['data']['Status'], timeout)
- discovery_time = time.time() - start_time
- return discovery_time
-
- except queue.Empty:
- raise DiscoveryError('Failed to discover device %s after %d seconds' %
- (mac_address, timeout))
-
- def wait_for_pairing_success(
- self,
- mac_address: str,
- timeout: float = 30) -> float:
- """Waits for a device to pair with the AndroidDevice.
-
- Args:
- mac_address: The Bluetooth mac address of the peripheral device.
- timeout: Number of seconds to wait for the devices to pair.
-
- Returns:
- pairing_time: The time it takes to pair in seconds.
-
- Raises:
- ControllerError
- """
- start_time = time.time()
- try:
- self._ad.ed.wait_for_event('Bond%s' % mac_address,
- lambda x: x['data']['Status'], timeout)
- pairing_time = time.time() - start_time
- return pairing_time
-
- except queue.Empty:
- raise signals.ControllerError(
- 'Failed to bond with device %s after %d seconds' %
- (mac_address, timeout))
-
- def wait_for_connection_success(
- self,
- mac_address: str,
- timeout: int = 30) -> float:
- """Waits for a device to connect with the AndroidDevice.
-
- Args:
- mac_address: The Bluetooth mac address of the peripheral device.
- timeout: Number of seconds to wait for the devices to connect.
-
- Returns:
- connection_time: The time it takes to connect in seconds.
-
- Raises:
- ControllerError
- """
- start_time = time.time()
- end_time = start_time + timeout
- while time.time() < end_time:
- if self._is_device_connected(mac_address):
- connection_time = (time.time() - start_time)
- logging.info('Connected device %s in %d seconds', mac_address,
- connection_time)
- return connection_time
-
- raise signals.ControllerError(
- 'Failed to connect device within %d seconds.' % timeout)
-
- def factory_reset_bluetooth(self) -> None:
- """Factory resets Bluetooth on an AndroidDevice."""
-
- logging.info('Factory resetting Bluetooth for AndroidDevice.')
- self._ad.sl4a.bluetoothToggleState(True)
- paired_devices = self._ad.mbs.btGetPairedDevices()
- for device in paired_devices:
- self._ad.sl4a.bluetoothUnbond(device['Address'])
- self._ad.sl4a.bluetoothFactoryReset()
- self._wait_for_bluetooth_manager_state()
- self._ad.sl4a.bluetoothToggleState(True)
-
- def get_device_info(self) -> Dict[str, Any]:
- """Gets the configuration info of an AndroidDevice.
-
- Returns:
- dict, A dictionary mapping metric keys to their respective values.
- """
-
- device_info = {
- 'device_class':
- 'AndroidDevice',
- 'device_model':
- self._ad.device_info['model'],
- 'hardware_version':
- self._ad.adb.getprop('ro.boot.hardware.revision'),
- 'software_version':
- self._ad.build_info['build_id'],
- 'android_build_type':
- self._ad.build_info['build_type'],
- 'android_build_number':
- self._ad.adb.getprop('ro.build.version.incremental'),
- 'android_release_id':
- self._ad.build_info['build_id']
- }
-
- return device_info
-
- def pair_and_connect_bluetooth(
- self,
- mac_address: str,
- attempts: int = 3,
- enable_pairing_retry: bool = True) -> Tuple[float, float]:
- """Pairs and connects an AndroidDevice with a peripheral Bluetooth device.
-
- Ensures that an AndroidDevice is paired and connected to a peripheral
- device. If the devices are already connected, does nothing. If
- the devices are paired but not connected, connects the devices. If the
- devices are neither paired nor connected, this method pairs and connects the
- devices.
-
- Suggests to use the retry mechanism on Discovery because it sometimes fail
- even if the devices are testing in shielding. In order to avoid the remote
- device may not respond a incoming pairing request causing to bonding failure
- , it suggests to retry pairing too.
-
- Args:
- mac_address: The Bluetooth mac address of the peripheral device.
- attempts: Number of attempts to discover and pair the peripheral device.
- enable_pairing_retry: Bool to control whether the retry mechanism is used
- on bonding failure, it's enabled if True.
-
- Returns:
- pairing_time: The time, in seconds, it takes to pair the devices.
- connection_time: The time, in seconds, it takes to connect the
- devices after pairing is completed.
-
- Raises:
- DiscoveryError: Raised if failed to discover the peripheral device.
- ControllerError: Raised if failed to bond the peripheral device.
- """
-
- connected = self._is_device_connected(mac_address)
- pairing_time = 0
- connection_time = 0
- if connected:
- logging.info('Device %s already paired and connected', mac_address)
- return pairing_time, connection_time
-
- paired_devices = [device['address'] for device in
- self._ad.sl4a.bluetoothGetBondedDevices()]
- if mac_address in paired_devices:
- self._ad.sl4a.bluetoothConnectBonded(mac_address)
- return pairing_time, self.wait_for_connection_success(mac_address)
-
- logging.info('Initiate pairing to the device "%s".', mac_address)
- for i in range(attempts):
- self._ad.sl4a.bluetoothDiscoverAndBond(mac_address)
- try:
- self.wait_for_discovery_success(mac_address)
- pairing_time = self.wait_for_pairing_success(mac_address)
- break
- except DiscoveryError:
- if i + 1 < attempts:
- logging.error(
- 'Failed to find the device "%s" on Attempt %d. '
- 'Retrying discovery...', mac_address, i + 1)
- continue
- raise DiscoveryError('Failed to find the device "%s".' % mac_address)
- except signals.ControllerError:
- if i + 1 < attempts and enable_pairing_retry:
- logging.error(
- 'Failed to bond the device "%s" on Attempt %d. '
- 'Retrying pairing...', mac_address, i + 1)
- continue
- raise signals.ControllerError('Failed to bond the device "%s".' %
- mac_address)
-
- connection_time = self.wait_for_connection_success(mac_address)
- return pairing_time, connection_time
-
- def disconnect_bluetooth(
- self,
- mac_address: str,
- timeout: float = 30) -> float:
- """Disconnects Bluetooth between an AndroidDevice and peripheral device.
-
- Args:
- mac_address: The Bluetooth mac address of the peripheral device.
- timeout: Number of seconds to wait for the devices to disconnect the
- peripheral device.
-
- Returns:
- disconnection_time: The time, in seconds, it takes to disconnect the
- peripheral device.
-
- Raises:
- ControllerError: Raised if failed to disconnect the peripheral device.
- """
- if not self._is_device_connected(mac_address):
- logging.info('Device %s already disconnected', mac_address)
- return 0
-
- self._ad.sl4a.bluetoothDisconnectConnected(mac_address)
- start_time = time.time()
- end_time = time.time() + timeout
- while time.time() < end_time:
- connected = self._is_device_connected(mac_address)
- if not connected:
- logging.info('Device %s disconnected successfully.', mac_address)
- return time.time() - start_time
-
- raise signals.ControllerError(
- 'Failed to disconnect device within %d seconds.' % timeout)
-
- def connect_bluetooth(self, mac_address: str, timeout: float = 30) -> float:
- """Connects Bluetooth between an AndroidDevice and peripheral device.
-
- Args:
- mac_address: The Bluetooth mac address of the peripheral device.
- timeout: Number of seconds to wait for the devices to connect the
- peripheral device.
-
- Returns:
- connection_time: The time, in seconds, it takes to connect the
- peripheral device.
-
- Raises:
- ControllerError: Raised if failed to connect the peripheral device.
- """
- if self._is_device_connected(mac_address):
- logging.info('Device %s already connected', mac_address)
- return 0
-
- self._ad.sl4a.bluetoothConnectBonded(mac_address)
- connect_time = self.wait_for_connection_success(mac_address)
-
- return connect_time
-
- def activate_pairing_mode(self) -> None:
- """Activates pairing mode on an AndroidDevice."""
- logging.info('Activating pairing mode on AndroidDevice.')
- self._ad.sl4a.bluetoothMakeDiscoverable()
- self._ad.sl4a.bluetoothStartPairingHelper()
-
- def activate_ble_pairing_mode(self) -> None:
- """Activates BLE pairing mode on an AndroidDevice."""
- self.ble_advertise_callback = self._ad.sl4a.bleGenBleAdvertiseCallback()
- self._ad.sl4a.bleSetAdvertiseDataIncludeDeviceName(True)
- # Sets advertise mode to low latency.
- self._ad.sl4a.bleSetAdvertiseSettingsAdvertiseMode(
- bt_constants.BleAdvertiseSettingsMode.LOW_LATENCY)
- self._ad.sl4a.bleSetAdvertiseSettingsIsConnectable(True)
- # Sets TX power level to High.
- self._ad.sl4a.bleSetAdvertiseSettingsTxPowerLevel(
- bt_constants.BleAdvertiseSettingsTxPower.HIGH)
- advertise_data = self._ad.sl4a.bleBuildAdvertiseData()
- advertise_settings = self._ad.sl4a.bleBuildAdvertiseSettings()
- logging.info('Activating BLE pairing mode on AndroidDevice.')
- self._ad.sl4a.bleStartBleAdvertising(
- self.ble_advertise_callback, advertise_data, advertise_settings)
-
- def deactivate_ble_pairing_mode(self) -> None:
- """Deactivates BLE pairing mode on an AndroidDevice."""
- if not self.ble_advertise_callback:
- self._ad.log.debug('BLE pairing mode is not activated.')
- return
- logging.info('Deactivating BLE pairing mode on AndroidDevice.')
- self._ad.sl4a.bleStopBleAdvertising(self.ble_advertise_callback)
- self.ble_advertise_callback = None
-
- def get_bluetooth_mac_address(self) -> str:
- """Gets Bluetooth mac address of an AndroidDevice."""
- logging.info('Getting Bluetooth mac address for AndroidDevice.')
- mac_address = self._ad.sl4a.bluetoothGetLocalAddress()
- logging.info('Bluetooth mac address of AndroidDevice: %s', mac_address)
- return mac_address
-
- def scan_and_get_ble_device_address(
- self,
- device_name: str,
- timeout_sec: float = 30) -> str:
- """Searchs a BLE device by BLE scanner and returns it's BLE mac address.
-
- Args:
- device_name: string, the name of BLE device.
- timeout_sec: int, number of seconds to wait for finding the advertisement.
-
- Returns:
- String of the BLE mac address.
-
- Raises:
- ControllerError: Raised if failed to get the BLE device address
- """
- filter_list = self._ad.sl4a.bleGenFilterList()
- scan_settings = self._ad.sl4a.bleBuildScanSetting()
- scan_callback = self._ad.sl4a.bleGenScanCallback()
- self._ad.sl4a.bleSetScanFilterDeviceName(device_name)
- self._ad.sl4a.bleBuildScanFilter(filter_list)
- self._ad.sl4a.bleStartBleScan(filter_list, scan_settings, scan_callback)
- try:
- event = self._ad.ed.pop_event(
- 'BleScan%sonScanResults' % scan_callback, timeout_sec)
- except queue.Empty:
- raise signals.ControllerError(
- 'Timed out %ds after waiting for phone finding BLE device: %s.' %
- (timeout_sec, device_name))
- finally:
- self._ad.sl4a.bleStopBleScan(scan_callback)
- return event['data']['Result']['deviceInfo']['address']
-
- def get_device_name(self) -> str:
- """Gets Bluetooth device name of an AndroidDevice."""
- logging.info('Getting Bluetooth device name for AndroidDevice.')
- device_name = self._ad.sl4a.bluetoothGetLocalName()
- logging.info('Bluetooth device name of AndroidDevice: %s', device_name)
- return device_name
-
- def is_bluetooth_sco_on(self) -> bool:
- """Checks whether communications use Bluetooth SCO."""
- cmd = 'dumpsys bluetooth_manager | grep "isBluetoothScoOn"'
- get_status = self._ad.adb.shell(cmd)
- if isinstance(get_status, bytes):
- get_status = get_status.decode()
- return 'true' in get_status
-
- def connect_with_profile(
- self,
- snd_ad_mac_address: str,
- profile: BluetoothProfile) -> bool:
- """Connects with the profile.
-
- The connection can only be completed after the bluetooth devices are paired.
- To connected with the profile, the bluetooth connection policy is set to
- forbidden first and then set to allowed. The paired bluetooth devices will
- start to make connection. The connection time could be long. The waitting
- time is set to BT_CONNECTION_WAITING_TIME_SECONDS (currently 10 seconds).
-
- Args:
- snd_ad_mac_address: the mac address of the device accepting connection.
- profile: the profiles to be set
-
- Returns:
- The profile connection succeed/fail
- """
- if profile == BluetoothProfile.MAP_MCE:
- self._ad.sl4a.bluetoothMapClientConnect(snd_ad_mac_address)
- elif profile == BluetoothProfile.PBAP_CLIENT:
- self.set_profile_policy(
- snd_ad_mac_address, profile,
- BluetoothConnectionPolicy.CONNECTION_POLICY_ALLOWED)
- self._ad.sl4a.bluetoothPbapClientConnect(snd_ad_mac_address)
- else:
- self.set_profile_policy(
- snd_ad_mac_address, profile,
- BluetoothConnectionPolicy.CONNECTION_POLICY_FORBIDDEN)
- self.set_profile_policy(
- snd_ad_mac_address, profile,
- BluetoothConnectionPolicy.CONNECTION_POLICY_ALLOWED)
- self._ad.sl4a.bluetoothConnectBonded(snd_ad_mac_address)
- time.sleep(BT_CONNECTION_WAITING_TIME_SECONDS)
- is_connected = self._is_profile_connected(snd_ad_mac_address, profile)
- self.log.info('The connection between %s and %s for profile %s succeed: %s',
- self.serial, snd_ad_mac_address, profile, is_connected)
- return is_connected
-
- def connect_to_snd_with_profile(
- self,
- snd_ad: AndroidDevice,
- profile: BluetoothProfile,
- attempts: int = 5) -> bool:
- """Connects pri android device to snd android device with profile.
-
- Args:
- snd_ad: android device accepting connection
- profile: the profile to be connected
- attempts: Number of attempts to try until failure.
-
- Returns:
- Boolean of connecting result
- """
- pri_ad = self._ad
- curr_attempts = 0
- snd_ad_mac_address = snd_ad.sl4a.bluetoothGetLocalAddress()
- if not self.is_bt_paired(snd_ad_mac_address):
- self.log.error('Devices %s and %s not paired before connecting',
- self.serial, snd_ad.serial)
- return False
- while curr_attempts < attempts:
- curr_attempts += 1
- self.log.info('Connection of profile %s at curr attempt %d (total %d)',
- profile, curr_attempts, attempts)
- if self.connect_with_profile(snd_ad_mac_address, profile):
- self.log.info('Connection between devices %s and %s succeeds at %d try',
- pri_ad.serial, snd_ad.serial, curr_attempts)
- return True
- self.log.error('Connection of profile %s failed after %d attempts', profile,
- attempts)
- return False
-
- def is_bt_paired(self, mac_address: str) -> bool:
- """Check if the bluetooth device with mac_address is paired to ad.
-
- Args:
- mac_address: the mac address of the bluetooth device for pairing
-
- Returns:
- True if they are paired
- """
- bonded_info = self._ad.sl4a.bluetoothGetBondedDevices()
- return mac_address in [info['address'] for info in bonded_info]
-
- def is_a2dp_sink_connected(self, mac_address: str) -> bool:
- """Checks if the Android device connects to a A2DP sink device.
-
- Args:
- mac_address: String, Bluetooth MAC address of the A2DP sink device.
-
- Returns:
- True if connected else False.
- """
- connected_devices = self._ad.sl4a.bluetoothA2dpGetConnectedDevices()
- return mac_address in [d['address'] for d in connected_devices]
-
- def hfp_connect(self, ag_ad: AndroidDevice) -> bool:
- """Hfp connecting hf android device to ag android device.
-
- The android device should support the Headset Client profile. For example,
- the android device with git_master-bds-dev build.
-
- Args:
- ag_ad: Audio Gateway (ag) android device
-
- Returns:
- Boolean of connecting result
- """
- return self.connect_to_snd_with_profile(ag_ad,
- BluetoothProfile.HEADSET_CLIENT)
-
- def a2dp_sink_connect(self, src_ad: AndroidDevice) -> bool:
- """Connects pri android device to secondary android device.
-
- The android device should support the A2dp Sink profile. For example, the
- android device with git_master-bds-dev build.
-
- Args:
- src_ad: A2dp source android device
-
- Returns:
- Boolean of connecting result
- """
- return self.connect_to_snd_with_profile(src_ad, BluetoothProfile.A2DP_SINK)
-
- def map_connect(self, map_ad: AndroidDevice) -> bool:
- """Connects primary device to secondary device via MAP MCE profile.
-
- The primary device should support the MAP MCE profile. For example,
- the android device with git_master-bds-dev build.
-
- Args:
- map_ad: AndroidDevice, a android device supporting MAP profile.
-
- Returns:
- Boolean of connecting result
- """
- return self.connect_to_snd_with_profile(map_ad,
- BluetoothProfile.MAP_MCE)
-
- def map_disconnect(self, bluetooth_address: str) -> bool:
- """Disconnects a MAP MSE device with specified Bluetooth MAC address.
-
- Args:
- bluetooth_address: a connected device's bluetooth address.
-
- Returns:
- True if the device is disconnected else False.
- """
- self._ad.sl4a.bluetoothMapClientDisconnect(bluetooth_address)
- return bt_test_utils.wait_until(
- timeout_sec=COMMON_TIMEOUT_SECONDS,
- condition_func=self._is_profile_connected,
- func_args=[bluetooth_address, BluetoothProfile.MAP_MCE],
- expected_value=False)
-
- def pbap_connect(self, pbap_ad: AndroidDevice) -> bool:
- """Connects primary device to secondary device via PBAP client profile.
-
- The primary device should support the PBAP client profile. For example,
- the android device with git_master-bds-dev build.
-
- Args:
- pbap_ad: AndroidDevice, a android device supporting PBAP profile.
-
- Returns:
- Boolean of connecting result
- """
- return self.connect_to_snd_with_profile(pbap_ad,
- BluetoothProfile.PBAP_CLIENT)
-
- def set_bluetooth_tethering(self, status_enabled: bool) -> None:
- """Sets Bluetooth tethering to be specific status.
-
- Args:
- status_enabled: Bool, Bluetooth tethering will be set to enable if True,
- else disable.
- """
- if self._ad.sl4a.bluetoothPanIsTetheringOn() == status_enabled:
- self._ad.log.info('Already %s Bluetooth tethering.' %
- ('enabled' if status_enabled else 'disabled'))
- return
-
- self._ad.log.info('%s Bluetooth tethering.' %
- ('Enable' if status_enabled else 'Disable'))
- self._ad.sl4a.bluetoothPanSetBluetoothTethering(status_enabled)
-
- bt_test_utils.wait_until(
- timeout_sec=COMMON_TIMEOUT_SECONDS,
- condition_func=self._ad.sl4a.bluetoothPanIsTetheringOn,
- func_args=[],
- expected_value=status_enabled,
- exception=signals.ControllerError(
- 'Failed to %s Bluetooth tethering.' %
- ('enable' if status_enabled else 'disable')))
-
- def set_profile_policy(
- self,
- snd_ad_mac_address: str,
- profile: BluetoothProfile,
- policy: BluetoothConnectionPolicy) -> None:
- """Sets policy of the profile car related profiles to OFF.
-
- This avoids autoconnect being triggered randomly. The use of this function
- is encouraged when you're testing individual profiles in isolation.
-
- Args:
- snd_ad_mac_address: the mac address of the device accepting connection.
- profile: the profiles to be set
- policy: the policy value to be set
- """
- pri_ad = self._ad
- pri_ad_local_name = pri_ad.sl4a.bluetoothGetLocalName()
- pri_ad.log.info('Sets profile %s on %s for %s to policy %s', profile,
- pri_ad_local_name, snd_ad_mac_address, policy)
- if profile == BluetoothProfile.A2DP:
- pri_ad.sl4a.bluetoothA2dpSetPriority(snd_ad_mac_address, policy.value)
- elif profile == BluetoothProfile.A2DP_SINK:
- pri_ad.sl4a.bluetoothA2dpSinkSetPriority(snd_ad_mac_address, policy.value)
- elif profile == BluetoothProfile.HEADSET_CLIENT:
- pri_ad.sl4a.bluetoothHfpClientSetPriority(snd_ad_mac_address,
- policy.value)
- elif profile == BluetoothProfile.PBAP_CLIENT:
- pri_ad.sl4a.bluetoothPbapClientSetPriority(snd_ad_mac_address,
- policy.value)
- elif profile == BluetoothProfile.HID_HOST:
- pri_ad.sl4a.bluetoothHidSetPriority(snd_ad_mac_address, policy.value)
- else:
- pri_ad.log.error('Profile %s not yet supported for policy settings',
- profile)
-
- def set_profiles_policy(
- self,
- snd_ad: AndroidDevice,
- profile_list: Sequence[BluetoothProfile],
- policy: BluetoothConnectionPolicy) -> None:
- """Sets the policy of said profile(s) on pri_ad for snd_ad.
-
- Args:
- snd_ad: android device accepting connection
- profile_list: list of the profiles to be set
- policy: the policy to be set
- """
- mac_address = snd_ad.sl4a.bluetoothGetLocalAddress()
- for profile in profile_list:
- self.set_profile_policy(mac_address, profile, policy)
-
- def set_profiles_policy_off(
- self,
- snd_ad: AndroidDevice,
- profile_list: Sequence[BluetoothProfile]) -> None:
- """Sets policy of the profiles to OFF.
-
- This avoids autoconnect being triggered randomly. The use of this function
- is encouraged when you're testing individual profiles in isolation
-
- Args:
- snd_ad: android device accepting connection
- profile_list: list of the profiles to be turned off
- """
- self.set_profiles_policy(
- snd_ad, profile_list,
- BluetoothConnectionPolicy.CONNECTION_POLICY_FORBIDDEN)
-
- def wait_for_call_state(
- self,
- call_state: Union[int, CallState],
- timeout_sec: float,
- wait_interval: int = 3) -> bool:
- """Waits for call state of the device to be changed.
-
- Args:
- call_state: int, the expected call state. Call state values are:
- 0: IDLE
- 1: RINGING
- 2: OFFHOOK
- timeout_sec: int, number of seconds of expiration time
- wait_interval: int, number of seconds of waiting in each cycle
-
- Returns:
- True if the call state has been changed else False.
- """
- # TODO(user): Force external call to use CallState instead of int
- if isinstance(call_state, CallState):
- call_state = call_state.value
- expiration_time = time.time() + timeout_sec
- which_cycle = 1
- while time.time() < expiration_time:
- # Waits for the call state change in every cycle.
- time.sleep(wait_interval)
- self._ad.log.info(
- 'in cycle %d of waiting for call state %d', which_cycle, call_state)
- if call_state == self._ad.mbs.getTelephonyCallState():
- return True
- self._ad.log.info('The call state did not change to %d before timeout',
- call_state)
- return False
-
- def play_audio_file_with_google_play_music(self) -> None:
- """Plays an audio file on an AndroidDevice with Google Play Music app.
-
- Returns:
- None
- """
- try:
- self._ad.aud.add_watcher('LOGIN').when(text='SKIP').click(text='SKIP')
- self._ad.aud.add_watcher('NETWORK').when(text='Server error').click(
- text='OK')
- self._ad.aud.add_watcher('MENU').when(text='Settings').click(
- text='Listen Now')
- except adb_ui.Error:
- logging.info('The watcher has been added.')
- self._ad.sl4a.appLaunch('com.google.android.music')
- if self._ad.aud(text='No Music available').exists(10):
- self._ad.reboot()
- self._ad.sl4a.appLaunch('com.google.android.music')
- self._ad.aud(
- resource_id='com.google.android.music:id/li_thumbnail_frame').click()
- time.sleep(6) # Wait for audio playback to reach steady state
-
- def add_call_log(
- self,
- call_log_type: Union[int, CallLogType],
- phone_number: str,
- call_time: int) -> None:
- """Add call number and time to specified log.
-
- Args:
- call_log_type: int, number of call log type. Call log type values are:
- 1: Incoming call
- 2: Outgoing call
- 3: Missed call
- phone_number: string, phone number to be added in call log.
- call_time: int, call time to be added in call log.
-
- Returns:
- None
- """
- # TODO(user): Force external call to use CallLogType instead of int
- if isinstance(call_log_type, CallLogType):
- call_log_type = call_log_type.value
- new_call_log = {}
- new_call_log['type'] = str(call_log_type)
- new_call_log['number'] = phone_number
- new_call_log['time'] = str(call_time)
- self._ad.sl4a.callLogsPut(new_call_log)
-
- def get_call_volume(self) -> int:
- """Gets current call volume of an AndroidDevice when Bluetooth SCO On.
-
- Returns:
- An integer specifying the number of current call volume level.
- """
- cmd = 'dumpsys audio | grep "STREAM_BLUETOOTH_SCO" | tail -1'
- out = self._ad.adb.shell(cmd).decode()
- # TODO(user): Should we handle the case that re.search(...) return None
- # below?
- pattern = r'(?<=SCO index:)[\d]+'
- return int(re.search(pattern, out).group())
-
- def make_phone_call(
- self,
- callee: AndroidDevice,
- timeout_sec: float = 30) -> None:
- """Make a phone call to callee and check if callee is ringing.
-
- Args:
- callee: AndroidDevice, The callee in the phone call.
- timeout_sec: int, number of seconds to wait for the callee ringing.
-
- Raises:
- TestError
- """
- self._ad.sl4a.telecomCallNumber(callee.dimensions['phone_number'])
- is_ringing = callee.wait_for_call_state(bt_constants.CALL_STATE_RINGING,
- timeout_sec)
- if not is_ringing:
- raise signals.TestError(
- 'Timed out after %ds waiting for call state: RINGING' % timeout_sec)
-
- def wait_for_disconnection_success(
- self,
- mac_address: str,
- timeout: float = 30) -> float:
- """Waits for a device to connect with the AndroidDevice.
-
- Args:
- mac_address: The Bluetooth mac address of the peripheral device.
- timeout: Number of seconds to wait for the devices to connect.
-
- Returns:
- connection_time: The time it takes to connect in seconds.
-
- Raises:
- ControllerError
- """
- start_time = time.time()
- end_time = start_time + timeout
- while time.time() < end_time:
- if not self._ad.sl4a.bluetoothIsDeviceConnected(mac_address):
- disconnection_time = (time.time() - start_time)
- logging.info('Disconnected device %s in %d seconds', mac_address,
- disconnection_time)
- return disconnection_time
-
- raise signals.ControllerError(
- 'Failed to disconnect device within %d seconds.' % timeout)
-
- def first_pair_and_connect_bluetooth(self, bt_device: BtDevice) -> None:
- """Pairs and connects an AndroidDevice with a Bluetooth device.
-
- This method does factory reset bluetooth first and then pairs and connects
- the devices.
-
- Args:
- bt_device: The peripheral Bluetooth device or an AndroidDevice.
-
- Returns:
- None
- """
- bt_device.factory_reset_bluetooth()
- mac_address = bt_device.get_bluetooth_mac_address()
- bt_device.activate_pairing_mode()
- self.pair_and_connect_bluetooth(mac_address)
-
- def get_device_time(self) -> str:
- """Get device epoch time and transfer to logcat timestamp format.
-
- Returns:
- String of the device time.
- """
- return self._ad.adb.shell(
- 'date +"%m-%d %H:%M:%S.000"').decode().splitlines()[0]
-
- def logcat_filter(
- self,
- start_time: str,
- text_filter: str = '') -> str:
- """Returns logcat after a given time.
-
- This method calls from the android_device logcat service file and filters
- all logcat line prior to the start_time.
-
- Args:
- start_time: start time in string format of _DATETIME_FMT.
- text_filter: only return logcat lines that include this string.
-
- Returns:
- A logcat output.
-
- Raises:
- ValueError Exception if start_time is invalid format.
- """
- try:
- start_time_conv = datetime.datetime.strptime(start_time, _DATETIME_FMT)
- except ValueError as ex:
- logging.error('Invalid time format!')
- raise ex
- logcat_response = ''
- with open(self._ad.adb_logcat_file_path, 'r', errors='replace') \
- as logcat_file:
- post_start_time = False
- for line in logcat_file:
- match = self.regex_logcat_time.match(line)
- if match:
- if (datetime.datetime.strptime(
- match.group('datetime'), _DATETIME_FMT) >= start_time_conv):
- post_start_time = True
- if post_start_time and line.find(text_filter) >= 0:
- logcat_response += line
- return logcat_response
-
- def logcat_filter_message(
- self,
- current_time: str,
- text: str = '') -> str:
- """DEPRECATED Builds the logcat command.
-
- This method builds the logcat command to check for a specified log
- message after the specified time. If text=None, the logcat returned will be
- unfiltered.
-
- Args:
- current_time: time cutoff for grepping for the specified
- message, format = ('%m-%d %H:%M:%S.000').
- text: text to search for.
-
- Returns:
- The response of the logcat filter.
- """
- return self.logcat_filter(current_time, text)
-
- def send_media_passthrough_cmd(
- self,
- command: str,
- event_receiver: Optional[AndroidDevice] = None) -> None:
- """Sends a media passthrough command.
-
- Args:
- command: string, media passthrough command.
- event_receiver: AndroidDevice, a device which starts
- BluetoothSL4AAudioSrcMBS.
-
- Raises:
- signals.ControllerError: raised if the event is not received.
- """
- self._ad.log.info('Sending Media Passthough: %s' % command)
- self._ad.sl4a.bluetoothMediaPassthrough(command)
- try:
- if not event_receiver:
- event_receiver = self._ad
- event_receiver.ed.pop_event(MEDIA_CMD_MAP[command],
- MEDIA_EVENT_TIMEOUT_SEC)
- except queue.Empty:
- raise signals.ControllerError(
- 'Device "%s" failed to receive the event "%s" '
- 'when the command "%s" was sent.' %
- (event_receiver.serial, MEDIA_CMD_MAP[command], command))
-
- def pause(self) -> None:
- """Sends the AVRCP command "pause"."""
- self.send_media_passthrough_cmd(bt_constants.CMD_MEDIA_PAUSE)
-
- def play(self) -> None:
- """Sends the AVRCP command "play"."""
- self.send_media_passthrough_cmd(bt_constants.CMD_MEDIA_PLAY)
-
- def track_previous(self) -> None:
- """Sends the AVRCP command "skipPrev"."""
- self.send_media_passthrough_cmd(bt_constants.CMD_MEDIA_SKIP_PREV)
-
- def track_next(self) -> None:
- """Sends the AVRCP command "skipNext"."""
- self.send_media_passthrough_cmd(bt_constants.CMD_MEDIA_SKIP_NEXT)
-
- def get_current_track_info(self) -> Dict[str, Any]:
- """Returns Dict (Media metadata) representing the current track."""
- return self._ad.sl4a.bluetoothMediaGetCurrentMediaMetaData()
-
- def get_current_playback_state(self) -> int:
- """Returns Integer representing the current playback state."""
- return self._ad.sl4a.bluetoothMediaGetCurrentPlaybackState()['state']
-
- def verify_playback_state_changed(
- self,
- expected_state: str,
- exception: Optional[Exception] = None) -> bool:
- """Verifies the playback state is changed to be the expected state.
-
- Args:
- expected_state: string, the changed state as expected.
- exception: Exception, raised when the state is not changed if needed.
- """
- bt_test_utils.wait_until(
- timeout_sec=MEDIA_UPDATE_TIMEOUT_SEC,
- condition_func=self.get_current_playback_state,
- func_args=[],
- expected_value=expected_state,
- exception=exception)
-
- def verify_current_track_changed(
- self,
- expected_track: str,
- exception: Optional[Exception] = None) -> bool:
- """Verifies the Now playing track is changed to be the expected track.
-
- Args:
- expected_track: string, the changed track as expected.
- exception: Exception, raised when the track is not changed if needed.
- """
- bt_test_utils.wait_until(
- timeout_sec=MEDIA_UPDATE_TIMEOUT_SEC,
- condition_func=self.get_current_track_info,
- func_args=[],
- expected_value=expected_track,
- exception=exception)
-
- def verify_avrcp_event(
- self,
- event_name: AvrcpEvent,
- check_time: str,
- timeout_sec: float = 20) -> bool:
- """Verifies that an AVRCP event was received by an AndroidDevice.
-
- Checks logcat to verify that an AVRCP event was received after a given
- time.
-
- Args:
- event_name: enum, AVRCP event name. Currently supports play, pause,
- track_previous, and track_next.
- check_time: string, The earliest desired cutoff time to check the logcat.
- Must be in format '%m-%d %H:%M:%S.000'. Use
- datetime.datetime.now().strftime('%m-%d %H:%M:%S.%f') to get current time
- in this format.
- timeout_sec: int, Number of seconds to wait for the specified AVRCP event
- be found in logcat.
-
- Raises:
- TestError
-
- Returns:
- True if the event was received.
- """
- avrcp_events = [
- 'State:NOT_PLAYING->PLAYING', 'State:PLAYING->NOT_PLAYING',
- 'sendMediaKeyEvent: keyEvent=76', 'sendMediaKeyEvent: keyEvent=75'
- ]
- if event_name.value not in avrcp_events:
- raise signals.TestError('An unexpected AVRCP event is specified.')
-
- end_time = time.time() + timeout_sec
- while time.time() < end_time:
- if self.logcat_filter_message(check_time, event_name.value):
- logging.info('%s event received successfully.', event_name)
- return True
- time.sleep(1)
- logging.error('AndroidDevice failed to receive %s event.', event_name)
- logging.info('Logcat:\n%s', self.logcat_filter_message(check_time))
- return False
-
- def add_google_account(self, retries: int = 5) -> bool:
- """Login Google account.
-
- Args:
- retries: int, the number of retries.
-
- Returns:
- True if account is added successfully.
-
- Raises:
- TestError
- """
- for _ in range(retries):
- output = self._ad.adb.shell(
- 'am instrument -w -e account "%s" -e password '
- '"%s" -e sync true -e wait-for-checkin false '
- 'com.google.android.tradefed.account/.AddAccount' %
- (self._ad.dimensions['google_account'],
- self._ad.dimensions['google_account_password'])).decode()
- if 'result=SUCCESS' in output:
- logging.info('Google account is added successfully')
- time.sleep(3) # Wait for account to steady state
- return True
- raise signals.TestError('Failed to add google account: %s' % output)
-
- def remove_google_account(self, retries: int = 5) -> bool:
- """Remove Google account.
-
- Args:
- retries: int, the number of retries.
-
- Returns:
- True if account is removed successfully.
-
- Raises:
- TestError
- """
- for _ in range(retries):
- output = self._ad.adb.shell(
- 'am instrument -w com.google.android.tradefed.account/.RemoveAccounts'
- ).decode()
- if 'result=SUCCESS' in output:
- logging.info('Google account is removed successfully')
- return True
- time.sleep(1) # Buffer between retries.
- raise signals.TestError('Failed to remove google account: %s' % output)
-
- def make_hangouts_voice_call(self, callee: AndroidDevice) -> None:
- """Make Hangouts VOIP voice call.
-
- Args:
- callee: Android Device, the android device of callee.
-
- Returns:
- None
- """
- try:
- self._ad.aud.add_watcher('SETUP').when(text='SKIP').click(text='SKIP')
- self._ad.aud.add_watcher('REMINDER').when(text='Got it').click(
- text='Got it')
- except adb_ui.Error:
- # TODO(user): Need to figure out the logic here why use info in
- # exception catch block instead of warning/error
- logging.info('The watcher has been added.')
- self._ad.sl4a.appLaunch('com.google.android.talk')
- callee.sl4a.appLaunch('com.google.android.talk')
- # Make voice call to callee
- try:
- # Click the callee icon
- self._ad.aud(resource_id='com.google.android.talk:id/avatarView').click()
- except adb_ui.Error:
- # Press BACK key twice and re-launch Hangouts if it is not in main page
- for _ in range(2):
- self._ad.aud.send_key_code(4)
- self._ad.sl4a.appLaunch('com.google.android.talk')
- self._ad.aud(resource_id='com.google.android.talk:id/avatarView').click()
- # Click the button to make a voice call
- self._ad.aud(content_desc='Call').click()
- # Answer by callee
- if callee.aud(text='Answer').exists(5):
- callee.aud(text='Answer').click()
- else:
- callee.aud(content_desc='Join voice call').click()
-
- def hang_up_hangouts_call(self) -> None:
- """Hang up Hangouts VOIP voice call.
-
- Returns:
- None
- """
- # Click the in call icon to show the end call button
- self._ad.aud(
- resource_id='com.google.android.talk:id/in_call_main_avatar').click()
- # Click the button to hang up call
- self._ad.aud(content_desc='Hang up').click()
- time.sleep(3) # Wait for VoIP call state to reach idle state
-
- def detect_and_pull_ssrdump(self, ramdump_type: str = 'ramdump_bt') -> bool:
- """Detect and pull RAMDUMP log.
-
- Args:
- ramdump_type: str, the partial of file names to search for in ramdump
- files path. 'ramdump_bt' is used for searching Bluetooth ramdump log
- files.
-
- Returns:
- True if there is a file with file name matching the ramdump type.
- """
- files = self._ad.adb.shell('ls %s' % bt_constants.RAMDUMP_PATH).decode()
- if ramdump_type in files:
- logging.info('RAMDUMP is found.')
- log_name_timestamp = mobly_logger.get_log_file_timestamp()
- destination = os.path.join(self._ad.log_path, 'RamdumpLogs',
- log_name_timestamp)
- utils.create_dir(destination)
- self._ad.adb.pull([bt_constants.RAMDUMP_PATH, destination])
- return True
- return False
-
- def get_bt_num_of_crashes(self) -> int:
- """Get number of Bluetooth crash times from bluetooth_manager.
-
- Returns:
- Number of Bluetooth crashed times.
- """
- out = self._regex_bt_crash.search(
- self._ad.adb.shell('dumpsys bluetooth_manager').decode())
- # TODO(user): Need to consider the case "out=None" when miss in
- # matching
- return int(out.group('num_bt_crashes'))
-
- def clean_ssrdump(self) -> None:
- """Clean RAMDUMP log.
-
- Returns:
- None
- """
- self._ad.adb.shell('rm -rf %s/*' % bt_constants.RAMDUMP_PATH)
-
- def set_target(self, bt_device: BtDevice) -> None:
- """Allows for use to get target device object for target interaction."""
- self._target_device = bt_device
-
- def wait_for_hsp_connection_state(self,
- mac_address: str,
- connected: bool,
- timeout_sec: float = 30) -> bool:
- """Waits for HSP connection to be in a expected state on Android device.
-
- Args:
- mac_address: The Bluetooth mac address of the peripheral device.
- connected: True if HSP connection state is connected as expected.
- timeout_sec: Number of seconds to wait for HSP connection state change.
- """
- expected_state = BluetoothConnectionStatus.STATE_DISCONNECTED
- if connected:
- expected_state = BluetoothConnectionStatus.STATE_CONNECTED
- bt_test_utils.wait_until(
- timeout_sec=timeout_sec,
- condition_func=self._ad.sl4a.bluetoothHspGetConnectionStatus,
- func_args=[mac_address],
- expected_value=expected_state,
- exception=signals.TestError(
- 'Failed to %s the device "%s" within %d seconds via HSP.' %
- ('connect' if connected else 'disconnect', mac_address,
- timeout_sec)))
-
- def wait_for_bluetooth_toggle_state(self,
- enabled: bool = True,
- timeout_sec: float = 30) -> bool:
- """Waits for Bluetooth to be in an expected state.
-
- Args:
- enabled: True if Bluetooth status is enabled as expected.
- timeout_sec: Number of seconds to wait for Bluetooth to be in the expected
- state.
- """
- bt_test_utils.wait_until(
- timeout_sec=timeout_sec,
- condition_func=self._ad.mbs.btIsEnabled,
- func_args=[],
- expected_value=enabled,
- exception=signals.TestError(
- 'Bluetooth is not %s within %d seconds on the device "%s".' %
- ('enabled' if enabled else 'disabled', timeout_sec,
- self._ad.serial)))
-
- def wait_for_a2dp_connection_state(self,
- mac_address: str,
- connected: bool,
- timeout_sec: float = 30) -> bool:
- """Waits for A2DP connection to be in a expected state on Android device.
-
- Args:
- mac_address: The Bluetooth mac address of the peripheral device.
- connected: True if A2DP connection state is connected as expected.
- timeout_sec: Number of seconds to wait for A2DP connection state change.
- """
- bt_test_utils.wait_until(
- timeout_sec=timeout_sec,
- condition_func=self.is_a2dp_sink_connected,
- func_args=[mac_address],
- expected_value=connected,
- exception=signals.TestError(
- 'Failed to %s the device "%s" within %d seconds via A2DP.' %
- ('connect' if connected else 'disconnect', mac_address,
- timeout_sec)))
-
- def wait_for_nap_service_connection(
- self,
- connected_mac_addr: str,
- state_connected: bool,
- exception: Exception) -> bool:
- """Waits for NAP service connection to be expected state.
-
- Args:
- connected_mac_addr: String, Bluetooth Mac address is needed to be checked.
- state_connected: Bool, NAP service connection is established as expected
- if True, else terminated as expected.
- exception: Exception, Raised if NAP service connection is not expected
- state.
-
- Raises:
- exception: Raised if NAP service connection is not expected state.
- """
- def is_device_connected():
- """Returns True if connected else False."""
- connected_devices = self._ad.sl4a.bluetoothPanGetConnectedDevices()
- # Check if the Bluetooth mac address is in the connected device list.
- return connected_mac_addr in [d['address'] for d in connected_devices]
-
- bt_test_utils.wait_until(
- timeout_sec=bt_constants.NAP_CONNECTION_TIMEOUT_SECS,
- condition_func=is_device_connected,
- func_args=[],
- expected_value=state_connected,
- exception=exception)
-
- def verify_internet(self,
- allow_access: bool,
- exception: Exception,
- test_url: str = TEST_URL,
- interval_sec: int = PING_INTERVAL_TIME_SEC,
- timeout_sec: float = PING_TIMEOUT_SEC) -> bool:
- """Verifies that internet is in expected state.
-
- Continuously make ping request to a URL for internet verification.
-
- Args:
- allow_access: Bool, Device can have internet access as expected if True,
- else no internet access as expected.
- exception: Exception, Raised if internet is not in expected state.
- test_url: String, A URL is used to verify internet by ping request.
- interval_sec: Int, Interval time between ping requests in second.
- timeout_sec: Int, Number of seconds to wait for ping success if
- allow_access is True else wait for ping failure if allow_access is
- False.
-
- Raises:
- exception: Raised if internet is not in expected state.
- """
- self._ad.log.info('Verify that internet %s be used.' %
- ('can' if allow_access else 'can not'))
-
- def http_ping():
- """Returns True if http ping success else False."""
- try:
- return bool(self._ad.sl4a.httpPing(test_url))
- except jsonrpc_client_base.ApiError as e:
- # ApiError is raised by httpPing() when no internet.
- self._ad.log.debug(str(e))
- return False
-
- bt_test_utils.wait_until(
- timeout_sec=timeout_sec,
- condition_func=http_ping,
- func_args=[],
- expected_value=allow_access,
- exception=exception,
- interval_sec=interval_sec)
-
- def allow_extra_permissions(self) -> None:
- """A method to allow extra permissions.
-
- This method has no any logics. It is used to skip the operation when it is
- called if a test is not Wear OS use case.
- """
-
- def goto_bluetooth_device_details(self) -> None:
- """Goes to bluetooth device detail page."""
- self._ad.adb.shell('am force-stop com.android.settings')
- self._ad.adb.shell('am start -a android.settings.BLUETOOTH_SETTINGS')
- self._ad.aud(
- resource_id='com.android.settings:id/settings_button').click()
-
- def bluetooth_ui_forget_device(self) -> None:
- """Clicks the forget device button."""
- self.goto_bluetooth_device_details()
- self._ad.aud(resource_id='com.android.settings:id/button1').click()
-
- def bluetooth_ui_disconnect_device(self) -> None:
- """Clicks the disconnect device button."""
- self.goto_bluetooth_device_details()
- self._ad.aud(resource_id='com.android.settings:id/button2').click()
-
- def _find_bt_device_details_ui_switch(self, switch_name: str):
- """Returns the UI node for a BT switch.
-
- Args:
- switch_name: each switch button name in bluetooth connect device detail
- page. switch name like 'Phone calls', 'Media audio', etc.
-
- Returns:
- adb_ui_device.XML node UI element of the BT each option switch button.
- """
- switch_button_name = ('Phone calls',
- 'Media audio',
- 'Contact sharing',
- 'Text Messages'
- )
- if switch_name not in switch_button_name:
- raise ValueError(f'Unknown switch name {switch_name}.')
- self.goto_bluetooth_device_details()
- text_node = adb_ui.wait_and_get_xml_node(
- self._ad, timeout=10, text=switch_name)
- text_grandparent_node = text_node.parentNode.parentNode
- switch_node = adb_ui.Selector(
- resource_id='android:id/switch_widget').find_node(text_grandparent_node)
- return switch_node
-
- def get_bt_device_details_ui_switch_state(self, switch_name: str) -> bool:
- """Gets bluetooth each option switch button state value.
-
- Args:
- switch_name: each switch button name in bluetooth connect device detail
- page.
-
- Returns:
- State True or False.
- """
- switch_node = self._find_bt_device_details_ui_switch(switch_name)
- current_state = switch_node.attributes['checked'].value == 'true'
- return current_state
-
- def set_bt_device_details_ui_switch_state(
- self, switch_name: str,
- target_state: bool) -> None:
- """Sets and checks the BT each option button is the target enable state.
-
- Args:
- switch_name: each switch button name in bluetooth connect device detail
- page.
- target_state: The desired state expected from the switch. If the state of
- the switch already meet expectation, no action will be taken.
- """
- if self.get_bt_device_details_ui_switch_state(switch_name) == target_state:
- return
- switch_node = self._find_bt_device_details_ui_switch(switch_name)
- x, y = adb_ui.find_point_in_bounds(switch_node.attributes['bounds'].value)
- self._ad.aud.click(x, y)
-
- def get_bt_quick_setting_switch_state(self) -> bool:
- """Gets bluetooth quick settings switch button state value."""
- self._ad.open_notification()
- switch_node = self._ad_aud(class_name='android.widget.Switch', index='1')
- current_state = switch_node.attributes['content-desc'].value == 'Bluetooth.'
- return current_state
-
- def assert_bt_device_details_state(self, target_state: bool) -> None:
- """Asserts the Bluetooth connection state.
-
- Asserts the BT each option button in device detail,
- BT quick setting state and BT manager service from log are at the target
- state.
-
- Args:
- target_state: BT each option button, quick setting and bluetooth manager
- service target state.
-
- """
- for switch_name in ['Phone calls', 'Media audio']:
- asserts.assert_equal(
- self._ad.get_bt_device_details_ui_switch_state(switch_name),
- target_state,
- f'The BT Media calls switch button state is not {target_state}.')
- asserts.assert_equal(self._ad.is_service_running(), target_state,
- f'The BT service state is not {target_state}.')
- asserts.assert_equal(
- self._ad.get_bt_quick_setting_switch_state(), target_state,
- f'The BT each switch button state is not {target_state}.')
-
- def is_service_running(
- self,
- mac_address: str,
- timeout_sec: float) -> bool:
- """Checks bluetooth profile state.
-
- Check bluetooth headset/a2dp profile connection
- status from bluetooth manager log.
-
- Args:
- mac_address: The Bluetooth mac address of the peripheral device.
- timeout_sec: Number of seconds to wait for the specified message
- be found in bluetooth manager log.
-
- Returns:
- True: If pattern match with bluetooth_manager_log.
- """
- pattern_headset = (r'\sm\w+e:\sC\w+d')
- pattern_a2dp = (r'StateMachine:.*state=Connected')
- output_headset = self._ad.adb.shell(
- 'dumpsys bluetooth_manager | egrep -A20 "Profile: HeadsetService"'
- ).decode()
- output_a2dp = self._ad.adb.shell(
- 'dumpsys bluetooth_manager | egrep -A30 "Profile: A2dpService"').decode(
- )
- service_type = {
- 'a2dp': ((pattern_a2dp), (output_a2dp)),
- 'headset': ((pattern_headset), (output_headset))
- }
- start_time = time.time()
- end_time = start_time + timeout_sec
- while start_time < end_time:
- try:
- match = service_type
- if match and mac_address in service_type:
- return True
- except adb.AdbError as e:
- logging.exception(e)
- time.sleep(ADB_WAITING_TIME_SECONDS)
- return False
-
- def browse_internet(self, url: str = 'www.google.com') -> None:
- """Browses internet by Chrome.
-
- Args:
- url: web address.
-
- Raises:
- signals.TestError: raised if it failed to browse internet by Chrome.
- """
- browse_url = (
- 'am start -n com.android.chrome/com.google.android.apps.chrome.Main -d'
- ' %s' % url
- )
- self._ad.adb.shell(browse_url)
- self._ad.aud.add_watcher('Welcome').when(
- text='Accept & continue').click(text='Accept & continue')
- self._ad.aud.add_watcher('sync page').when(
- text='No thanks').click(text='No thanks')
- if self._ad.aud(text='No internet').exists():
- raise signals.TestError('No connect internet.')
-
- def connect_wifi_from_other_device_hotspot(
- self, wifi_hotspot_device: AndroidDevice) -> None:
- """Turns on 2.4G Wifi hotspot from the other android device and connect on the android device.
-
- Args:
- wifi_hotspot_device: Android device, turn on 2.4G Wifi hotspot.
- """
- # Turn on 2.4G Wifi hotspot on the secondary phone.
- wifi_hotspot_device.sl4a.wifiSetWifiApConfiguration(
- bt_constants.WIFI_HOTSPOT_2_4G)
- wifi_hotspot_device.sl4a.connectivityStartTethering(0, False)
- # Connect the 2.4G Wifi on the primary phone.
- self._ad.mbs.wifiEnable()
- self._ad.mbs.wifiConnectSimple(
- bt_constants.WIFI_HOTSPOT_2_4G['SSID'],
- bt_constants.WIFI_HOTSPOT_2_4G['password'])
diff --git a/blueberry/utils/arduino_base.py b/blueberry/utils/arduino_base.py
deleted file mode 100644
index 37c9146..0000000
--- a/blueberry/utils/arduino_base.py
+++ /dev/null
@@ -1,78 +0,0 @@
-"""Base class for Blueberry controllers using Arduino board.
-
-This module uses pyserial library to communicate with Arduino UNO board.
-
-About Arduino code, please refer to the code of following Arduino project:
-Internal link
-"""
-
-import time
-from mobly.signals import ControllerError
-import serial
-
-
-class ArduinoBase(object):
- """Implements an Arduino base class.
-
- Attributes:
- serial: serial object, a serial object which is used to communicate with
- Arduino board.
- """
-
- def __init__(self, config):
- """Initializes an Arduino base class."""
- self._verify_config(config)
- self.serial = serial.Serial(config['arduino_port'], 9600)
- self.serial.timeout = 30
- # Buffer between calling serial.Serial() and serial.Serial.write().
- time.sleep(2)
-
- def _verify_config(self, config):
- """Checks the device config's required config parameters.
-
- Args:
- config: dict, Mobly controller config for ArduinoBass. The config should
- include the key "arduino_port" whose value is a string representing
- Arduino board name. e.g. /dev/ttyACM0.
- """
- if 'arduino_port' not in config:
- raise ControllerError('Please provide an Arduino board port for the'
- ' ArduinoBase in Mobile Harness config')
-
- def _send_string_to_arduino(self, tx_string):
- """Sends a particular string to communicate with Arduino.
-
- The method requires that Arduino code can read string which is received from
- a python serial object and then send the same string to the serial object.
-
- An example of Arduino code:
- String kRxString = "";
- void setup() {
- ...
- }
- void loop() {
- if (Serial.available() > 0) {
- kRxString = Serial.readString();
- ...
- Serial.write(kRxString.c_str());
- }
- }
-
- Args:
- tx_string: string, is used to be sent to Arduino port for making the
- controlled device perform action. After Arduino receives the string, it
- will send a response which is the same string.
-
- Returns:
- The time it takes for waiting a response, in seconds.
-
- Raises:
- ControllerError: raised if not received a response from Arduino.
- """
- self.serial.write(str.encode(tx_string))
- start_time = time.time()
- rx_string = self.serial.read_until(tx_string, len(tx_string)).decode()
- if rx_string == tx_string:
- return time.time() - start_time
- raise ControllerError('Timed out after %ds waiting for the string "%s" from'
- ' Arduino.' % (self.serial.timeout, tx_string))
diff --git a/blueberry/utils/blueberry_base_test.py b/blueberry/utils/blueberry_base_test.py
deleted file mode 100644
index abe19cd..0000000
--- a/blueberry/utils/blueberry_base_test.py
+++ /dev/null
@@ -1,244 +0,0 @@
-"""Base test class for Blueberry."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import re
-
-from mobly import base_test
-from mobly import signals
-from mobly.controllers import android_device
-from mobly.controllers.android_device_lib import adb
-
-# Internal import
-# Internal import
-# Internal import
-# Internal import
-from blueberry.controllers import derived_bt_device
-from blueberry.decorators import android_bluetooth_client_decorator
-from blueberry.utils.android_bluetooth_decorator import AndroidBluetoothDecorator
-
-
-class BlueberryBaseTest(base_test.BaseTestClass):
- """Base test class for all Blueberry tests to inherit from.
-
- This class assists with device setup for device logging and other pre test
- setup required for Bluetooth tests.
- """
-
- def setup_generated_tests(self):
- """Generates multiple the same tests for pilot run.
-
- This is used to let developers can easily pilot run their tests many times,
- help them to check test stability and reliability. If need to use this,
- please add a flag called "test_iterations" to TestParams in Mobly test
- configuration and its value is number of test methods to be generated. The
- naming rule of test method on Sponge is such as the following example:
- test_send_file_via_bluetooth_opp_1_of_50
- test_send_file_via_bluetooth_opp_2_of_50
- test_send_file_via_bluetooth_opp_3_of_50
- ...
- test_send_file_via_bluetooth_opp_50_of_50
-
- Don't use "test_case_selector" when using "test_iterations", and please use
- "test_method_selector" to replace it.
- """
- test_iterations = int(self.user_params.get('test_iterations', 0))
- if test_iterations < 2:
- return
-
- test_method_selector = self.user_params.get('test_method_selector', 'all')
- existing_test_names = self.get_existing_test_names()
-
- selected_test_names = None
- if test_method_selector == 'all':
- selected_test_names = existing_test_names
- else:
- selected_test_names = test_method_selector.split(' ')
- # Check if selected test methods exist in the test class.
- for test_name in selected_test_names:
- if test_name not in existing_test_names:
- raise base_test.Error('%s does not have test method "%s".' %
- (self.TAG, test_name))
-
- for test_name in selected_test_names:
- test_method = getattr(self.__class__, test_name)
- # List of (<new test name>, <test method>).
- test_arg_sets = [('%s_%s_of_%s' % (test_name, i + 1, test_iterations),
- test_method) for i in range(test_iterations)]
- # pylint: disable=cell-var-from-loop
- self.generate_tests(
- test_logic=lambda _, test: test(self),
- name_func=lambda name, _: name,
- arg_sets=test_arg_sets)
-
- # Delete origin test methods in order to avoid below situation:
- # test_send_file_via_bluetooth_opp <-- origin test method
- # test_send_file_via_bluetooth_opp_1_of_50
- # test_send_file_via_bluetooth_opp_2_of_50
- for test_name in existing_test_names:
- delattr(self.__class__, test_name)
-
- def setup_class(self):
- """Setup class is called before running any tests."""
- super(BlueberryBaseTest, self).setup_class()
- self.capture_bugreport_on_fail = int(self.user_params.get(
- 'capture_bugreport_on_fail', 0))
- self.ignore_device_setup_failures = int(self.user_params.get(
- 'ignore_device_setup_failures', 0))
- self.enable_bluetooth_verbose_logging = int(self.user_params.get(
- 'enable_bluetooth_verbose_logging', 0))
- self.enable_hci_snoop_logging = int(self.user_params.get(
- 'enable_hci_snoop_logging', 0))
- self.increase_logger_buffers = int(self.user_params.get(
- 'increase_logger_buffers', 0))
- self.enable_all_bluetooth_logging = int(self.user_params.get(
- 'enable_all_bluetooth_logging', 0))
-
- # base test should include the test between primary device with Bluetooth
- # peripheral device.
- self.android_devices = self.register_controller(
- android_device, required=False)
-
- # In the case of no android_device assigned, at least 2 derived_bt_device
- # is required.
- if self.android_devices is None:
- self.derived_bt_devices = self.register_controller(
- module=derived_bt_device, min_number=2)
- else:
- self.derived_bt_devices = self.register_controller(
- module=derived_bt_device, required=False)
-
- if self.derived_bt_devices is None:
- self.derived_bt_devices = []
- else:
- for derived_device in self.derived_bt_devices:
- derived_device.set_user_params(self.user_params)
- derived_device.setup()
-
- self.android_ui_devices = {}
- # Create a dictionary of Android UI Devices
- for device in self.android_devices:
- self.android_ui_devices[device.serial] = AdbUiDevice(device)
- mobly_config = {'aud': self.android_ui_devices[device.serial]}
- device.load_config(mobly_config)
- need_restart_bluetooth = False
- if (self.enable_bluetooth_verbose_logging or
- self.enable_all_bluetooth_logging):
- if self.set_bt_trc_level_verbose(device):
- need_restart_bluetooth = True
- if self.enable_hci_snoop_logging or self.enable_all_bluetooth_logging:
- if self.set_btsnooplogmode_full(device):
- need_restart_bluetooth = True
- if self.increase_logger_buffers or self.enable_all_bluetooth_logging:
- self.set_logger_buffer_size_16m(device)
-
- # Restarts Bluetooth to take BT VERBOSE and HCI Snoop logging effect.
- if need_restart_bluetooth:
- device.log.info('Restarting Bluetooth by airplane mode...')
- self.restart_bluetooth_by_airplane_mode(device)
- self.android_devices = [AndroidBluetoothDecorator(device)
- for device in self.android_devices]
- for device in self.android_devices:
- device.set_user_params(self.user_params)
-
- self.client_decorators = self.user_params.get('sync_decorator', [])
- if self.client_decorators:
- self.client_decorators = self.client_decorators.split(',')
-
- self.target_decorators = self.user_params.get('target_decorator', [])
- if self.target_decorators:
- self.target_decorators = self.target_decorators.split(',')
-
- for decorator in self.client_decorators:
- self.android_devices[0] = android_bluetooth_client_decorator.decorate(
- self.android_devices[0], decorator)
-
- for num_devices in range(1, len(self.android_devices)):
- for decorator in self.target_decorators:
- self.android_devices[
- num_devices] = android_bluetooth_client_decorator.decorate(
- self.android_devices[num_devices], decorator)
-
- def on_fail(self, record):
- """This method is called when a test failure."""
- # Capture bugreports on fail if enabled.
- if self.capture_bugreport_on_fail:
- devices = self.android_devices
- # Also capture bugreport of AndroidBtTargetDevice.
- for d in self.derived_bt_devices:
- if hasattr(d, 'take_bug_report'):
- devices = devices + [d]
- android_device.take_bug_reports(
- devices,
- record.test_name,
- record.begin_time,
- destination=self.current_test_info.output_path)
-
- def set_logger_buffer_size_16m(self, device):
- """Sets all logger sizes per log buffer to 16M."""
- device.log.info('Setting all logger sizes per log buffer to 16M...')
- # Logger buffer info:
- # https://developer.android.com/studio/command-line/logcat#alternativeBuffers
- logger_buffers = ['main', 'system', 'crash', 'radio', 'events', 'kernel']
- for buffer in logger_buffers: # pylint: disable=redefined-builtin
- device.adb.shell('logcat -b %s -G 16M' % buffer)
- buffer_size = device.adb.shell('logcat -b %s -g' % buffer)
- if isinstance(buffer_size, bytes):
- buffer_size = buffer_size.decode()
- if 'ring buffer is 16' in buffer_size:
- device.log.info('Successfully set "%s" buffer size to 16M.' % buffer)
- else:
- msg = 'Failed to set "%s" buffer size to 16M.' % buffer
- if not self.ignore_device_setup_failures:
- raise signals.TestError(msg)
- device.log.warning(msg)
-
- def set_bt_trc_level_verbose(self, device):
- """Modifies etc/bluetooth/bt_stack.conf to enable Bluetooth VERBOSE log."""
- device.log.info('Enabling Bluetooth VERBOSE logging...')
- bt_stack_conf = device.adb.shell('cat etc/bluetooth/bt_stack.conf')
- if isinstance(bt_stack_conf, bytes):
- bt_stack_conf = bt_stack_conf.decode()
- # Check if 19 trace level settings are set to 6(VERBOSE). E.g. TRC_HCI=6.
- if len(re.findall('TRC.*=[6]', bt_stack_conf)) == 19:
- device.log.info('Bluetooth VERBOSE logging has already enabled.')
- return False
- # Suggest to use AndroidDeviceSettingsDecorator to disable verity and then
- # reboot (b/140277443).
- disable_verity_check(device)
- device.adb.remount()
- try:
- device.adb.shell(r'sed -i "s/\(TRC.*=\)2/\16/g;s/#\(LoggingV=--v=\)0/\13'
- '/" etc/bluetooth/bt_stack.conf')
- device.log.info('Successfully enabled Bluetooth VERBOSE Logging.')
- return True
- except adb.AdbError:
- msg = 'Failed to enable Bluetooth VERBOSE Logging.'
- if not self.ignore_device_setup_failures:
- raise signals.TestError(msg)
- device.log.warning(msg)
- return False
-
- def set_btsnooplogmode_full(self, device):
- """Enables bluetooth snoop logging."""
- device.log.info('Enabling Bluetooth HCI Snoop logging...')
- device.adb.shell('setprop persist.bluetooth.btsnooplogmode full')
- out = device.adb.shell('getprop persist.bluetooth.btsnooplogmode')
- if isinstance(out, bytes):
- out = out.decode()
- # The expected output is "full/n".
- if 'full' in out:
- device.log.info('Successfully enabled Bluetooth HCI Snoop Logging.')
- return True
- msg = 'Failed to enable Bluetooth HCI Snoop Logging.'
- if not self.ignore_device_setup_failures:
- raise signals.TestError(msg)
- device.log.warning(msg)
- return False
-
- def restart_bluetooth_by_airplane_mode(self, device):
- """Restarts bluetooth by airplane mode."""
- enable_airplane_mode(device, 3)
- disable_airplane_mode(device, 3)
diff --git a/blueberry/utils/bt_audio_utils.py b/blueberry/utils/bt_audio_utils.py
deleted file mode 100644
index a4c2e8e..0000000
--- a/blueberry/utils/bt_audio_utils.py
+++ /dev/null
@@ -1,229 +0,0 @@
-# Lint as: python3
-"""Utils for bluetooth audio testing."""
-
-import logging as log
-import os
-import numpy as np
-from scipy import signal as scipy_signal
-from scipy.io import wavfile
-# Internal import
-# Internal import
-
-
-def generate_sine_wave_to_device(
- device,
- pushed_file_path='/sdcard/Music',
- frequency=480,
- channel=2,
- sample_rate=48000,
- sample_format=16,
- duration_sec=10):
- """Generates a fixed frequency sine wave file and push it to the device.
-
- Generates a sine wave to the Mobly device directory and push it to the device
- storage. The output file name format is such as the example:
- sine_480hz_2ch_48000rate_16bit_10sec.wav
-
- Args:
- device: AndroidDevice, Mobly Android controller class.
- pushed_file_path: string, the wave file path which is pushed to the device
- storage. E.g. /sdcard/Music
- frequency: int, fixed frequency in Hz.
- channel: int, number of channels.
- sample_rate: int, sampling rate in Hz.
- sample_format: int, sampling format in bit.
- duration_sec: int, audio duration in second.
-
- Returns:
- device_storage_path: string, the wave file on the device storage.
- mobly_directory_path: string, the wave file on the Mobly device directory.
- """
- file_name = 'sine_%dhz_%dch_%drate_%dbit_%dsec.wav' % (
- frequency, channel, sample_rate, sample_format, duration_sec)
- mobly_directory_path = os.path.join(device.log_path, file_name)
- os.system('%s -n -c %d -r %d -b %d %s synth %d sine %d' %
- (audio_processor.AudioProcessor.SOX, channel, sample_rate,
- sample_format, mobly_directory_path, duration_sec, frequency))
- device.adb.push([mobly_directory_path, pushed_file_path])
- device_storage_path = os.path.join(pushed_file_path, file_name)
- return device_storage_path, mobly_directory_path
-
-
-def measure_audio_mos(recorded_audio_file, reference_audio_file):
- """Measures mean opinion score (MOS) of a recorded audio.
-
- This function uses the module of A/V Analysis Service to measure MOS:
- Internal reference
-
- Args:
- recorded_audio_file: string, the recorded audio file to be measured.
- reference_audio_file: string, the reference audio file for comparison.
-
- Returns:
- Float which is the mean opinion score of the recorded audio.
- """
- results = audio_calculator.AudioAnalyzer().Analyze(reference_audio_file,
- recorded_audio_file)
- # Returns 0.0 if the results fails to be generated.
- if not results:
- log.warning('Failed to generate the audio analysis results.')
- return 0.0
- return results[0].mos
-
-
-def measure_fundamental_frequency(signal, sample_rate):
- """Measures fundamental frequency of a signal.
-
- Args:
- signal: An 1-D array representing the signal data.
- sample_rate: int, sample rate of the signal.
-
- Returns:
- Float representing the fundamental frequency.
- """
- return sample_rate * (np.argmax(np.abs(np.fft.rfft(signal))) / len(signal))
-
-
-def measure_rms(signal):
- """Measures Root Mean Square (RMS) of a signal.
-
- Args:
- signal: An 1-D array representing the signal data.
-
- Returns:
- Float representing the root mean square.
- """
- return np.sqrt(np.mean(np.absolute(signal)**2))
-
-
-def measure_thdn(signal, sample_rate, q, frequency=None):
- """Measures Total Harmonic Distortion + Noise (THD+N) of a signal.
-
- Args:
- signal: An 1-D array representing the signal data.
- sample_rate: int, sample rate of the signal.
- q: float, quality factor for the notch filter.
- frequency: float, fundamental frequency of the signal. All other frequencies
- are noise. If not specified, will be calculated using FFT.
-
- Returns:
- Float representing THD+N ratio calculated from the ratio of RMS of pure
- harmonics and noise signal to RMS of original signal.
- """
- # Normalizes the signal.
- signal -= np.mean(signal)
- # Gets Blackman-Harris window from the signal.
- window = signal * scipy_signal.blackmanharris(len(signal))
- # Finds the fundamental frequency to remove if not specified.
- if not frequency:
- frequency = measure_fundamental_frequency(window, sample_rate)
- # Creates a notch filter to get noise from the signal.
- wo = frequency / (sample_rate / 2)
- b, a = scipy_signal.iirnotch(wo, q)
- noise = scipy_signal.lfilter(b, a, window)
- return measure_rms(noise) / measure_rms(window)
-
-
-def measure_audio_thdn_per_window(
- audio_file,
- thdn_threshold,
- step_size,
- window_size,
- q,
- frequency=None):
- """Measures Total Harmonic Distortion + Noise (THD+N) of an audio file.
-
- This function is used to capture audio glitches from a recorded audio file,
- and the audio file shall record a fixed frequency sine wave.
-
- Args:
- audio_file: A .wav file to be measured.
- thdn_threshold: float, a THD+N threshold used to compare with the measured
- THD+N for every windows. If THD+N of a window is greater than the
- threshold, will record this to results.
- step_size: int, number of samples to move the window by for each analysis.
- window_size: int, number of samples to analyze each time.
- q: float, quality factor for the notch filter.
- frequency: float, fundamental frequency of the signal. All other frequencies
- are noise. If not specified, will be calculated using FFT.
-
- Returns:
- List containing each result of channels. Like the following structure:
- ```
- [
- [ # result of channel 1
- {
- "thd+n": <float>, # THD+N of a window
- "start_time": <float>, # start time of a window
- "end_time": <float>, # end time of a window
- },
- ...,
- ],
- [...,] # result of channel 2
- ...,
- ]
- ```
- """
- if step_size <= 0:
- raise ValueError('step_size shall be greater than 0.')
- if window_size <= 0:
- raise ValueError('window_size shall be greater than 0.')
- sample_rate, wave_data = wavfile.read(audio_file)
- wave_data = wave_data.astype('float64')
- # Collects the result for each channels.
- results = []
- for signal in wave_data.transpose():
- current_position = 0
- channel_result = []
- while current_position + window_size < len(signal):
- window = signal[current_position:current_position + window_size]
- thdn = measure_thdn(
- signal=window,
- sample_rate=sample_rate,
- q=q,
- frequency=frequency)
- start_time = current_position / sample_rate
- end_time = (current_position + window_size) / sample_rate
- if thdn > thdn_threshold:
- channel_result.append({
- 'thd+n': thdn,
- 'start_time': start_time,
- 'end_time': end_time
- })
- current_position += step_size
- results.append(channel_result)
- return results
-
-
-def trim_audio(audio_file: str,
- duration_sec: float,
- start_time_sec: float = 0.0) -> str:
- """Trims an audio file with a specific start time and duration.
-
- Generates a output file and its name is such as below format:
- `<input file name>_<start time sec>-<duration sec>.<input file type>`
-
- Args:
- audio_file: string, an audio file to be trimed.
- duration_sec: float, the duration of the output file in seconds.
- start_time_sec: float, the start time of the audio file to be trimmed in
- seconds. Default value is 0.0 second if not specified.
-
- Returns:
- String, the output file of the same path of the origin file.
- """
- file_path, file_name = os.path.split(audio_file)
- file_name, file_ext = os.path.splitext(file_name)
- output_file_name = '%s_%s-%s%s' % (
- file_name,
- start_time_sec,
- (start_time_sec + duration_sec),
- file_ext)
- output_file = os.path.join(file_path, output_file_name)
- processor = audio_processor.AudioProcessor()
- processor.TrimAudio(
- input_file=audio_file,
- output_file=output_file,
- duration=duration_sec,
- start=start_time_sec)
- return output_file
diff --git a/blueberry/utils/bt_constants.py b/blueberry/utils/bt_constants.py
deleted file mode 100644
index 6a94e83..0000000
--- a/blueberry/utils/bt_constants.py
+++ /dev/null
@@ -1,191 +0,0 @@
-# Lint as: python3
-"""Constants used for bluetooth test."""
-
-import enum
-
-
-### Generic Constants Begin ###
-BT_DEFAULT_TIMEOUT_SECONDS = 15
-DEFAULT_RFCOMM_TIMEOUT_MS = 10000
-CALL_STATE_IDLE = 0
-CALL_STATE_RINGING = 1
-CALL_STATE_OFFHOOK = 2
-CALL_STATE_TIMEOUT_SEC = 30
-NAP_CONNECTION_TIMEOUT_SECS = 20
-
-# Call log types.
-INCOMING_CALL_LOG_TYPE = '1'
-OUTGOING_CALL_LOG_TYPE = '2'
-MISSED_CALL_LOG_TYPE = '3'
-
-# Passthrough Commands sent to the RPC Server.
-CMD_MEDIA_PLAY = 'play'
-CMD_MEDIA_PAUSE = 'pause'
-CMD_MEDIA_SKIP_NEXT = 'skipNext'
-CMD_MEDIA_SKIP_PREV = 'skipPrev'
-
-# Events dispatched from the RPC Server.
-EVENT_PLAY_RECEIVED = 'playReceived'
-EVENT_PAUSE_RECEIVED = 'pauseReceived'
-EVENT_SKIP_NEXT_RECEIVED = 'skipNextReceived'
-EVENT_SKIP_PREV_RECEIVED = 'skipPrevReceived'
-
-# A playback state indicating the media session is currently paused.
-STATE_PAUSED = 2
-STATE_PLAYING = 3
-
-# File path
-RAMDUMP_PATH = 'data/vendor/ssrdump'
-
-# UiAutoHelper package name.
-UIAUTO_HELPER_PACKAGE_NAME = 'com.google.android.uiautohelper'
-
-# Test Runner for Android instrumentation test.
-ANDROIDX_TEST_RUNNER = 'androidx.test.runner.AndroidJUnitRunner'
-
-# Wifi hotspot setting
-WIFI_HOTSPOT_2_4G = {'SSID': 'pqmBT', 'password': 'password', 'apBand': 0}
-
-
-class AvrcpEvent(enum.Enum):
- """Enumeration of AVRCP event types."""
- PLAY = 'State:NOT_PLAYING->PLAYING'
- PAUSE = 'State:PLAYING->NOT_PLAYING'
- TRACK_PREVIOUS = 'sendMediaKeyEvent: keyEvent=76'
- TRACK_NEXT = 'sendMediaKeyEvent: keyEvent=75'
-
-# Bluetooth RFCOMM UUIDs as defined by the SIG
-BT_RFCOMM_UUIDS = {
- 'default_uuid': '457807c0-4897-11df-9879-0800200c9a66',
- 'base_uuid': '00000000-0000-1000-8000-00805F9B34FB',
- 'sdp': '00000001-0000-1000-8000-00805F9B34FB',
- 'udp': '00000002-0000-1000-8000-00805F9B34FB',
- 'rfcomm': '00000003-0000-1000-8000-00805F9B34FB',
- 'tcp': '00000004-0000-1000-8000-00805F9B34FB',
- 'tcs_bin': '00000005-0000-1000-8000-00805F9B34FB',
- 'tcs_at': '00000006-0000-1000-8000-00805F9B34FB',
- 'att': '00000007-0000-1000-8000-00805F9B34FB',
- 'obex': '00000008-0000-1000-8000-00805F9B34FB',
- 'ip': '00000009-0000-1000-8000-00805F9B34FB',
- 'ftp': '0000000A-0000-1000-8000-00805F9B34FB',
- 'http': '0000000C-0000-1000-8000-00805F9B34FB',
- 'wsp': '0000000E-0000-1000-8000-00805F9B34FB',
- 'bnep': '0000000F-0000-1000-8000-00805F9B34FB',
- 'upnp': '00000010-0000-1000-8000-00805F9B34FB',
- 'hidp': '00000011-0000-1000-8000-00805F9B34FB',
- 'hardcopy_control_channel': '00000012-0000-1000-8000-00805F9B34FB',
- 'hardcopy_data_channel': '00000014-0000-1000-8000-00805F9B34FB',
- 'hardcopy_notification': '00000016-0000-1000-8000-00805F9B34FB',
- 'avctp': '00000017-0000-1000-8000-00805F9B34FB',
- 'avdtp': '00000019-0000-1000-8000-00805F9B34FB',
- 'cmtp': '0000001B-0000-1000-8000-00805F9B34FB',
- 'mcap_control_channel': '0000001E-0000-1000-8000-00805F9B34FB',
- 'mcap_data_channel': '0000001F-0000-1000-8000-00805F9B34FB',
- 'l2cap': '00000100-0000-1000-8000-00805F9B34FB'
-}
-
-
-class BluetoothAccessLevel(enum.IntEnum):
- """Enum class for bluetooth profile access levels."""
- ACCESS_ALLOWED = 1
- ACCESS_DENIED = 2
-
-
-class BluetoothProfile(enum.IntEnum):
- """Enum class for bluetooth profile types.
-
- Should be kept in sync with
- //frameworks/base/core/java/android/bluetooth/BluetoothProfile.java
- """
-
- HEADSET = 1
- A2DP = 2
- HEALTH = 3
- HID_HOST = 4
- PAN = 5
- PBAP = 6
- GATT = 7
- GATT_SERVER = 8
- MAP = 9
- SAP = 10
- A2DP_SINK = 11
- AVRCP_CONTROLLER = 12
- AVRCP = 13
- HEADSET_CLIENT = 16
- PBAP_CLIENT = 17
- MAP_MCE = 18
- HID_DEVICE = 19
- OPP = 20
- HEARING_AID = 21
-
-
-class BluetoothConnectionPolicy(enum.IntEnum):
- """Enum class for bluetooth bluetooth connection policy.
-
- bluetooth connection policy as defined in
- //frameworks/base/core/java/android/bluetooth/BluetoothProfile.java
- """
- CONNECTION_POLICY_UNKNOWN = -1
- CONNECTION_POLICY_FORBIDDEN = 0
- CONNECTION_POLICY_ALLOWED = 100
-
-
-class BluetoothConnectionStatus(enum.IntEnum):
- """Enum class for bluetooth connection status.
-
- Bluetooth connection status as defined in
- //frameworks/base/core/java/android/bluetooth/BluetoothProfile.java
- """
- STATE_DISCONNECTED = 0
- STATE_CONNECTING = 1
- STATE_CONNECTED = 2
- STATE_DISCONNECTING = 3
-
-
-class BluetoothPriorityLevel(enum.IntEnum):
- """Enum class for bluetooth priority level.
-
- Priority levels as defined in
- //frameworks/base/core/java/android/bluetooth/BluetoothProfile.java
- """
-
- PRIORITY_AUTO_CONNECT = 1000
- PRIORITY_ON = 100
- PRIORITY_OFF = 0
- PRIORITY_UNDEFINED = -1
-
-
-class BleAdvertiseSettingsMode(enum.IntEnum):
- """Enum class for BLE advertise settings mode."""
- LOW_POWER = 0
- BALANCED = 1
- LOW_LATENCY = 2
-
-
-class BleAdvertiseSettingsTxPower(enum.IntEnum):
- """Enum class for BLE advertise settings tx power."""
- ULTRA_LOW = 0
- LOW = 1
- MEDIUM = 2
- HIGH = 3
-
-
-class LogType(enum.Enum):
- """Enumeration of device log type."""
- DEFAULT_VALUE = 'GENERIC'
- BLUETOOTH_DEVICE_SIMULATOR = 'BDS'
- ICLEVER_HB01 = 'GENERIC'
-
-
-class CallState(enum.IntEnum):
- """Enum class for phone call state."""
- IDLE = 0
- RINGING = 1
- OFFHOOK = 2
-
-
-class CallLogType(enum.IntEnum):
- """Enum class for phone call log type."""
- INCOMING_CALL = 1
- OUTGOING_CALL = 2
- MISSED_CALL = 3
diff --git a/blueberry/utils/bt_test_utils.py b/blueberry/utils/bt_test_utils.py
deleted file mode 100644
index e9d6ec0..0000000
--- a/blueberry/utils/bt_test_utils.py
+++ /dev/null
@@ -1,200 +0,0 @@
-# Lint as: python3
-"""Utils for blue tooth tests.
-
-Partly ported from acts/framework/acts/test_utils/bt/bt_test_utils.py
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import logging as log
-import os
-import random
-import string
-import time
-import wave
-
-
-def convert_pcm_to_wav(pcm_file_path, wave_file_path, audio_params):
- """Converts raw pcm data into wave file.
-
- Args:
- pcm_file_path: File path of origin pcm file.
- wave_file_path: File path of converted wave file.
- audio_params: A dict with audio configuration.
- """
- with open(pcm_file_path, 'rb') as pcm_file:
- frames = pcm_file.read()
- write_record_file(wave_file_path, audio_params, frames)
-
-
-def create_vcf_from_vcard(output_path: str,
- num_of_contacts: int,
- first_name: str = None,
- last_name: str = None,
- phone_number: int = None) -> str:
- """Creates a vcf file from vCard.
-
- Args:
- output_path: Path of the output vcf file.
- num_of_contacts: Number of contacts to be generated.
- first_name: First name of the contacts.
- last_name: Last name of the contacts.
- phone_number: Phone number of the contacts.
-
- Returns:
- vcf_file_path: Path of the output vcf file. E.g.
- "/<output_path>/contacts_<time>.vcf".
- """
- file_name = f'contacts_{int(time.time())}.vcf'
- vcf_file_path = os.path.join(output_path, file_name)
- with open(vcf_file_path, 'w+') as f:
- for i in range(num_of_contacts):
- lines = []
- if first_name is None:
- first_name = 'Person'
- vcard_last_name = last_name
- if last_name is None:
- vcard_last_name = i
- vcard_phone_number = phone_number
- if phone_number is None:
- vcard_phone_number = random.randrange(int(10e10))
- lines.append('BEGIN:VCARD\n')
- lines.append('VERSION:2.1\n')
- lines.append(f'N:{vcard_last_name};{first_name};;;\n')
- lines.append(f'FN:{first_name} {vcard_last_name}\n')
- lines.append(f'TEL;CELL:{vcard_phone_number}\n')
- lines.append(f'EMAIL;PREF:{first_name}{vcard_last_name}@gmail.com\n')
- lines.append('END:VCARD\n')
- f.write(''.join(lines))
- return vcf_file_path
-
-
-def generate_id_by_size(size,
- chars=(string.ascii_lowercase + string.ascii_uppercase +
- string.digits)):
- """Generate random ascii characters of input size and input char types.
-
- Args:
- size: Input size of string.
- chars: (Optional) Chars to use in generating a random string.
-
- Returns:
- String of random input chars at the input size.
- """
- return ''.join(random.choice(chars) for _ in range(size))
-
-
-def get_duration_seconds(wav_file_path):
- """Get duration of most recently recorded file.
-
- Args:
- wav_file_path: path of the wave file.
-
- Returns:
- duration (float): duration of recorded file in seconds.
- """
- f = wave.open(wav_file_path, 'r')
- frames = f.getnframes()
- rate = f.getframerate()
- duration = (frames / float(rate))
- f.close()
- return duration
-
-
-def wait_until(timeout_sec,
- condition_func,
- func_args,
- expected_value,
- exception=None,
- interval_sec=0.5):
- """Waits until a function returns a expected value or timeout is reached.
-
- Example usage:
- ```
- def is_bluetooth_enabled(device) -> bool:
- do something and return something...
-
- # Waits and checks if Bluetooth is turned on.
- bt_test_utils.wait_until(
- timeout_sec=10,
- condition_func=is_bluetooth_enabled,
- func_args=[dut],
- expected_value=True,
- exception=signals.TestFailure('Failed to turn on Bluetooth.'),
- interval_sec=1)
- ```
-
- Args:
- timeout_sec: float, max waiting time in seconds.
- condition_func: function, when the condiction function returns the expected
- value, the waiting mechanism will be interrupted.
- func_args: tuple or list, the arguments for the condition function.
- expected_value: a expected value that the condition function returns.
- exception: Exception, an exception will be raised when timed out if needed.
- interval_sec: float, interval time between calls of the condition function
- in seconds.
-
- Returns:
- True if the function returns the expected value else False.
- """
- start_time = time.time()
- end_time = start_time + timeout_sec
- while time.time() < end_time:
- if condition_func(*func_args) == expected_value:
- return True
- time.sleep(interval_sec)
- args_string = ', '.join(list(map(str, func_args)))
- log.warning('Timed out after %.1fs waiting for "%s(%s)" to be "%s".',
- timeout_sec, condition_func.__name__, args_string, expected_value)
- if exception:
- raise exception
- return False
-
-
-def write_read_verify_data_sl4a(client_ad, server_ad, msg, binary=False):
- """Verify that the client wrote data to the server Android device correctly.
-
- Args:
- client_ad: the Android device to perform the write.
- server_ad: the Android device to read the data written.
- msg: the message to write.
- binary: if the msg arg is binary or not.
-
- Returns:
- True if the data written matches the data read, false if not.
- """
- client_ad.log.info('Write message %s.', msg)
- if binary:
- client_ad.sl4a.bluetoothSocketConnWriteBinary(msg)
- else:
- client_ad.sl4a.bluetoothSocketConnWrite(msg)
- server_ad.log.info('Read message %s.', msg)
- if binary:
- read_msg = server_ad.sl4a.bluetoothSocketConnReadBinary().rstrip('\r\n')
- else:
- read_msg = server_ad.sl4a.bluetoothSocketConnRead()
- log.info('Verify message.')
- if msg != read_msg:
- log.error('Mismatch! Read: %s, Expected: %s', read_msg, msg)
- return False
- log.info('Matched! Read: %s, Expected: %s', read_msg, msg)
- return True
-
-
-def write_record_file(file_name, audio_params, frames):
- """Writes the recorded audio into the file.
-
- Args:
- file_name: The file name for writing the recorded audio.
- audio_params: A dict with audio configuration.
- frames: Recorded audio frames.
- """
- log.debug('writing frame to %s', file_name)
- wf = wave.open(file_name, 'wb')
- wf.setnchannels(audio_params['channel'])
- wf.setsampwidth(audio_params.get('sample_width', 1))
- wf.setframerate(audio_params['sample_rate'])
- wf.writeframes(frames)
- wf.close()
diff --git a/blueberry/utils/command_line_runner/run_bluetooth_tests.py b/blueberry/utils/command_line_runner/run_bluetooth_tests.py
deleted file mode 100644
index 3a186b8..0000000
--- a/blueberry/utils/command_line_runner/run_bluetooth_tests.py
+++ /dev/null
@@ -1,248 +0,0 @@
-"""Command-line test runner script for running Bluetooth tests.
-
-This module allows users to initiate Bluetooth test targets and run them against
-specified DUTs (devices-under-test) using a simple command line interface.
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-
-from __future__ import print_function
-
-import base64
-
-from absl import app
-from absl import flags
-from absl import logging
-
-# Internal import
-# Internal import
-# Internal import
-# Internal import
-# Internal import
-
-FLAGS = flags.FLAGS
-
-flags.DEFINE_multi_string('bt_test', None, 'Bluetooth test to run.')
-flags.DEFINE_multi_string('bt_dut', None,
- 'Bluetooth device to allocate for tests.')
-
-
-# Valid config keys for the --bt_test command line flag.
-BT_TEST_CONFIG_KEYS = {'target'}
-
-# Valid config keys for the --bt_dut (device-under-test) command line flag.
-BT_DUT_CONFIG_KEYS = {'hardware'}
-
-TEST_FLAGS = ('--notest_loasd --test_output=streamed '
- '--test_arg=--param_dut_config=%s')
-
-
-class Error(Exception):
- """Base class for module exceptions."""
- pass
-
-
-class TestConfigError(Error):
- """Raised when --bt_test config flags are specified incorrectly."""
- pass
-
-
-class DutConfigError(Error):
- """Raised when --bt_dut config flags are specified incorrectly."""
- pass
-
-
-def validate_bt_test_flags(flag_value):
- """Validates the format of specified --bt_test flags.
-
- Args:
- flag_value: string, the config flag value for a given --bt_test flag.
-
- Returns:
- bool, True if --bt_test flags have been specified correctly.
- """
- if not flag_value:
- logging.error('No tests specified! Please specify at least one '
- 'test using the --bt_test flag.')
- return False
- for test in flag_value:
- config_args = test.split(',')
- for config_arg in config_args:
- if config_arg.split('=')[0] not in BT_TEST_CONFIG_KEYS:
- logging.error('--bt_test config key "%s" is invalid!',
- config_arg.split('=')[0])
- return False
- return True
-
-
-def validate_bt_dut_flags(flag_value):
- """Validates the format of specified --bt_dut flags.
-
- Args:
- flag_value: string, the config flag value for a given --bt_dut flag.
-
- Returns:
- bool, True if --bt_dut flags have been specified correctly.
- """
- if not flag_value:
- logging.error('No DUTs specified! Please specify at least one '
- 'DUT using the --bt_dut flag.')
- return False
- for dut in flag_value:
- config_args = dut.split(',')
- for config_arg in config_args:
- if config_arg.split('=')[0] not in BT_DUT_CONFIG_KEYS:
- logging.error('--bt_dut config key "%s" is invalid!',
- config_arg.split('=')[0])
- return False
- return True
-
-flags.register_validator(
- 'bt_test', validate_bt_test_flags,
- ('Invalid --bt_test configuration specified!'
- ' Valid configuration fields include: %s')
- % BT_TEST_CONFIG_KEYS)
-
-
-flags.register_validator(
- 'bt_dut', validate_bt_dut_flags,
- ('Invalid --bt_dut configuration specified!'
- ' Valid configuration fields include: %s')
- % BT_DUT_CONFIG_KEYS)
-
-
-def parse_flag_value(flag_value):
- """Parses a config flag value string into a dict.
-
- Example input: 'target=//tests:bluetooth_pairing_test'
- Example output: {'target': '//tests:bluetooth_pairing_test'}
-
- Args:
- flag_value: string, the config flag value for a given flag.
-
- Returns:
- dict, A dict object representation of a config flag value.
- """
- config_dict = {}
- config_args = flag_value.split(',')
- for config_arg in config_args:
- config_dict[config_arg.split('=')[0]] = config_arg.split('=')[1]
- return config_dict
-
-
-def get_device_type(gateway_stub, dut_config_dict):
- """Determines a device type based on a device query.
-
- Args:
- gateway_stub: An RPC2 stub object.
- dut_config_dict: dict, A dict of device config args.
-
- Returns:
- string, The MobileHarness device type.
-
- Raises:
- DutConfigError: If --bt_dut flag(s) are incorrectly specified.
- """
- device_query_filter = device_query_pb2.DeviceQueryFilter()
- device_query_filter.type_regex.append('AndroidRealDevice')
- for dut_config_key in dut_config_dict:
- dimension_filter = device_query_filter.dimension_filter.add()
- dimension_filter.name = dut_config_key
- dimension_filter.value_regex = dut_config_dict[dut_config_key]
- request = gateway_service_pb2.QueryDeviceRequest(
- device_query_filter=device_query_filter)
- response = gateway_stub.QueryDevice(request)
- if response.device_query_result.device_info:
- return 'AndroidRealDevice'
-
- device_query_filter.ClearField('type_regex')
- device_query_filter.type_regex.append('TestbedDevice')
- request = gateway_service_pb2.QueryDeviceRequest(
- device_query_filter=device_query_filter)
- response = gateway_stub.QueryDevice(request)
- if response.device_query_result.device_info:
- return 'TestbedDevice'
-
- raise DutConfigError('Invalid --bt_dut config specified: %s' %
- dut_config_dict)
-
-
-def generate_dut_configs(gateway_stub):
- """Generates a unicode string specifying the desired DUT configurations.
-
- Args:
- gateway_stub: An RPC2 stub object.
-
- Returns:
- string, Unicode string specifying DUT configurations.
-
- Raises:
- DutConfigError: If --bt_dut flag(s) are incorrectly specified.
- """
- dut_list = job_config_pb2.JobConfig().DeviceList()
- dut_config_dict_list = [parse_flag_value(value) for value in FLAGS.bt_dut]
-
- for dut_config_dict in dut_config_dict_list:
- dut_config_dict['pool'] = 'bluetooth-iop'
- dut = job_config_pb2.JobConfig().SubDeviceSpec()
- if 'hardware' not in dut_config_dict:
- raise DutConfigError('Must specify hardware name for bt_dut: %s' %
- dut_config_dict)
- dut.type = get_device_type(gateway_stub, dut_config_dict)
- for config_key in dut_config_dict:
- dut.dimensions.content[config_key] = dut_config_dict[config_key]
- dut_list.sub_device_spec.append(dut)
- logging.info(base64.b64encode(dut_list.SerializeToString()).decode('utf-8'))
- return base64.b64encode(dut_list.SerializeToString()).decode('utf-8')
-
-
-def generate_blaze_targets(session_config, gateway_stub):
- """Generates and appends blaze test targets to a MobileHarness session.
-
- Args:
- session_config: The SessionConfig object to append blaze test targets to.
- gateway_stub: An RPC2 stub object.
-
- Raises:
- TestConfigError: If --bt_test flag(s) are incorrectly specified.
- """
- test_config_dict_list = [parse_flag_value(value) for value in FLAGS.bt_test]
-
- for test_config_dict in test_config_dict_list:
- target = setting_pb2.BlazeTarget()
- if 'target' not in test_config_dict:
- raise TestConfigError('Must specify a target for bt_test: %s' %
- test_config_dict)
- target.target_name = test_config_dict['target']
- target.test_flags = TEST_FLAGS % generate_dut_configs(gateway_stub)
- session_config.blaze_target.append(target)
-
-
-def run_session():
- """Runs a configured test session.
-
- Returns:
- A RunSessionResponse object.
- """
- session_config = setting_pb2.SessionConfig()
- channel = rpcutil.GetNewChannel('blade:mobileharness-gateway')
- gateway_stub = gateway_service_pb2.GatewayService.NewRPC2Stub(channel=channel)
- generate_blaze_targets(session_config, gateway_stub)
- request = gateway_service_pb2.RunSessionRequest()
- request.session_config.CopyFrom(session_config)
- response = gateway_stub.RunSession(request)
- logging.info('Sponge link: %s', response.sponge)
- logging.info('Session ID: %s', response.session_id)
- return response
-
-
-def main(argv):
- logging.use_python_logging()
- del argv
- run_session()
-
-if __name__ == '__main__':
- flags.mark_flag_as_required('bt_test')
- flags.mark_flag_as_required('bt_dut')
- app.run(main)
diff --git a/blueberry/utils/metrics_utils.py b/blueberry/utils/metrics_utils.py
deleted file mode 100644
index b62b9e9..0000000
--- a/blueberry/utils/metrics_utils.py
+++ /dev/null
@@ -1,111 +0,0 @@
-"""Metrics reporting module for Blueberry using protobuf.
-
-Internal reference
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-
-from __future__ import print_function
-
-import base64
-import logging
-import time
-
-# Internal import
-
-
-class BluetoothMetricLogger(object):
- """A class used for gathering metrics from tests and devices.
-
- This class provides methods to allow test writers to easily export metrics
- from their tests as protobuf messages.
-
- Attributes:
- _metrics: The Bluetooth test proto message to add metrics to.
- """
-
- def __init__(self, bluetooth_test_proto_message):
- self._metrics = bluetooth_test_proto_message
- self._start_time = int(time.time())
-
- def add_primary_device_metrics(self, device):
- """Adds primary device metrics to the test proto message.
-
- Args:
- device: The Bluetooth device object to gather device metrics from.
- """
- device_message = self._metrics.configuration_data.primary_device
- message_fields = device_message.DESCRIPTOR.fields_by_name.keys()
- try:
- device_metrics_dict = device.get_device_info()
- except AttributeError:
- logging.info(
- 'Must implement get_device_info method for this controller in order to upload device metrics.'
- )
- return
-
- for metric in device_metrics_dict:
- if metric in message_fields:
- setattr(device_message, metric, device_metrics_dict[metric])
- else:
- logging.info('%s is not a valid metric field.', metric)
-
- def add_connected_device_metrics(self, device):
- """Adds connected device metrics to the test proto message.
-
- Args:
- device: The Bluetooth device object to gather device metrics from.
- """
- device_message = self._metrics.configuration_data.connected_device
- message_fields = device_message.DESCRIPTOR.fields_by_name.keys()
- try:
- device_metrics_dict = device.get_device_info()
- except AttributeError:
- logging.info(
- 'Must implement get_device_info method for this controller in order to upload device metrics.'
- )
- return
-
- for metric in device_metrics_dict:
- if metric in message_fields:
- setattr(device_message, metric, device_metrics_dict[metric])
- else:
- logging.warning('%s is not a valid metric field.', metric)
-
- def add_test_metrics(self, test_metrics_dict):
- """Adds test metrics to the test proto message.
-
- Args:
- test_metrics_dict: A dictionary of metrics to add to the test proto
- message. Metric will only be added if the key exists as a field in the
- test proto message.
- """
- if hasattr(self._metrics, 'configuration_data'):
- self._metrics.configuration_data.test_date_time = self._start_time
- message_fields = self._metrics.DESCRIPTOR.fields_by_name.keys()
- for metric in test_metrics_dict:
- if metric in message_fields:
- metric_value = test_metrics_dict[metric]
- if isinstance(metric_value, (list, tuple)):
- getattr(self._metrics, metric).extend(metric_value)
- else:
- setattr(self._metrics, metric, metric_value)
- else:
- logging.warning('%s is not a valid metric field.', metric)
-
- def proto_message_to_base64(self):
- """Converts a proto message to a base64 string.
-
- Returns:
- string, Message formatted as a base64 string.
- """
- return base64.b64encode(self._metrics.SerializeToString()).decode('utf-8')
-
- def proto_message_to_ascii(self):
- """Converts a proto message to an ASCII string.
-
- Returns:
- string, Message formatted as an ASCII string. Useful for debugging.
- """
- return text_format.MessageToString(self._metrics)
diff --git a/bta/Android.bp b/bta/Android.bp
deleted file mode 100644
index b91db34..0000000
--- a/bta/Android.bp
+++ /dev/null
@@ -1,527 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-cc_defaults {
- name: "fluoride_bta_defaults",
- defaults: ["fluoride_defaults"],
- local_include_dirs: [
- "include",
- "sys",
- "dm",
- "hd",
- "hh",
- ],
- include_dirs: [
- "system/bt",
- "system/bt/bta/include",
- "system/bt/btcore/include",
- "system/bt/btif/avrcp",
- "system/bt/btif/include",
- "system/bt/gd",
- "system/bt/hci/include",
- "system/bt/internal_include",
- "system/bt/stack/include",
- "system/bt/stack/btm",
- "system/bt/udrv/include",
- "system/bt/vnd/include",
- "system/bt/utils/include",
- "system/bt/gd/rust/shim",
- ],
- shared_libs: [
- "libcutils",
- ],
- header_libs: ["libbluetooth_headers"],
- cflags: ["-DBUILDCFG"],
-}
-
-filegroup {
- name: "BtaDmSources",
- srcs: [
- "dm/bta_dm_act.cc",
- "dm/bta_dm_api.cc",
- "dm/bta_dm_cfg.cc",
- "dm/bta_dm_ci.cc",
- "dm/bta_dm_main.cc",
- "dm/bta_dm_pm.cc",
- ],
-}
-
-// BTA static library for target
-cc_library_static {
- name: "libbt-bta",
- defaults: ["fluoride_bta_defaults"],
- srcs: [
- ":BtaDmSources",
- "ag/bta_ag_act.cc",
- "ag/bta_ag_api.cc",
- "ag/bta_ag_at.cc",
- "ag/bta_ag_cfg.cc",
- "ag/bta_ag_cmd.cc",
- "ag/bta_ag_main.cc",
- "ag/bta_ag_rfc.cc",
- "ag/bta_ag_sco.cc",
- "ag/bta_ag_sdp.cc",
- "ar/bta_ar.cc",
- "av/bta_av_aact.cc",
- "av/bta_av_act.cc",
- "av/bta_av_api.cc",
- "av/bta_av_cfg.cc",
- "av/bta_av_ci.cc",
- "av/bta_av_main.cc",
- "av/bta_av_ssm.cc",
- "csis/csis_client.cc",
- "gatt/bta_gattc_act.cc",
- "gatt/bta_gattc_api.cc",
- "gatt/bta_gattc_cache.cc",
- "gatt/bta_gattc_main.cc",
- "gatt/bta_gattc_queue.cc",
- "gatt/bta_gattc_utils.cc",
- "gatt/bta_gatts_act.cc",
- "gatt/bta_gatts_api.cc",
- "gatt/bta_gatts_main.cc",
- "gatt/bta_gatts_utils.cc",
- "gatt/database.cc",
- "gatt/database_builder.cc",
- "groups/groups.cc",
- "vc/device.cc",
- "vc/vc.cc",
- "le_audio/client.cc",
- "le_audio/devices.cc",
- "le_audio/hal_verifier.cc",
- "le_audio/state_machine.cc",
- "le_audio/client_parser.cc",
- "le_audio/client_audio.cc",
- "le_audio/le_audio_types.cc",
- "hearing_aid/hearing_aid.cc",
- "hearing_aid/hearing_aid_audio_source.cc",
- "hf_client/bta_hf_client_act.cc",
- "hf_client/bta_hf_client_api.cc",
- "hf_client/bta_hf_client_at.cc",
- "hf_client/bta_hf_client_main.cc",
- "hf_client/bta_hf_client_rfc.cc",
- "hf_client/bta_hf_client_sco.cc",
- "hf_client/bta_hf_client_sdp.cc",
- "hh/bta_hh_act.cc",
- "hh/bta_hh_api.cc",
- "hh/bta_hh_cfg.cc",
- "hh/bta_hh_le.cc",
- "hh/bta_hh_main.cc",
- "hh/bta_hh_utils.cc",
- "hd/bta_hd_act.cc",
- "hd/bta_hd_api.cc",
- "hd/bta_hd_main.cc",
- "jv/bta_jv_act.cc",
- "jv/bta_jv_api.cc",
- "jv/bta_jv_cfg.cc",
- "pan/bta_pan_act.cc",
- "pan/bta_pan_api.cc",
- "pan/bta_pan_ci.cc",
- "pan/bta_pan_main.cc",
- "sdp/bta_sdp.cc",
- "sdp/bta_sdp_act.cc",
- "sdp/bta_sdp_api.cc",
- "sdp/bta_sdp_cfg.cc",
- "sys/bta_sys_conn.cc",
- "sys/bta_sys_main.cc",
- "sys/utl.cc",
- ],
- static_libs: [
- "avrcp-target-service",
- "lib-bt-packets",
- ],
- shared_libs: [
- "android.hardware.bluetooth.audio@2.0",
- "android.hardware.bluetooth.audio@2.1",
- ],
- host_supported: true,
-}
-
-// bta unit tests for target
-cc_test {
- name: "net_test_bta",
- defaults: ["fluoride_bta_defaults"],
- test_suites: ["device-tests"],
- srcs: [
- ":TestMockStackBtm",
- ":TestCommonMockFunctions",
- "test/bta_hf_client_test.cc",
- "test/bta_dm_cust_uuid_test.cc",
- "test/bta_dip_test.cc",
- "test/gatt/database_builder_test.cc",
- "test/gatt/database_builder_sample_device_test.cc",
- "test/gatt/database_test.cc",
- ],
- shared_libs: [
- "libcrypto",
- "liblog",
- "libprotobuf-cpp-lite",
- ],
- static_libs: [
- "crypto_toolbox_for_tests",
- "libbtcore",
- "libbt-bta",
- "libbt-audio-hal-interface",
- "libbluetooth-types",
- "libbt-protos-lite",
- "libosi",
- "libbt-common",
- ],
-}
-
-cc_test {
- name: "bt_host_test_bta",
- defaults: ["fluoride_bta_defaults"],
- test_suites: ["device-tests"],
- host_supported: true,
- include_dirs: [
- "system/bt",
- "system/bt/gd",
- ],
- generated_headers: [
- "BluetoothGeneratedDumpsysDataSchema_h",
- "BluetoothGeneratedPackets_h",
- ],
- srcs: [
- ":OsiCompatSources",
- ":TestCommonMainHandler",
- ":TestMockBtif",
- ":TestMockDevice",
- ":TestMockMainShim",
- ":TestMockOsi",
- ":TestMockStack",
- "ar/bta_ar.cc",
- "dm/bta_dm_api.cc",
- "dm/bta_dm_act.cc",
- "dm/bta_dm_cfg.cc",
- "dm/bta_dm_ci.cc",
- "dm/bta_dm_main.cc",
- "dm/bta_dm_pm.cc",
- "gatt/bta_gattc_act.cc",
- "gatt/bta_gattc_api.cc",
- "gatt/bta_gattc_cache.cc",
- "gatt/bta_gattc_main.cc",
- "gatt/bta_gattc_queue.cc",
- "gatt/bta_gattc_utils.cc",
- "gatt/database.cc",
- "gatt/database_builder.cc",
- "hh/bta_hh_act.cc",
- "hh/bta_hh_api.cc",
- "hh/bta_hh_cfg.cc",
- "hh/bta_hh_le.cc",
- "hh/bta_hh_main.cc",
- "hh/bta_hh_utils.cc",
- "pan/bta_pan_act.cc",
- "pan/bta_pan_api.cc",
- "pan/bta_pan_main.cc",
- "sys/bta_sys_conn.cc",
- "sys/bta_sys_main.cc",
- "test/bta_dm_test.cc",
- "test/bta_gatt_test.cc",
- "test/bta_pan_test.cc",
- ],
- shared_libs: [
- "libcrypto",
- "libflatbuffers-cpp",
- "liblog",
- "libprotobuf-cpp-lite",
- ],
- static_libs: [
- "libbluetooth-types",
- "libbt-common",
- "libbt-protos-lite",
- "libbtcore",
- "libgmock",
- ],
- sanitize: {
- address: true,
- cfi: true,
- misc_undefined: ["bounds"],
- },
-}
-
-// bta hf client add record tests for target
-cc_test {
- name: "net_test_hf_client_add_record",
- defaults: ["fluoride_defaults"],
- test_suites: ["device-tests"],
- include_dirs: [
- "system/bt",
- "system/bt/gd",
- "system/bt/bta/include",
- "system/bt/bta/sys",
- "system/bt/btif/include",
- "system/bt/internal_include",
- "system/bt/stack/include",
- "system/bt/utils/include",
- ],
- srcs: [
- "test/bta_hf_client_add_record_test.cc",
- ],
- header_libs: ["libbluetooth_headers"],
- shared_libs: [
- "libcutils",
- "liblog",
- ],
- static_libs: [
- "libbluetooth-types",
- "libosi",
- ],
- cflags: ["-DBUILDCFG"],
-}
-
-// csis unit tests for host
-cc_test {
- name: "bluetooth_csis_test",
- test_suites: ["device-tests"],
- defaults: [
- "fluoride_bta_defaults",
- "clang_coverage_bin",
- ],
- host_supported: true,
- include_dirs: [
- "system/bt",
- "system/bt/bta/groups",
- "system/bt/bta/include",
- "system/bt/bta/test/common",
- "system/bt/btif/include",
- "system/bt/osi/include",
- ],
- srcs : [
- ":TestMockBtif",
- "csis/csis_client.cc",
- "csis/csis_client_test.cc",
- "groups/groups.cc",
- "gatt/database.cc",
- "gatt/database_builder.cc",
- "test/common/bta_dm_api_mock.cc",
- "test/common/bta_gatt_api_mock.cc",
- "test/common/bta_gatt_queue_mock.cc",
- "test/common/btm_api_mock.cc",
- ],
- shared_libs: [
- "libprotobuf-cpp-lite",
- "libcrypto",
- ],
- static_libs : [
- "crypto_toolbox_for_tests",
- "libgmock",
- "libbt-common",
- "libbt-protos-lite",
- "libosi",
- ],
- sanitize: {
- cfi: true,
- scs: true,
- address: true,
- all_undefined: true,
- integer_overflow: true,
- diag: {
- undefined : true
- },
- },
-}
-
-// groups unit tests for host
-cc_test {
- name: "bluetooth_groups_test",
- test_suites: ["device-tests"],
- defaults: [
- "fluoride_bta_defaults",
- "clang_coverage_bin",
- ],
- host_supported: true,
- include_dirs: [
- "system/bt",
- "system/bt/bta/include",
- ],
- srcs : [
- ":TestMockBtif",
- "groups/groups_test.cc",
- "groups/groups.cc",
- ],
- shared_libs: [
- "libprotobuf-cpp-lite",
- "libcrypto",
- ],
- static_libs : [
- "crypto_toolbox_for_tests",
- "libgmock",
- "libbt-common",
- "libbt-protos-lite",
- "libosi",
- ],
- sanitize: {
- cfi: true,
- scs: true,
- address: true,
- all_undefined: true,
- integer_overflow: true,
- diag: {
- undefined : true
- },
- },
-}
-
-// bta unit tests for host
-cc_test {
- name: "bluetooth_vc_test",
- test_suites: ["device-tests"],
- defaults: [
- "fluoride_bta_defaults",
- "clang_coverage_bin",
- ],
- host_supported: true,
- include_dirs: [
- "system/bt",
- "system/bt/bta/include",
- "system/bt/bta/test/common",
- "system/bt/stack/include",
- ],
- srcs : [
- ":TestMockOsi",
- "gatt/database.cc",
- "gatt/database_builder.cc",
- "test/common/bta_gatt_api_mock.cc",
- "test/common/bta_gatt_queue_mock.cc",
- "test/common/mock_csis_client.cc",
- "test/common/btm_api_mock.cc",
- "vc/devices_test.cc",
- "vc/device.cc",
- "vc/vc.cc",
- "vc/vc_test.cc",
- ],
- shared_libs: [
- "libprotobuf-cpp-lite",
- "libcrypto",
- ],
- static_libs : [
- "crypto_toolbox_for_tests",
- "libgmock",
- "libbt-common",
- "libbt-protos-lite",
- "libosi"
- ],
- sanitize: {
- cfi: false,
- },
-}
-
-// bta unit tests for LE Audio
-// ========================================================
-cc_test {
- name: "bluetooth_le_audio_test",
- test_suites: ["device-tests"],
- defaults: [
- "fluoride_defaults",
- "clang_coverage_bin",
- ],
- host_supported: true,
- include_dirs: [
- "system/bt",
- "system/bt/bta/include",
- "system/bt/bta/test/common",
- "system/bt/btif/include",
- "system/bt/gd",
- "system/bt/stack/include",
- ],
- srcs : [
- ":TestStubOsi",
- "test/common/bta_gatt_api_mock.cc",
- "test/common/bta_gatt_queue_mock.cc",
- "test/common/btm_api_mock.cc",
- "le_audio/client_audio.cc",
- "le_audio/client_audio_test.cc",
- "le_audio/client_parser.cc",
- "le_audio/client_parser_test.cc",
- "le_audio/devices.cc",
- "le_audio/devices_test.cc",
- "le_audio/le_audio_types.cc",
- "le_audio/le_audio_types_test.cc",
- "le_audio/mock_iso_manager.cc",
- "test/common/mock_controller.cc",
- "le_audio/state_machine.cc",
- "le_audio/state_machine_test.cc"
- ],
- shared_libs: [
- "libprotobuf-cpp-lite",
- "libcrypto",
- "liblog", // __android_log_print
- ],
- static_libs : [
- "libgmock",
- "libbt-common",
- "libbt-protos-lite",
- "libosi",
- ],
- sanitize: {
- cfi: false,
- },
-}
-
-cc_test {
- name: "bluetooth_le_audio_client_test",
- test_suites: ["device-tests"],
- defaults: [
- "fluoride_bta_defaults",
- "clang_coverage_bin",
- ],
- host_supported: true,
- include_dirs: [
- "system/bt",
- "system/bt/bta/include",
- "system/bt/bta/test/common",
- "system/bt/stack/include",
- ],
- srcs : [
- ":TestMockBtaLeAudioHalVerifier",
- "gatt/database.cc",
- "gatt/database_builder.cc",
- "le_audio/client.cc",
- "le_audio/client_parser.cc",
- "le_audio/devices.cc",
- "le_audio/le_audio_client_test.cc",
- "le_audio/le_audio_types.cc",
- "le_audio/mock_iso_manager.cc",
- "le_audio/mock_le_audio_client_audio.cc",
- "le_audio/mock_state_machine.cc",
- "test/common/btm_api_mock.cc",
- "test/common/bta_gatt_api_mock.cc",
- "test/common/bta_gatt_queue_mock.cc",
- "test/common/btif_storage_mock.cc",
- "test/common/mock_csis_client.cc",
- "test/common/mock_controller.cc",
- "test/common/mock_device_groups.cc",
- ],
- shared_libs: [
- "android.hardware.bluetooth.audio@2.0",
- "android.hardware.bluetooth.audio@2.1",
- "libprotobuf-cpp-lite",
- "libcrypto",
- "liblog",
- ],
- static_libs : [
- "crypto_toolbox_for_tests",
- "libgmock",
- "libbt-common",
- "libbt-protos-lite",
- "libosi",
- "liblc3codec",
- ],
- sanitize: {
- cfi: true,
- scs: true,
- address: true,
- all_undefined: true,
- integer_overflow: true,
- diag: {
- undefined : true
- },
- },
-}
-
diff --git a/bta/BUILD.gn b/bta/BUILD.gn
deleted file mode 100644
index 7fc7b92..0000000
--- a/bta/BUILD.gn
+++ /dev/null
@@ -1,161 +0,0 @@
-#
-# Copyright 2015 Google, Inc.
-#
-# 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.
-#
-
-static_library("bta") {
- sources = [
- "ag/bta_ag_act.cc",
- "ag/bta_ag_api.cc",
- "ag/bta_ag_at.cc",
- "ag/bta_ag_cfg.cc",
- "ag/bta_ag_cmd.cc",
- "ag/bta_ag_main.cc",
- "ag/bta_ag_rfc.cc",
- "ag/bta_ag_sco.cc",
- "ag/bta_ag_sdp.cc",
- "ar/bta_ar.cc",
- "av/bta_av_aact.cc",
- "av/bta_av_act.cc",
- "av/bta_av_api.cc",
- "av/bta_av_cfg.cc",
- "av/bta_av_ci.cc",
- "av/bta_av_main.cc",
- "av/bta_av_ssm.cc",
- "csis/csis_client.cc",
- "dm/bta_dm_act.cc",
- "dm/bta_dm_api.cc",
- "dm/bta_dm_cfg.cc",
- "dm/bta_dm_ci.cc",
- "dm/bta_dm_main.cc",
- "dm/bta_dm_pm.cc",
- "gatt/bta_gattc_act.cc",
- "gatt/bta_gattc_api.cc",
- "gatt/bta_gattc_cache.cc",
- "gatt/bta_gattc_main.cc",
- "gatt/bta_gattc_utils.cc",
- "gatt/bta_gattc_queue.cc",
- "gatt/bta_gatts_act.cc",
- "gatt/bta_gatts_api.cc",
- "gatt/bta_gatts_main.cc",
- "gatt/bta_gatts_utils.cc",
- "gatt/database.cc",
- "gatt/database_builder.cc",
- "groups/groups.cc",
- "hearing_aid/hearing_aid.cc",
- "hearing_aid/hearing_aid_audio_source.cc",
- "hf_client/bta_hf_client_act.cc",
- "hf_client/bta_hf_client_api.cc",
- "hf_client/bta_hf_client_at.cc",
- "hf_client/bta_hf_client_main.cc",
- "hf_client/bta_hf_client_rfc.cc",
- "hf_client/bta_hf_client_sdp.cc",
- "hf_client/bta_hf_client_sco.cc",
- "hh/bta_hh_act.cc",
- "hh/bta_hh_api.cc",
- "hh/bta_hh_cfg.cc",
- "hh/bta_hh_le.cc",
- "hh/bta_hh_main.cc",
- "hh/bta_hh_utils.cc",
- "hd/bta_hd_act.cc",
- "hd/bta_hd_api.cc",
- "hd/bta_hd_main.cc",
- "jv/bta_jv_act.cc",
- "jv/bta_jv_api.cc",
- "jv/bta_jv_cfg.cc",
- "le_audio/client_linux.cc",
- "le_audio/hal_verifier_linux.cc",
- "pan/bta_pan_act.cc",
- "pan/bta_pan_api.cc",
- "pan/bta_pan_ci.cc",
- "pan/bta_pan_main.cc",
- "sdp/bta_sdp.cc",
- "sdp/bta_sdp_act.cc",
- "sdp/bta_sdp_api.cc",
- "sdp/bta_sdp_cfg.cc",
- "sys/bta_sys_conn.cc",
- "sys/bta_sys_main.cc",
- "sys/utl.cc",
- "vc/device.cc",
- "vc/vc.cc",
- ]
-
- include_dirs = [
- "closure",
- "dm",
- "hh",
- "hd",
- "include",
- "sys",
- "//bt/",
- "//bt/linux_include",
- "//bt/bta",
- "//bt/internal_include",
- "//bt/btcore/include",
- "//bt/hci/include",
- "//bt/internal_include",
- "//bt/stack/include",
- "//bt/stack/btm",
- "//bt/udrv/include",
- "//bt/utils/include",
- "//bt/vnd/include",
- "//bt/btif/include",
- "//bt/btif/avrcp",
- "//bt/include/hardware/avrcp",
- "//bt/profile/avrcp",
- "//bt/packet/avrcp",
- "//bt/packet/base",
- ]
-
- configs += [
- "//bt:target_defaults"
- ]
-
- deps = [
- "//bt/gd/rust/shim:shim_bridge_header",
- "//bt/gd/rust/shim:init_flags_bridge_header",
- "//bt/gd/rust/shim:message_loop_thread_bridge_header",
- ]
-}
-
-if (use.test) {
- executable("net_test_bta") {
- sources = [
- "gatt/database_builder.cc",
- "test/gatt/database_builder_test.cc",
- "test/gatt/database_builder_sample_device_test.cc",
- "test/gatt/database_test.cc",
- ]
-
- include_dirs = [
- "include",
- "//bt/",
- "//bt/bta",
- "//bt/btcore/include",
- "//bt/hci/include",
- "//bt/internal_include",
- "//bt/stack/btm",
- ]
-
- deps = [
- "//bt/bta",
- "//bt/types",
- ]
-
- configs += [
- "//bt:external_gmock_main",
- "//bt:target_defaults",
- ]
- }
-}
diff --git a/bta/ag/bta_ag_act.cc b/bta/ag/bta_ag_act.cc
deleted file mode 100644
index adf08be..0000000
--- a/bta/ag/bta_ag_act.cc
+++ /dev/null
@@ -1,862 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains action functions for the audio gateway.
- *
- ******************************************************************************/
-
-#include <cstdint>
-#include <cstring>
-
-#include "bta/ag/bta_ag_int.h"
-#include "bta/include/bta_dm_api.h"
-#include "btif/include/btif_config.h"
-#include "osi/include/osi.h" // UNUSED_ATTR
-#include "stack/include/l2c_api.h"
-#include "stack/include/port_api.h"
-#include "types/raw_address.h"
-
-#include <base/logging.h>
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-
-/* maximum length of data to read from RFCOMM */
-#define BTA_AG_RFC_READ_MAX 512
-
-/* maximum AT command length */
-#define BTA_AG_CMD_MAX 512
-
-const uint16_t bta_ag_uuid[BTA_AG_NUM_IDX] = {
- UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, UUID_SERVCLASS_AG_HANDSFREE};
-
-const uint8_t bta_ag_sec_id[BTA_AG_NUM_IDX] = {BTM_SEC_SERVICE_HEADSET_AG,
- BTM_SEC_SERVICE_AG_HANDSFREE};
-
-const tBTA_SERVICE_ID bta_ag_svc_id[BTA_AG_NUM_IDX] = {BTA_HSP_SERVICE_ID,
- BTA_HFP_SERVICE_ID};
-
-const tBTA_SERVICE_MASK bta_ag_svc_mask[BTA_AG_NUM_IDX] = {
- BTA_HSP_SERVICE_MASK, BTA_HFP_SERVICE_MASK};
-
-typedef void (*tBTA_AG_ATCMD_CBACK)(tBTA_AG_SCB* p_scb, uint16_t cmd,
- uint8_t arg_type, char* p_arg, char* p_end,
- int16_t int_arg);
-
-const tBTA_AG_ATCMD_CBACK bta_ag_at_cback_tbl[BTA_AG_NUM_IDX] = {
- bta_ag_at_hsp_cback, bta_ag_at_hfp_cback};
-
-/*******************************************************************************
- *
- * Function bta_ag_cback_open
- *
- * Description Send open callback event to application.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_cback_open(tBTA_AG_SCB* p_scb, const RawAddress& bd_addr,
- tBTA_AG_STATUS status) {
- tBTA_AG_OPEN open = {};
-
- /* call app callback with open event */
- open.hdr.handle = bta_ag_scb_to_idx(p_scb);
- open.hdr.app_id = p_scb->app_id;
- open.status = status;
- open.service_id = bta_ag_svc_id[p_scb->conn_service];
- open.bd_addr = bd_addr;
-
- (*bta_ag_cb.p_cback)(BTA_AG_OPEN_EVT, (tBTA_AG*)&open);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_register
- *
- * Description This function initializes values of the AG cb and sets up
- * the SDP record for the services.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_register(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- /* initialize control block */
- p_scb->reg_services = data.api_register.services;
- p_scb->features = data.api_register.features;
- p_scb->masked_features = data.api_register.features;
- p_scb->app_id = data.api_register.app_id;
-
- /* create SDP records */
- bta_ag_create_records(p_scb, data);
-
- /* start RFCOMM servers */
- bta_ag_start_servers(p_scb, p_scb->reg_services);
-
- /* call app callback with register event */
- tBTA_AG_REGISTER reg = {};
- reg.hdr.handle = bta_ag_scb_to_idx(p_scb);
- reg.hdr.app_id = p_scb->app_id;
- reg.status = BTA_AG_SUCCESS;
- (*bta_ag_cb.p_cback)(BTA_AG_REGISTER_EVT, (tBTA_AG*)®);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_deregister
- *
- * Description This function removes the sdp records, closes the RFCOMM
- * servers, and deallocates the service control block.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_deregister(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- /* set dealloc */
- p_scb->dealloc = true;
-
- /* remove sdp records */
- bta_ag_del_records(p_scb);
-
- /* remove rfcomm servers */
- bta_ag_close_servers(p_scb, p_scb->reg_services);
-
- /* dealloc */
- bta_ag_scb_dealloc(p_scb);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_start_dereg
- *
- * Description Start a deregister event.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_start_dereg(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- /* set dealloc */
- p_scb->dealloc = true;
-
- /* remove sdp records */
- bta_ag_del_records(p_scb);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_start_open
- *
- * Description This starts an AG open.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_start_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- p_scb->peer_addr = data.api_open.bd_addr;
- p_scb->open_services = p_scb->reg_services;
-
- /* Check if RFCOMM has any incoming connection to avoid collision. */
- RawAddress pending_bd_addr = RawAddress::kEmpty;
- if (PORT_IsOpening(&pending_bd_addr)) {
- /* Let the incoming connection goes through. */
- /* Issue collision for this scb for now. */
- /* We will decide what to do when we find incoming connetion later. */
- bta_ag_collision_cback(BTA_SYS_CONN_OPEN, BTA_ID_AG, 0, p_scb->peer_addr);
- return;
- }
-
- /* close servers */
- bta_ag_close_servers(p_scb, p_scb->reg_services);
-
- /* set role */
- p_scb->role = BTA_AG_INT;
-
- /* do service search */
- bta_ag_do_disc(p_scb, p_scb->open_services);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_disc_int_res
- *
- * Description This function handles a discovery result when initiator.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_disc_int_res(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- uint16_t event = BTA_AG_DISC_FAIL_EVT;
-
- APPL_TRACE_DEBUG("bta_ag_disc_int_res: Status: %d", data.disc_result.status);
-
- /* if found service */
- if (data.disc_result.status == SDP_SUCCESS ||
- data.disc_result.status == SDP_DB_FULL) {
- /* get attributes */
- if (bta_ag_sdp_find_attr(p_scb, p_scb->open_services)) {
- /* set connected service */
- p_scb->conn_service = bta_ag_service_to_idx(p_scb->open_services);
-
- /* send ourselves sdp ok event */
- event = BTA_AG_DISC_OK_EVT;
- }
- }
-
- /* free discovery db */
- bta_ag_free_db(p_scb, data);
-
- /* if service not found check if we should search for other service */
- if ((event == BTA_AG_DISC_FAIL_EVT) &&
- (data.disc_result.status == SDP_SUCCESS ||
- data.disc_result.status == SDP_DB_FULL ||
- data.disc_result.status == SDP_NO_RECS_MATCH)) {
- if ((p_scb->open_services & BTA_HFP_SERVICE_MASK) &&
- (p_scb->open_services & BTA_HSP_SERVICE_MASK)) {
- /* search for HSP */
- p_scb->open_services &= ~BTA_HFP_SERVICE_MASK;
- bta_ag_do_disc(p_scb, p_scb->open_services);
- } else if ((p_scb->open_services & BTA_HSP_SERVICE_MASK) &&
- (p_scb->hsp_version == HSP_VERSION_1_2)) {
- /* search for UUID_SERVCLASS_HEADSET instead */
- p_scb->hsp_version = HSP_VERSION_1_0;
- bta_ag_do_disc(p_scb, p_scb->open_services);
- } else {
- /* send ourselves sdp ok/fail event */
- bta_ag_sm_execute(p_scb, event, data);
- }
- } else {
- /* send ourselves sdp ok/fail event */
- bta_ag_sm_execute(p_scb, event, data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_disc_acp_res
- *
- * Description This function handles a discovery result when acceptor.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_disc_acp_res(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- /* if found service */
- if (data.disc_result.status == SDP_SUCCESS ||
- data.disc_result.status == SDP_DB_FULL) {
- /* get attributes */
- bta_ag_sdp_find_attr(p_scb, bta_ag_svc_mask[p_scb->conn_service]);
- }
-
- /* free discovery db */
- bta_ag_free_db(p_scb, data);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_disc_fail
- *
- * Description This function handles a discovery failure.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_disc_fail(tBTA_AG_SCB* p_scb,
- UNUSED_ATTR const tBTA_AG_DATA& data) {
- /* reopen registered servers */
- bta_ag_start_servers(p_scb, p_scb->reg_services);
-
- /* reinitialize stuff */
-
- /* clear the remote BD address */
- RawAddress peer_addr = p_scb->peer_addr;
- p_scb->peer_addr = RawAddress::kEmpty;
-
- /* call open cback w. failure */
- bta_ag_cback_open(p_scb, peer_addr, BTA_AG_FAIL_SDP);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_open_fail
- *
- * Description open connection failed.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_open_fail(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- /* call open cback w. failure */
- bta_ag_cback_open(p_scb, data.api_open.bd_addr, BTA_AG_FAIL_RESOURCES);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_rfc_fail
- *
- * Description RFCOMM connection failed.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_rfc_fail(tBTA_AG_SCB* p_scb, UNUSED_ATTR const tBTA_AG_DATA& data) {
- RawAddress peer_addr = p_scb->peer_addr;
- /* reinitialize stuff */
- p_scb->conn_handle = 0;
- p_scb->conn_service = 0;
- p_scb->peer_features = 0;
- p_scb->peer_codecs = BTM_SCO_CODEC_CVSD;
- p_scb->sco_codec = BTM_SCO_CODEC_CVSD;
- p_scb->role = 0;
- p_scb->svc_conn = false;
- p_scb->hsp_version = HSP_VERSION_1_2;
- /*Clear the BD address*/
- p_scb->peer_addr = RawAddress::kEmpty;
-
- /* reopen registered servers */
- bta_ag_start_servers(p_scb, p_scb->reg_services);
-
- /* call open cback w. failure */
- bta_ag_cback_open(p_scb, peer_addr, BTA_AG_FAIL_RFCOMM);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_rfc_close
- *
- * Description RFCOMM connection closed.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_rfc_close(tBTA_AG_SCB* p_scb,
- UNUSED_ATTR const tBTA_AG_DATA& data) {
- tBTA_AG_CLOSE close = {};
- tBTA_SERVICE_MASK services;
- int i, num_active_conn = 0;
-
- /* reinitialize stuff */
- p_scb->conn_service = 0;
- p_scb->peer_features = 0;
- p_scb->masked_features = p_scb->features;
- p_scb->peer_codecs = BTM_SCO_CODEC_CVSD;
- p_scb->sco_codec = BTM_SCO_CODEC_CVSD;
- /* Clear these flags upon SLC teardown */
- p_scb->codec_updated = false;
- p_scb->codec_fallback = false;
- p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
- p_scb->role = 0;
- p_scb->post_sco = BTA_AG_POST_SCO_NONE;
- p_scb->svc_conn = false;
- p_scb->hsp_version = HSP_VERSION_1_2;
- bta_ag_at_reinit(&p_scb->at_cb);
-
- for (auto& peer_hf_indicator : p_scb->peer_hf_indicators) {
- peer_hf_indicator = {};
- }
- for (auto& local_hf_indicator : p_scb->local_hf_indicators) {
- local_hf_indicator = {};
- }
-
- /* stop timers */
- alarm_cancel(p_scb->ring_timer);
- alarm_cancel(p_scb->codec_negotiation_timer);
-
- close.hdr.handle = bta_ag_scb_to_idx(p_scb);
- close.hdr.app_id = p_scb->app_id;
- close.bd_addr = p_scb->peer_addr;
-
- bta_sys_conn_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
-
- if (bta_ag_get_active_device() == p_scb->peer_addr) {
- bta_clear_active_device();
- }
-
- /* call close cback */
- (*bta_ag_cb.p_cback)(BTA_AG_CLOSE_EVT, (tBTA_AG*)&close);
-
- /* if not deregistering (deallocating) reopen registered servers */
- if (!p_scb->dealloc) {
- /* Clear peer bd_addr so instance can be reused */
- p_scb->peer_addr = RawAddress::kEmpty;
-
- /* start only unopened server */
- services = p_scb->reg_services;
- for (i = 0; i < BTA_AG_NUM_IDX && services != 0; i++) {
- if (p_scb->serv_handle[i])
- services &= ~((tBTA_SERVICE_MASK)1 << (BTA_HSP_SERVICE_ID + i));
- }
- bta_ag_start_servers(p_scb, services);
-
- p_scb->conn_handle = 0;
-
- /* Make sure SCO state is BTA_AG_SCO_SHUTDOWN_ST */
- bta_ag_sco_shutdown(p_scb, tBTA_AG_DATA::kEmpty);
-
- /* Check if all the SLCs are down */
- for (i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++) {
- if (bta_ag_cb.scb[i].in_use && bta_ag_cb.scb[i].svc_conn)
- num_active_conn++;
- }
-
- if (!num_active_conn) {
- bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
- }
-
- }
- /* else close port and deallocate scb */
- else {
- RFCOMM_RemoveServer(p_scb->conn_handle);
- bta_ag_scb_dealloc(p_scb);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_rfc_open
- *
- * Description Handle RFCOMM channel open.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_rfc_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- /* initialize AT feature variables */
- p_scb->clip_enabled = false;
- p_scb->ccwa_enabled = false;
- p_scb->cmer_enabled = false;
- p_scb->cmee_enabled = false;
- p_scb->inband_enabled =
- ((p_scb->features & BTA_AG_FEAT_INBAND) == BTA_AG_FEAT_INBAND);
- if (p_scb->conn_service == BTA_AG_HFP) {
- size_t version_value_size = sizeof(p_scb->peer_version);
- if (!btif_config_get_bin(
- p_scb->peer_addr.ToString(), HFP_VERSION_CONFIG_KEY,
- (uint8_t*)&p_scb->peer_version, &version_value_size)) {
- APPL_TRACE_WARNING("%s: Failed read cached peer HFP version for %s",
- __func__, p_scb->peer_addr.ToString().c_str());
- p_scb->peer_version = HFP_HSP_VERSION_UNKNOWN;
- }
- size_t sdp_features_size = sizeof(p_scb->peer_sdp_features);
- if (btif_config_get_bin(
- p_scb->peer_addr.ToString(), HFP_SDP_FEATURES_CONFIG_KEY,
- (uint8_t*)&p_scb->peer_sdp_features, &sdp_features_size)) {
- bool sdp_wbs_support = p_scb->peer_sdp_features & BTA_AG_FEAT_WBS_SUPPORT;
- if (!p_scb->received_at_bac && sdp_wbs_support) {
- p_scb->codec_updated = true;
- p_scb->peer_codecs = BTM_SCO_CODEC_CVSD & BTM_SCO_CODEC_MSBC;
- p_scb->sco_codec = UUID_CODEC_MSBC;
- }
- } else {
- APPL_TRACE_WARNING("%s: Failed read cached peer HFP SDP features for %s",
- __func__, p_scb->peer_addr.ToString().c_str());
- }
- }
-
- /* set up AT command interpreter */
- p_scb->at_cb.p_at_tbl = bta_ag_at_tbl[p_scb->conn_service];
- p_scb->at_cb.p_cmd_cback = bta_ag_at_cback_tbl[p_scb->conn_service];
- p_scb->at_cb.p_err_cback = bta_ag_at_err_cback;
- p_scb->at_cb.p_user = p_scb;
- p_scb->at_cb.cmd_max_len = BTA_AG_CMD_MAX;
- bta_ag_at_init(&p_scb->at_cb);
-
- bta_sys_conn_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
-
- bta_ag_cback_open(p_scb, p_scb->peer_addr, BTA_AG_SUCCESS);
-
- if (p_scb->conn_service == BTA_AG_HFP) {
- /* if hfp start timer for service level conn */
- bta_sys_start_timer(p_scb->ring_timer, p_bta_ag_cfg->conn_tout,
- BTA_AG_SVC_TIMEOUT_EVT, bta_ag_scb_to_idx(p_scb));
- } else {
- /* else service level conn is open */
- bta_ag_svc_conn_open(p_scb, data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_rfc_acp_open
- *
- * Description Handle RFCOMM channel open when accepting connection.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_rfc_acp_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- APPL_TRACE_DEBUG("%s: serv_handle0 = %d serv_handle = %d", __func__,
- p_scb->serv_handle[0], p_scb->serv_handle[1]);
- /* set role */
- p_scb->role = BTA_AG_ACP;
-
- /* get bd addr of peer */
- uint16_t lcid = 0;
- RawAddress dev_addr = RawAddress::kEmpty;
- int status = PORT_CheckConnection(data.rfc.port_handle, &dev_addr, &lcid);
- if (status != PORT_SUCCESS) {
- LOG(ERROR) << __func__ << ", PORT_CheckConnection returned " << status;
- return;
- }
-
- /* Collision Handling */
- for (tBTA_AG_SCB& ag_scb : bta_ag_cb.scb) {
- // Cancel any pending collision timers
- if (ag_scb.in_use && alarm_is_scheduled(ag_scb.collision_timer)) {
- VLOG(1) << __func__ << ": cancel collision alarm for "
- << ag_scb.peer_addr;
- alarm_cancel(ag_scb.collision_timer);
- if (dev_addr != ag_scb.peer_addr && p_scb != &ag_scb) {
- // Resume outgoing connection if incoming is not on the same device
- bta_ag_resume_open(&ag_scb);
- }
- }
- if (dev_addr == ag_scb.peer_addr && p_scb != &ag_scb) {
- VLOG(1) << __func__ << ": fail outgoing connection before accepting "
- << ag_scb.peer_addr;
- // Fail the outgoing connection to clean up any upper layer states
- bta_ag_rfc_fail(&ag_scb, tBTA_AG_DATA::kEmpty);
- // If client port is opened, close it
- if (ag_scb.conn_handle > 0) {
- status = RFCOMM_RemoveConnection(ag_scb.conn_handle);
- if (status != PORT_SUCCESS) {
- LOG(WARNING) << __func__ << ": RFCOMM_RemoveConnection failed for "
- << dev_addr << ", handle "
- << std::to_string(ag_scb.conn_handle) << ", error "
- << status;
- }
- }
- }
- VLOG(1) << __func__ << ": dev_addr=" << dev_addr
- << ", peer_addr=" << ag_scb.peer_addr
- << ", in_use=" << ag_scb.in_use
- << ", index=" << bta_ag_scb_to_idx(p_scb);
- }
-
- p_scb->peer_addr = dev_addr;
-
- /* determine connected service from port handle */
- for (uint8_t i = 0; i < BTA_AG_NUM_IDX; i++) {
- APPL_TRACE_DEBUG(
- "bta_ag_rfc_acp_open: i = %d serv_handle = %d port_handle = %d", i,
- p_scb->serv_handle[i], data.rfc.port_handle);
-
- if (p_scb->serv_handle[i] == data.rfc.port_handle) {
- p_scb->conn_service = i;
- p_scb->conn_handle = data.rfc.port_handle;
- break;
- }
- }
-
- APPL_TRACE_DEBUG("bta_ag_rfc_acp_open: conn_service = %d conn_handle = %d",
- p_scb->conn_service, p_scb->conn_handle);
-
- /* close any unopened server */
- bta_ag_close_servers(
- p_scb, (p_scb->reg_services & ~bta_ag_svc_mask[p_scb->conn_service]));
-
- /* do service discovery to get features */
- bta_ag_do_disc(p_scb, bta_ag_svc_mask[p_scb->conn_service]);
-
- /* continue with common open processing */
- bta_ag_rfc_open(p_scb, data);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_rfc_data
- *
- * Description Read and process data from RFCOMM.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_rfc_data(tBTA_AG_SCB* p_scb, UNUSED_ATTR const tBTA_AG_DATA& data) {
- uint16_t len;
- char buf[BTA_AG_RFC_READ_MAX] = "";
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- /* do the following */
- for (;;) {
- /* read data from rfcomm; if bad status, we're done */
- if (PORT_ReadData(p_scb->conn_handle, buf, BTA_AG_RFC_READ_MAX, &len) !=
- PORT_SUCCESS) {
- LOG(ERROR) << __func__ << ": failed to read data " << p_scb->peer_addr;
- break;
- }
-
- /* if no data, we're done */
- if (len == 0) {
- LOG(WARNING) << __func__ << ": no data for " << p_scb->peer_addr;
- break;
- }
-
- /* run AT command interpreter on data */
- bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
- bta_ag_at_parse(&p_scb->at_cb, buf, len);
- if ((p_scb->sco_idx != BTM_INVALID_SCO_INDEX) &&
- bta_ag_sco_is_open(p_scb)) {
- APPL_TRACE_DEBUG("%s change link policy for SCO", __func__);
- bta_sys_sco_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
- } else {
- bta_sys_idle(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
- }
-
- /* no more data to read, we're done */
- if (len < BTA_AG_RFC_READ_MAX) {
- break;
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_start_close
- *
- * Description Start the process of closing SCO and RFCOMM connection.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_start_close(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- /* Take the link out of sniff and set L2C idle time to 0 */
- bta_dm_pm_active(p_scb->peer_addr);
- L2CA_SetIdleTimeoutByBdAddr(p_scb->peer_addr, 0, BT_TRANSPORT_BR_EDR);
-
- /* if SCO is open close SCO and wait on RFCOMM close */
- if (bta_ag_sco_is_open(p_scb)) {
- p_scb->post_sco = BTA_AG_POST_SCO_CLOSE_RFC;
- } else {
- p_scb->post_sco = BTA_AG_POST_SCO_NONE;
- bta_ag_rfc_do_close(p_scb, data);
- }
-
- /* always do SCO shutdown to handle all SCO corner cases */
- bta_ag_sco_shutdown(p_scb, data);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_post_sco_open
- *
- * Description Perform post-SCO open action, if any
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_post_sco_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- switch (p_scb->post_sco) {
- case BTA_AG_POST_SCO_RING:
- bta_ag_send_ring(p_scb, data);
- p_scb->post_sco = BTA_AG_POST_SCO_NONE;
- break;
-
- case BTA_AG_POST_SCO_CALL_CONN:
- bta_ag_send_call_inds(p_scb, BTA_AG_IN_CALL_CONN_RES);
- p_scb->post_sco = BTA_AG_POST_SCO_NONE;
- break;
-
- default:
- break;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_post_sco_close
- *
- * Description Perform post-SCO close action, if any
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_post_sco_close(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- switch (p_scb->post_sco) {
- case BTA_AG_POST_SCO_CLOSE_RFC:
- bta_ag_rfc_do_close(p_scb, data);
- p_scb->post_sco = BTA_AG_POST_SCO_NONE;
- break;
-
- case BTA_AG_POST_SCO_CALL_CONN:
- bta_ag_send_call_inds(p_scb, BTA_AG_IN_CALL_CONN_RES);
- p_scb->post_sco = BTA_AG_POST_SCO_NONE;
- break;
-
- case BTA_AG_POST_SCO_CALL_ORIG:
- bta_ag_send_call_inds(p_scb, BTA_AG_OUT_CALL_ORIG_RES);
- p_scb->post_sco = BTA_AG_POST_SCO_NONE;
- break;
-
- case BTA_AG_POST_SCO_CALL_END:
- bta_ag_send_call_inds(p_scb, BTA_AG_END_CALL_RES);
- p_scb->post_sco = BTA_AG_POST_SCO_NONE;
- break;
-
- case BTA_AG_POST_SCO_CALL_END_INCALL:
- bta_ag_send_call_inds(p_scb, BTA_AG_END_CALL_RES);
-
- /* Sending callsetup IND and Ring were defered to after SCO close. */
- bta_ag_send_call_inds(p_scb, BTA_AG_IN_CALL_RES);
-
- if (bta_ag_inband_enabled(p_scb) &&
- !(p_scb->features & BTA_AG_FEAT_NOSCO)) {
- p_scb->post_sco = BTA_AG_POST_SCO_RING;
- bta_ag_sco_open(p_scb, data);
- } else {
- p_scb->post_sco = BTA_AG_POST_SCO_NONE;
- bta_ag_send_ring(p_scb, data);
- }
- break;
-
- default:
- break;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_svc_conn_open
- *
- * Description Service level connection opened
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_svc_conn_open(tBTA_AG_SCB* p_scb,
- UNUSED_ATTR const tBTA_AG_DATA& data) {
- tBTA_AG_CONN evt = {};
-
- if (!p_scb->svc_conn) {
- /* set state variable */
- p_scb->svc_conn = true;
-
- /* Clear AT+BIA mask from previous SLC if any. */
- p_scb->bia_masked_out = 0;
-
- alarm_cancel(p_scb->ring_timer);
-
- /* call callback */
- evt.hdr.handle = bta_ag_scb_to_idx(p_scb);
- evt.hdr.app_id = p_scb->app_id;
- evt.peer_feat = p_scb->peer_features;
- evt.bd_addr = p_scb->peer_addr;
- evt.peer_codec = p_scb->peer_codecs;
-
- if ((p_scb->call_ind != BTA_AG_CALL_INACTIVE) ||
- (p_scb->callsetup_ind != BTA_AG_CALLSETUP_NONE)) {
- bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
- }
- if (bta_ag_get_active_device().IsEmpty()) {
- bta_ag_api_set_active_device(p_scb->peer_addr);
- }
- (*bta_ag_cb.p_cback)(BTA_AG_CONN_EVT, (tBTA_AG*)&evt);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_setcodec
- *
- * Description Handle API SetCodec
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_setcodec(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- tBTA_AG_PEER_CODEC codec_type = data.api_setcodec.codec;
- tBTA_AG_VAL val = {};
- val.hdr.handle = bta_ag_scb_to_idx(p_scb);
-
- /* Check if the requested codec type is valid */
- if ((codec_type != BTM_SCO_CODEC_NONE) &&
- (codec_type != BTM_SCO_CODEC_CVSD) &&
- (codec_type != BTM_SCO_CODEC_MSBC)) {
- val.num = codec_type;
- val.hdr.status = BTA_AG_FAIL_RESOURCES;
- APPL_TRACE_ERROR("bta_ag_setcodec error: unsupported codec type %d",
- codec_type);
- (*bta_ag_cb.p_cback)(BTA_AG_WBS_EVT, (tBTA_AG*)&val);
- return;
- }
-
- if ((p_scb->peer_codecs & codec_type) || (codec_type == BTM_SCO_CODEC_NONE) ||
- (codec_type == BTM_SCO_CODEC_CVSD)) {
- p_scb->sco_codec = codec_type;
- p_scb->codec_updated = true;
- val.num = codec_type;
- val.hdr.status = BTA_AG_SUCCESS;
- APPL_TRACE_DEBUG("bta_ag_setcodec: Updated codec type %d", codec_type);
- } else {
- val.num = codec_type;
- val.hdr.status = BTA_AG_FAIL_RESOURCES;
- APPL_TRACE_ERROR("bta_ag_setcodec error: unsupported codec type %d",
- codec_type);
- }
-
- (*bta_ag_cb.p_cback)(BTA_AG_WBS_EVT, (tBTA_AG*)&val);
-}
-
-static void bta_ag_collision_timer_cback(void* data) {
- if (data == nullptr) {
- LOG(ERROR) << __func__ << ": data should never be null in a timer callback";
- return;
- }
- /* If the peer haven't opened AG connection */
- /* we will restart opening process. */
- bta_ag_resume_open(static_cast<tBTA_AG_SCB*>(data));
-}
-
-void bta_ag_handle_collision(tBTA_AG_SCB* p_scb,
- UNUSED_ATTR const tBTA_AG_DATA& data) {
- /* Cancel SDP if it had been started. */
- if (p_scb->p_disc_db) {
- SDP_CancelServiceSearch(p_scb->p_disc_db);
- bta_ag_free_db(p_scb, tBTA_AG_DATA::kEmpty);
- }
-
- /* reopen registered servers */
- /* Collision may be detected before or after we close servers. */
- if (bta_ag_is_server_closed(p_scb)) {
- bta_ag_start_servers(p_scb, p_scb->reg_services);
- }
-
- /* Start timer to han */
- alarm_set_on_mloop(p_scb->collision_timer, BTA_AG_COLLISION_TIMEOUT_MS,
- bta_ag_collision_timer_cback, p_scb);
-}
diff --git a/bta/ag/bta_ag_api.cc b/bta/ag/bta_ag_api.cc
deleted file mode 100644
index 34479cb..0000000
--- a/bta/ag/bta_ag_api.cc
+++ /dev/null
@@ -1,235 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the implementation of the API for the audio gateway (AG)
- * subsystem of BTA, Broadcom's Bluetooth application layer for mobile
- * phones.
- *
- ******************************************************************************/
-
-#include "bta/include/bta_ag_api.h"
-
-#include <base/bind.h>
-#include <base/location.h>
-
-#include <cstdint>
-#include <cstring>
-#include <vector>
-
-#include "bta/ag/bta_ag_int.h"
-#include "stack/include/btu.h" // do_in_main_thread
-#include "types/raw_address.h"
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-
-static const tBTA_SYS_REG bta_ag_reg = {bta_ag_hdl_event, BTA_AgDisable};
-const tBTA_AG_RES_DATA tBTA_AG_RES_DATA::kEmpty = {};
-
-/*******************************************************************************
- *
- * Function BTA_AgEnable
- *
- * Description Enable the audio gateway service. When the enable
- * operation is complete the callback function will be
- * called with a BTA_AG_ENABLE_EVT. This function must
- * be called before other function in the AG API are
- * called.
- *
- * Returns BTA_SUCCESS if OK, BTA_FAILURE otherwise.
- *
- ******************************************************************************/
-tBTA_STATUS BTA_AgEnable(tBTA_AG_CBACK* p_cback) {
- /* Error if AG is already enabled, or AG is in the middle of disabling. */
- for (const tBTA_AG_SCB& scb : bta_ag_cb.scb) {
- if (scb.in_use) {
- APPL_TRACE_ERROR("BTA_AgEnable: FAILED, AG already enabled.");
- return BTA_FAILURE;
- }
- }
- bta_sys_register(BTA_ID_AG, &bta_ag_reg);
- do_in_main_thread(FROM_HERE, base::Bind(&bta_ag_api_enable, p_cback));
- return BTA_SUCCESS;
-}
-
-/*******************************************************************************
- *
- * Function BTA_AgDisable
- *
- * Description Disable the audio gateway service
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AgDisable() {
- do_in_main_thread(FROM_HERE, base::Bind(&bta_ag_api_disable));
-}
-
-/*******************************************************************************
- *
- * Function BTA_AgRegister
- *
- * Description Register an Audio Gateway service.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AgRegister(tBTA_SERVICE_MASK services, tBTA_AG_FEAT features,
- const std::vector<std::string>& service_names,
- uint8_t app_id) {
- do_in_main_thread(FROM_HERE, base::Bind(&bta_ag_api_register, services,
- features, service_names, app_id));
-}
-
-/*******************************************************************************
- *
- * Function BTA_AgDeregister
- *
- * Description Deregister an audio gateway service.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AgDeregister(uint16_t handle) {
- do_in_main_thread(
- FROM_HERE, base::Bind(&bta_ag_sm_execute_by_handle, handle,
- BTA_AG_API_DEREGISTER_EVT, tBTA_AG_DATA::kEmpty));
-}
-
-/*******************************************************************************
- *
- * Function BTA_AgOpen
- *
- * Description Opens a connection to a headset or hands-free device.
- * When connection is open callback function is called
- * with a BTA_AG_OPEN_EVT. Only the data connection is
- * opened. The audio connection is not opened.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AgOpen(uint16_t handle, const RawAddress& bd_addr) {
- tBTA_AG_DATA data = {};
- data.api_open.bd_addr = bd_addr;
- do_in_main_thread(FROM_HERE, base::Bind(&bta_ag_sm_execute_by_handle, handle,
- BTA_AG_API_OPEN_EVT, data));
-}
-
-/*******************************************************************************
- *
- * Function BTA_AgClose
- *
- * Description Close the current connection to a headset or a handsfree
- * Any current audio connection will also be closed.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AgClose(uint16_t handle) {
- do_in_main_thread(FROM_HERE,
- base::Bind(&bta_ag_sm_execute_by_handle, handle,
- BTA_AG_API_CLOSE_EVT, tBTA_AG_DATA::kEmpty));
-}
-
-/*******************************************************************************
- *
- * Function BTA_AgAudioOpen
- *
- * Description Opens an audio connection to the currently connected
- * headset or hnadsfree.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AgAudioOpen(uint16_t handle) {
- do_in_main_thread(
- FROM_HERE, base::Bind(&bta_ag_sm_execute_by_handle, handle,
- BTA_AG_API_AUDIO_OPEN_EVT, tBTA_AG_DATA::kEmpty));
-}
-
-/*******************************************************************************
- *
- * Function BTA_AgAudioClose
- *
- * Description Close the currently active audio connection to a headset
- * or hnadsfree. The data connection remains open
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AgAudioClose(uint16_t handle) {
- do_in_main_thread(
- FROM_HERE, base::Bind(&bta_ag_sm_execute_by_handle, handle,
- BTA_AG_API_AUDIO_CLOSE_EVT, tBTA_AG_DATA::kEmpty));
-}
-
-/*******************************************************************************
- *
- * Function BTA_AgResult
- *
- * Description Send an AT result code to a headset or hands-free device.
- * This function is only used when the AG parse mode is set
- * to BTA_AG_PARSE.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AgResult(uint16_t handle, tBTA_AG_RES result,
- const tBTA_AG_RES_DATA& data) {
- do_in_main_thread(FROM_HERE,
- base::Bind(&bta_ag_api_result, handle, result, data));
-}
-
-/*******************************************************************************
- *
- * Function BTA_AgSetCodec
- *
- * Description Specify the codec type to be used for the subsequent
- * audio connection.
- *
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AgSetCodec(uint16_t handle, tBTA_AG_PEER_CODEC codec) {
- tBTA_AG_DATA data = {};
- data.api_setcodec.codec = codec;
- do_in_main_thread(FROM_HERE, base::Bind(&bta_ag_sm_execute_by_handle, handle,
- BTA_AG_API_SETCODEC_EVT, data));
-}
-
-void BTA_AgSetScoAllowed(bool value) {
- do_in_main_thread(FROM_HERE, base::Bind(&bta_ag_set_sco_allowed, value));
-}
-
-void BTA_AgSetActiveDevice(const RawAddress& active_device_addr) {
- do_in_main_thread(
- FROM_HERE, base::Bind(&bta_ag_api_set_active_device, active_device_addr));
-}
diff --git a/bta/ag/bta_ag_at.cc b/bta/ag/bta_ag_at.cc
deleted file mode 100644
index 613a64b..0000000
--- a/bta/ag/bta_ag_at.cc
+++ /dev/null
@@ -1,224 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2004-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * BTA AG AT command interpreter.
- *
- ******************************************************************************/
-#define LOG_TAG "bta_ag_at"
-
-#include <cstdint>
-
-#include "bt_target.h" // Must be first to define build configuration:
-
-#include "bta/ag/bta_ag_at.h"
-#include "bta/ag/bta_ag_int.h"
-#include "bta/include/utl.h"
-#include "osi/include/allocator.h"
-#include "osi/include/log.h"
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-
-/******************************************************************************
- *
- * Function bta_ag_at_init
- *
- * Description Initialize the AT command parser control block.
- *
- *
- * Returns void
- *
- *****************************************************************************/
-void bta_ag_at_init(tBTA_AG_AT_CB* p_cb) {
- p_cb->p_cmd_buf = nullptr;
- p_cb->cmd_pos = 0;
-}
-
-/******************************************************************************
- *
- * Function bta_ag_at_reinit
- *
- * Description Re-initialize the AT command parser control block. This
- * function resets the AT command parser state and frees
- * any GKI buffer.
- *
- *
- * Returns void
- *
- *****************************************************************************/
-void bta_ag_at_reinit(tBTA_AG_AT_CB* p_cb) {
- osi_free_and_reset((void**)&p_cb->p_cmd_buf);
- p_cb->cmd_pos = 0;
-}
-
-/******************************************************************************
- *
- * Function bta_ag_process_at
- *
- * Description Parse AT commands. This function will take the input
- * character string and parse it for AT commands according to
- * the AT command table passed in the control block.
- *
- *
- * Returns void
- *
- *****************************************************************************/
-void bta_ag_process_at(tBTA_AG_AT_CB* p_cb, char* p_end) {
- uint16_t idx;
- uint8_t arg_type;
- char* p_arg;
- int16_t int_arg = 0;
- /* loop through at command table looking for match */
- for (idx = 0; p_cb->p_at_tbl[idx].p_cmd[0] != 0; idx++) {
- if (!utl_strucmp(p_cb->p_at_tbl[idx].p_cmd, p_cb->p_cmd_buf)) {
- break;
- }
- }
-
- /* if there is a match; verify argument type */
- if (p_cb->p_at_tbl[idx].p_cmd[0] != 0) {
- /* start of argument is p + strlen matching command */
- p_arg = p_cb->p_cmd_buf + strlen(p_cb->p_at_tbl[idx].p_cmd);
- if (p_arg > p_end) {
- (*p_cb->p_err_cback)((tBTA_AG_SCB*)p_cb->p_user, false, nullptr);
- android_errorWriteLog(0x534e4554, "112860487");
- return;
- }
-
- /* if no argument */
- if (p_arg[0] == 0) {
- arg_type = BTA_AG_AT_NONE;
- }
- /* else if arg is '?' and it is last character */
- else if (p_arg[0] == '?' && p_arg[1] == 0) {
- /* we have a read */
- arg_type = BTA_AG_AT_READ;
- }
- /* else if arg is '=' */
- else if (p_arg[0] == '=' && p_arg[1] != 0) {
- if (p_arg[1] == '?' && p_arg[2] == 0) {
- /* we have a test */
- arg_type = BTA_AG_AT_TEST;
- } else {
- /* we have a set */
- arg_type = BTA_AG_AT_SET;
-
- /* skip past '=' */
- p_arg++;
- }
- } else
- /* else it is freeform argument */
- {
- arg_type = BTA_AG_AT_FREE;
- }
-
- /* if arguments match command capabilities */
- if ((arg_type & p_cb->p_at_tbl[idx].arg_type) != 0) {
- /* if it's a set integer check max, min range */
- if (arg_type == BTA_AG_AT_SET &&
- p_cb->p_at_tbl[idx].fmt == BTA_AG_AT_INT) {
- int_arg = utl_str2int(p_arg);
- if (int_arg < (int16_t)p_cb->p_at_tbl[idx].min ||
- int_arg > (int16_t)p_cb->p_at_tbl[idx].max) {
- /* arg out of range; error */
- LOG_WARN("arg out of range");
- (*p_cb->p_err_cback)((tBTA_AG_SCB*)p_cb->p_user, false, nullptr);
- } else {
- (*p_cb->p_cmd_cback)((tBTA_AG_SCB*)p_cb->p_user,
- p_cb->p_at_tbl[idx].command_id, arg_type, p_arg,
- p_end, int_arg);
- }
- } else {
- (*p_cb->p_cmd_cback)((tBTA_AG_SCB*)p_cb->p_user,
- p_cb->p_at_tbl[idx].command_id, arg_type, p_arg,
- p_end, int_arg);
- }
- } else {
- /* else error */
- LOG_WARN("Incoming arg type 0x%x does not match cmd arg type 0x%x",
- arg_type, p_cb->p_at_tbl[idx].arg_type);
- (*p_cb->p_err_cback)((tBTA_AG_SCB*)p_cb->p_user, false, nullptr);
- }
- } else {
- /* else no match call error callback */
- LOG_WARN("Unmatched command index %d", idx);
- (*p_cb->p_err_cback)((tBTA_AG_SCB*)p_cb->p_user, true, p_cb->p_cmd_buf);
- }
-}
-
-/******************************************************************************
- *
- * Function bta_ag_at_parse
- *
- * Description Parse AT commands. This function will take the input
- * character string and parse it for AT commands according to
- * the AT command table passed in the control block.
- *
- *
- * Returns void
- *
- *****************************************************************************/
-void bta_ag_at_parse(tBTA_AG_AT_CB* p_cb, char* p_buf, uint16_t len) {
- int i = 0;
- char* p_save;
-
- if (p_cb->p_cmd_buf == nullptr) {
- p_cb->p_cmd_buf = (char*)osi_malloc(p_cb->cmd_max_len);
- p_cb->cmd_pos = 0;
- }
-
- for (i = 0; i < len;) {
- while (p_cb->cmd_pos < p_cb->cmd_max_len - 1 && i < len) {
- /* Skip null characters between AT commands. */
- if ((p_cb->cmd_pos == 0) && (p_buf[i] == 0)) {
- i++;
- continue;
- }
-
- p_cb->p_cmd_buf[p_cb->cmd_pos] = p_buf[i++];
- if (p_cb->p_cmd_buf[p_cb->cmd_pos] == '\r' ||
- p_cb->p_cmd_buf[p_cb->cmd_pos] == '\n') {
- p_cb->p_cmd_buf[p_cb->cmd_pos] = 0;
- if ((p_cb->cmd_pos > 2) &&
- (p_cb->p_cmd_buf[0] == 'A' || p_cb->p_cmd_buf[0] == 'a') &&
- (p_cb->p_cmd_buf[1] == 'T' || p_cb->p_cmd_buf[1] == 't')) {
- p_save = p_cb->p_cmd_buf;
- char* p_end = p_cb->p_cmd_buf + p_cb->cmd_pos;
- p_cb->p_cmd_buf += 2;
- bta_ag_process_at(p_cb, p_end);
- p_cb->p_cmd_buf = p_save;
- }
-
- p_cb->cmd_pos = 0;
-
- } else if (p_cb->p_cmd_buf[p_cb->cmd_pos] == 0x1A ||
- p_cb->p_cmd_buf[p_cb->cmd_pos] == 0x1B) {
- p_cb->p_cmd_buf[++p_cb->cmd_pos] = 0;
- (*p_cb->p_err_cback)((tBTA_AG_SCB*)p_cb->p_user, true, p_cb->p_cmd_buf);
- p_cb->cmd_pos = 0;
- } else {
- ++p_cb->cmd_pos;
- }
- }
-
- if (i < len) p_cb->cmd_pos = 0;
- }
-}
diff --git a/bta/ag/bta_ag_at.h b/bta/ag/bta_ag_at.h
deleted file mode 100644
index e324e19..0000000
--- a/bta/ag/bta_ag_at.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2004-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Interface file for BTA AG AT command interpreter.
- *
- ******************************************************************************/
-#ifndef BTA_AG_AT_H
-#define BTA_AG_AT_H
-
-#include <stddef.h>
-#include <cstddef>
-#include <cstdint>
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-
-/* AT command argument capabilities */
-#define BTA_AG_AT_NONE 0x01 /* no argument */
-#define BTA_AG_AT_SET 0x02 /* set value */
-#define BTA_AG_AT_READ 0x04 /* read value */
-#define BTA_AG_AT_TEST 0x08 /* test value range */
-#define BTA_AG_AT_FREE 0x10 /* freeform argument */
-
-/* AT command argument format */
-#define BTA_AG_AT_STR 0 /* string */
-#define BTA_AG_AT_INT 1 /* integer */
-
-/*****************************************************************************
- * Data types
- ****************************************************************************/
-
-/* AT command table element */
-typedef struct {
- const char* p_cmd; /* AT command string */
- size_t command_id; /* passed to the callback on p_cmd match */
- uint8_t arg_type; /* allowable argument type syntax */
- uint8_t fmt; /* whether arg is int or string */
- uint8_t min; /* minimum value for int arg */
- int16_t max; /* maximum value for int arg */
-} tBTA_AG_AT_CMD;
-
-/* callback function executed when command is parsed */
-struct tBTA_AG_SCB;
-typedef void(tBTA_AG_AT_CMD_CBACK)(tBTA_AG_SCB* p_user, uint16_t command_id,
- uint8_t arg_type, char* p_arg, char* p_end,
- int16_t int_arg);
-
-/* callback function executed to send "ERROR" result code */
-typedef void(tBTA_AG_AT_ERR_CBACK)(tBTA_AG_SCB* p_user, bool unknown,
- const char* p_arg);
-
-/* AT command parsing control block */
-typedef struct {
- const tBTA_AG_AT_CMD* p_at_tbl; /* AT command table */
- tBTA_AG_AT_CMD_CBACK* p_cmd_cback; /* command callback */
- tBTA_AG_AT_ERR_CBACK* p_err_cback; /* error callback */
- void* p_user; /* user-defined data */
- char* p_cmd_buf; /* temp parsing buffer */
- uint16_t cmd_pos; /* position in temp buffer */
- uint16_t cmd_max_len; /* length of temp buffer to allocate */
- uint8_t state; /* parsing state */
-} tBTA_AG_AT_CB;
-
-/*****************************************************************************
- * Function prototypes
- ****************************************************************************/
-
-/*****************************************************************************
- *
- * Function bta_ag_at_init
- *
- * Description Initialize the AT command parser control block.
- *
- *
- * Returns void
- *
- ****************************************************************************/
-extern void bta_ag_at_init(tBTA_AG_AT_CB* p_cb);
-
-/*****************************************************************************
- *
- * Function bta_ag_at_reinit
- *
- * Description Re-initialize the AT command parser control block. This
- * function resets the AT command parser state and frees
- * any GKI buffer.
- *
- *
- * Returns void
- *
- ****************************************************************************/
-extern void bta_ag_at_reinit(tBTA_AG_AT_CB* p_cb);
-
-/*****************************************************************************
- *
- * Function bta_ag_at_parse
- *
- * Description Parse AT commands. This function will take the input
- * character string and parse it for AT commands according to
- * the AT command table passed in the control block.
- *
- *
- * Returns void
- *
- ****************************************************************************/
-extern void bta_ag_at_parse(tBTA_AG_AT_CB* p_cb, char* p_buf, uint16_t len);
-
-#endif /* BTA_AG_AT_H */
diff --git a/bta/ag/bta_ag_cfg.cc b/bta/ag/bta_ag_cfg.cc
deleted file mode 100644
index c331973..0000000
--- a/bta/ag/bta_ag_cfg.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains compile-time configurable constants for the audio
- * gateway.
- *
- ******************************************************************************/
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bta/ag/bta_ag_int.h"
-#include "bta/include/bta_ag_api.h"
-#include "device/include/esco_parameters.h"
-#include "osi/include/allocator.h"
-#include "osi/include/compat.h"
-#include "stack/include/bt_types.h"
-
-#ifndef BTA_AG_CIND_INFO
-#define BTA_AG_CIND_INFO \
- "(\"call\",(0,1)),(\"callsetup\",(0-3)),(\"service\",(0-3)),(\"signal\",(0-" \
- "6)),(\"roam\",(0,1)),(\"battchg\",(0-5)),(\"callheld\",(0-2)),(\"bearer\"," \
- "(0-7))"
-#endif
-
-#ifndef BTA_AG_CHLD_VAL_ECC
-#define BTA_AG_CHLD_VAL_ECC "(0,1,1x,2,2x,3,4)"
-#endif
-
-#ifndef BTA_AG_CHLD_VAL
-#define BTA_AG_CHLD_VAL "(0,1,2,3,4)"
-#endif
-
-#ifndef BTA_AG_CONN_TIMEOUT
-#define BTA_AG_CONN_TIMEOUT 5000
-#endif
-
-#ifndef BTA_AG_SCO_PKT_TYPES
-/* S1 packet type setting from HFP 1.5 spec */
-#define BTA_AG_SCO_PKT_TYPES /* BTM_SCO_LINK_ALL_PKT_MASK */ \
- (BTM_SCO_LINK_ONLY_MASK | ESCO_PKT_TYPES_MASK_EV3 | \
- ESCO_PKT_TYPES_MASK_NO_3_EV3 | ESCO_PKT_TYPES_MASK_NO_2_EV5 | \
- ESCO_PKT_TYPES_MASK_NO_3_EV5)
-#endif
-
-#ifndef BTA_AG_BIND_INFO
-#define BTA_AG_BIND_INFO "(1)"
-#endif
-
-const tBTA_AG_HF_IND bta_ag_local_hf_ind_cfg[] = {
- /* The first row contains the number of indicators. Need to be updated
- accordingly */
- {BTA_AG_NUM_LOCAL_HF_IND, false, false, 0, 0},
-
- {1, true, true, 0,
- 1}, /* Enhanced Driver Status, supported, enabled, range 0 ~ 1 */
- {2, true, true, 0,
- 100} /* Battery Level Status, supported, enabled, range 0 ~ 100 */
-};
-
-const tBTA_AG_CFG bta_ag_cfg = {BTA_AG_CIND_INFO, BTA_AG_BIND_INFO,
- BTA_AG_NUM_LOCAL_HF_IND, BTA_AG_CONN_TIMEOUT,
- BTA_AG_SCO_PKT_TYPES, BTA_AG_CHLD_VAL_ECC,
- BTA_AG_CHLD_VAL};
-
-const tBTA_AG_CFG* p_bta_ag_cfg = &bta_ag_cfg;
diff --git a/bta/ag/bta_ag_cmd.cc b/bta/ag/bta_ag_cmd.cc
deleted file mode 100644
index 7d06226..0000000
--- a/bta/ag/bta_ag_cmd.cc
+++ /dev/null
@@ -1,1824 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2004-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-#define LOG_TAG "bta_ag_cmd"
-
-#include <cstdint>
-#include <cstring>
-
-#include "bta/ag/bta_ag_at.h"
-#include "bta/ag/bta_ag_int.h"
-#include "bta/include/bta_ag_api.h"
-#include "bta/include/utl.h"
-#include "device/include/interop.h"
-#include "osi/include/compat.h"
-#include "osi/include/log.h"
-#include "osi/include/osi.h" // UNUSED_ATTR
-#include "stack/include/port_api.h"
-
-#include <base/logging.h>
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-
-/* Ring timeout */
-#define BTA_AG_RING_TIMEOUT_MS (5 * 1000) /* 5 seconds */
-
-#define BTA_AG_CMD_MAX_VAL 32767 /* Maximum value is signed 16-bit value */
-
-/* Invalid Chld command */
-#define BTA_AG_INVALID_CHLD 255
-
-#define COLON_IDX_4_VGSVGM 4
-
-/* Local events which will not trigger a higher layer callback */
-enum {
- BTA_AG_LOCAL_EVT_FIRST = 0x100,
- BTA_AG_LOCAL_EVT_CCWA,
- BTA_AG_LOCAL_EVT_CLIP,
- BTA_AG_LOCAL_EVT_CMER,
- BTA_AG_LOCAL_EVT_BRSF,
- BTA_AG_LOCAL_EVT_CMEE,
- BTA_AG_LOCAL_EVT_BCC,
-};
-
-/* AT command interpreter table for HSP */
-static const tBTA_AG_AT_CMD bta_ag_hsp_cmd[] = {
- {"+CKPD", BTA_AG_AT_CKPD_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 200, 200},
- {"+VGS", BTA_AG_SPK_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 15},
- {"+VGM", BTA_AG_MIC_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 15},
- /* End-of-table marker used to stop lookup iteration */
- {"", 0, 0, 0, 0, 0}};
-
-/* AT command interpreter table for HFP */
-static const tBTA_AG_AT_CMD bta_ag_hfp_cmd[] = {
- {"A", BTA_AG_AT_A_EVT, BTA_AG_AT_NONE, BTA_AG_AT_STR, 0, 0},
- {"D", BTA_AG_AT_D_EVT, BTA_AG_AT_NONE | BTA_AG_AT_FREE, BTA_AG_AT_STR, 0,
- 0},
- {"+VGS", BTA_AG_SPK_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 15},
- {"+VGM", BTA_AG_MIC_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 15},
- {"+CCWA", BTA_AG_LOCAL_EVT_CCWA, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 1},
- /* Consider CHLD as str to take care of indexes for ECC */
- {"+CHLD", BTA_AG_AT_CHLD_EVT, BTA_AG_AT_SET | BTA_AG_AT_TEST, BTA_AG_AT_STR,
- 0, 4},
- {"+CHUP", BTA_AG_AT_CHUP_EVT, BTA_AG_AT_NONE, BTA_AG_AT_STR, 0, 0},
- {"+CIND", BTA_AG_AT_CIND_EVT, BTA_AG_AT_READ | BTA_AG_AT_TEST,
- BTA_AG_AT_STR, 0, 0},
- {"+CLIP", BTA_AG_LOCAL_EVT_CLIP, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 1},
- {"+CMER", BTA_AG_LOCAL_EVT_CMER, BTA_AG_AT_SET, BTA_AG_AT_STR, 0, 0},
- {"+VTS", BTA_AG_AT_VTS_EVT, BTA_AG_AT_SET, BTA_AG_AT_STR, 0, 0},
- {"+BINP", BTA_AG_AT_BINP_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 1, 1},
- {"+BLDN", BTA_AG_AT_BLDN_EVT, BTA_AG_AT_NONE, BTA_AG_AT_STR, 0, 0},
- {"+BVRA", BTA_AG_AT_BVRA_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 1},
- {"+BRSF", BTA_AG_LOCAL_EVT_BRSF, BTA_AG_AT_SET, BTA_AG_AT_INT, 0,
- BTA_AG_CMD_MAX_VAL},
- {"+NREC", BTA_AG_AT_NREC_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 0},
- {"+CNUM", BTA_AG_AT_CNUM_EVT, BTA_AG_AT_NONE, BTA_AG_AT_STR, 0, 0},
- {"+BTRH", BTA_AG_AT_BTRH_EVT, BTA_AG_AT_READ | BTA_AG_AT_SET, BTA_AG_AT_INT,
- 0, 2},
- {"+CLCC", BTA_AG_AT_CLCC_EVT, BTA_AG_AT_NONE, BTA_AG_AT_STR, 0, 0},
- {"+COPS", BTA_AG_AT_COPS_EVT, BTA_AG_AT_READ | BTA_AG_AT_SET, BTA_AG_AT_STR,
- 0, 0},
- {"+CMEE", BTA_AG_LOCAL_EVT_CMEE, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 1},
- {"+BIA", BTA_AG_AT_BIA_EVT, BTA_AG_AT_SET, BTA_AG_AT_STR, 0, 20},
- {"+CBC", BTA_AG_AT_CBC_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 100},
- {"+BCC", BTA_AG_LOCAL_EVT_BCC, BTA_AG_AT_NONE, BTA_AG_AT_STR, 0, 0},
- {"+BCS", BTA_AG_AT_BCS_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0,
- BTA_AG_CMD_MAX_VAL},
- {"+BIND", BTA_AG_AT_BIND_EVT,
- BTA_AG_AT_SET | BTA_AG_AT_READ | BTA_AG_AT_TEST, BTA_AG_AT_STR, 0, 0},
- {"+BIEV", BTA_AG_AT_BIEV_EVT, BTA_AG_AT_SET, BTA_AG_AT_STR, 0, 0},
- {"+BAC", BTA_AG_AT_BAC_EVT, BTA_AG_AT_SET, BTA_AG_AT_STR, 0, 0},
- /* End-of-table marker used to stop lookup iteration */
- {"", 0, 0, 0, 0, 0}};
-
-/* AT result code table element */
-typedef struct {
- const char* result_string; /* AT result string */
- size_t result_id; /* Local or BTA result id */
- uint8_t arg_type; /* whether argument is int or string */
-} tBTA_AG_RESULT;
-
-/* AT result code argument types */
-enum {
- BTA_AG_RES_FMT_NONE, /* no argument */
- BTA_AG_RES_FMT_INT, /* integer argument */
- BTA_AG_RES_FMT_STR /* string argument */
-};
-
-/* Local AT command result codes not defined in bta_ag_api.h */
-enum {
- BTA_AG_LOCAL_RES_FIRST = 0x0100,
- BTA_AG_LOCAL_RES_OK,
- BTA_AG_LOCAL_RES_ERROR,
- BTA_AG_LOCAL_RES_RING,
- BTA_AG_LOCAL_RES_CLIP,
- BTA_AG_LOCAL_RES_BRSF,
- BTA_AG_LOCAL_RES_CMEE,
- BTA_AG_LOCAL_RES_BCS
-};
-
-/* AT result code constant table */
-static const tBTA_AG_RESULT bta_ag_result_tbl[] = {
- {"OK", BTA_AG_LOCAL_RES_OK, BTA_AG_RES_FMT_NONE},
- {"ERROR", BTA_AG_LOCAL_RES_ERROR, BTA_AG_RES_FMT_NONE},
- {"RING", BTA_AG_LOCAL_RES_RING, BTA_AG_RES_FMT_NONE},
- {"+VGS: ", BTA_AG_SPK_RES, BTA_AG_RES_FMT_INT},
- {"+VGM: ", BTA_AG_MIC_RES, BTA_AG_RES_FMT_INT},
- {"+CCWA: ", BTA_AG_CALL_WAIT_RES, BTA_AG_RES_FMT_STR},
- {"+CHLD: ", BTA_AG_IN_CALL_HELD_RES, BTA_AG_RES_FMT_STR},
- {"+CIND: ", BTA_AG_CIND_RES, BTA_AG_RES_FMT_STR},
- {"+CLIP: ", BTA_AG_LOCAL_RES_CLIP, BTA_AG_RES_FMT_STR},
- {"+CIEV: ", BTA_AG_IND_RES, BTA_AG_RES_FMT_STR},
- {"+BINP: ", BTA_AG_BINP_RES, BTA_AG_RES_FMT_STR},
- {"+BVRA: ", BTA_AG_BVRA_RES, BTA_AG_RES_FMT_INT},
- {"+BRSF: ", BTA_AG_LOCAL_RES_BRSF, BTA_AG_RES_FMT_INT},
- {"+BSIR: ", BTA_AG_INBAND_RING_RES, BTA_AG_RES_FMT_INT},
- {"+CNUM: ", BTA_AG_CNUM_RES, BTA_AG_RES_FMT_STR},
- {"+BTRH: ", BTA_AG_BTRH_RES, BTA_AG_RES_FMT_INT},
- {"+CLCC: ", BTA_AG_CLCC_RES, BTA_AG_RES_FMT_STR},
- {"+COPS: ", BTA_AG_COPS_RES, BTA_AG_RES_FMT_STR},
- {"+CME ERROR: ", BTA_AG_LOCAL_RES_CMEE, BTA_AG_RES_FMT_INT},
- {"+BCS: ", BTA_AG_LOCAL_RES_BCS, BTA_AG_RES_FMT_INT},
- {"+BIND: ", BTA_AG_BIND_RES, BTA_AG_RES_FMT_STR},
- {"", BTA_AG_UNAT_RES, BTA_AG_RES_FMT_STR}};
-
-static const tBTA_AG_RESULT* bta_ag_result_by_code(size_t code) {
- for (size_t i = 0;
- i != sizeof(bta_ag_result_tbl) / sizeof(bta_ag_result_tbl[0]); ++i) {
- if (code == bta_ag_result_tbl[i].result_id) return &bta_ag_result_tbl[i];
- }
- return nullptr;
-}
-
-const tBTA_AG_AT_CMD* bta_ag_at_tbl[BTA_AG_NUM_IDX] = {bta_ag_hsp_cmd,
- bta_ag_hfp_cmd};
-
-typedef struct {
- size_t result_code;
- size_t indicator;
-} tBTA_AG_INDICATOR_MAP;
-
-/* callsetup indicator value lookup table */
-static const tBTA_AG_INDICATOR_MAP callsetup_indicator_map[] = {
- {BTA_AG_IN_CALL_RES, BTA_AG_CALLSETUP_INCOMING},
- {BTA_AG_CALL_WAIT_RES, BTA_AG_CALLSETUP_INCOMING},
- {BTA_AG_OUT_CALL_ORIG_RES, BTA_AG_CALLSETUP_OUTGOING},
- {BTA_AG_OUT_CALL_ALERT_RES, BTA_AG_CALLSETUP_ALERTING}};
-
-static size_t bta_ag_indicator_by_result_code(size_t code) {
- for (size_t i = 0;
- i !=
- sizeof(callsetup_indicator_map) / sizeof(callsetup_indicator_map[0]);
- ++i) {
- if (code == callsetup_indicator_map[i].result_code)
- return callsetup_indicator_map[i].indicator;
- }
- return BTA_AG_CALLSETUP_NONE;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_send_result
- *
- * Description Send an AT result code.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_send_result(tBTA_AG_SCB* p_scb, size_t code,
- const char* p_arg, int16_t int_arg) {
- const tBTA_AG_RESULT* result = bta_ag_result_by_code(code);
- if (result == nullptr) {
- LOG_ERROR("%s Unable to lookup result for code %zu", __func__, code);
- return;
- }
-
- char buf[BTA_AG_AT_MAX_LEN + 16] = "";
- char* p = buf;
-
- /* init with \r\n */
- *p++ = '\r';
- *p++ = '\n';
-
- /* copy result code string */
- strlcpy(p, result->result_string, sizeof(buf) - 2);
-
- if (p_scb->conn_service == BTA_AG_HSP) {
- /* If HSP then ":"symbol should be changed as "=" for HSP compatibility */
- switch (code) {
- case BTA_AG_SPK_RES:
- case BTA_AG_MIC_RES:
- if (*(p + COLON_IDX_4_VGSVGM) == ':') {
- *(p + COLON_IDX_4_VGSVGM) = '=';
- }
- break;
- }
- }
-
- p += strlen(result->result_string);
-
- /* copy argument if any */
- if (result->arg_type == BTA_AG_RES_FMT_INT) {
- p += utl_itoa((uint16_t)int_arg, p);
- } else if (result->arg_type == BTA_AG_RES_FMT_STR) {
- strcpy(p, p_arg);
- p += strlen(p_arg);
- }
-
- /* finish with \r\n */
- *p++ = '\r';
- *p++ = '\n';
-
- /* send to RFCOMM */
- uint16_t len = 0;
- PORT_WriteData(p_scb->conn_handle, buf, (uint16_t)(p - buf), &len);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_send_ok
- *
- * Description Send an OK result code.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_send_ok(tBTA_AG_SCB* p_scb) {
- bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_OK, nullptr, 0);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_send_error
- *
- * Description Send an ERROR result code.
- * errcode - used to send verbose errocode
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_send_error(tBTA_AG_SCB* p_scb, int16_t errcode) {
- /* If HFP and extended audio gateway error codes are enabled */
- if (p_scb->conn_service == BTA_AG_HFP && p_scb->cmee_enabled)
- bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_CMEE, nullptr, errcode);
- else
- bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_ERROR, nullptr, 0);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_send_ind
- *
- * Description Send an indicator CIEV result code.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_send_ind(tBTA_AG_SCB* p_scb, uint16_t id, uint16_t value,
- bool on_demand) {
- char str[12];
- char* p = str;
-
- /* If the indicator is masked out, just return */
- /* Mandatory indicators can not be masked out. */
- if ((p_scb->bia_masked_out & ((uint32_t)1 << id)) &&
- ((id != BTA_AG_IND_CALL) && (id != BTA_AG_IND_CALLSETUP) &&
- (id != BTA_AG_IND_CALLHELD)))
- return;
-
- /* Ensure we do not send duplicate indicators if not requested by app */
- /* If it was requested by app, transmit CIEV even if it is duplicate. */
- if (id == BTA_AG_IND_CALL) {
- if ((value == p_scb->call_ind) && (!on_demand)) return;
-
- p_scb->call_ind = (uint8_t)value;
- }
-
- if ((id == BTA_AG_IND_CALLSETUP) && (!on_demand)) {
- if (value == p_scb->callsetup_ind) return;
-
- p_scb->callsetup_ind = (uint8_t)value;
- }
-
- if ((id == BTA_AG_IND_SERVICE) && (!on_demand)) {
- if (value == p_scb->service_ind) return;
-
- p_scb->service_ind = (uint8_t)value;
- }
- if ((id == BTA_AG_IND_SIGNAL) && (!on_demand)) {
- if (value == p_scb->signal_ind) return;
-
- p_scb->signal_ind = (uint8_t)value;
- }
- if ((id == BTA_AG_IND_ROAM) && (!on_demand)) {
- if (value == p_scb->roam_ind) return;
-
- p_scb->roam_ind = (uint8_t)value;
- }
- if ((id == BTA_AG_IND_BATTCHG) && (!on_demand)) {
- if (value == p_scb->battchg_ind) return;
-
- p_scb->battchg_ind = (uint8_t)value;
- }
-
- if ((id == BTA_AG_IND_CALLHELD) && (!on_demand)) {
- /* call swap could result in sending callheld=1 multiple times */
- if ((value != 1) && (value == p_scb->callheld_ind)) return;
-
- p_scb->callheld_ind = (uint8_t)value;
- }
-
- if (p_scb->cmer_enabled) {
- p += utl_itoa(id, p);
- *p++ = ',';
- utl_itoa(value, p);
- bta_ag_send_result(p_scb, BTA_AG_IND_RES, str, 0);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_parse_cmer
- *
- * Description Parse AT+CMER parameter string.
- *
- *
- * Returns true if parsed ok, false otherwise.
- *
- ******************************************************************************/
-static bool bta_ag_parse_cmer(char* p_s, char* p_end, bool* p_enabled) {
- int16_t n[4] = {-1, -1, -1, -1};
- int i;
- char* p;
-
- for (i = 0; i < 4; i++, p_s = p + 1) {
- /* skip to comma delimiter */
- for (p = p_s; p < p_end && *p != ',' && *p != 0; p++)
- ;
-
- /* get integer value */
- if (p > p_end) {
- android_errorWriteLog(0x534e4554, "112860487");
- return false;
- }
- *p = 0;
- n[i] = utl_str2int(p_s);
- }
-
- /* process values */
- if (n[0] < 0 || n[3] < 0) {
- return false;
- }
-
- if ((n[0] == 3) && ((n[3] == 1) || (n[3] == 0))) {
- *p_enabled = (bool)n[3];
- }
-
- return true;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_parse_chld
- *
- * Description Parse AT+CHLD parameter string.
- *
- *
- * Returns Returns idx (1-7), 0 if ECC not enabled or
- BTA_AG_INVALID_CHLD
- if idx doesn't exist/1st character of argument is not a
- digit
- *
- ******************************************************************************/
-static uint8_t bta_ag_parse_chld(UNUSED_ATTR tBTA_AG_SCB* p_scb, char* p_s) {
- uint8_t retval = 0;
-
- if (!isdigit(p_s[0])) {
- return BTA_AG_INVALID_CHLD;
- }
-
- if (p_s[1] != 0) {
- /* p_idxstr++; point to beginning of call number */
- int16_t idx = utl_str2int(&p_s[1]);
- if (idx != -1 && idx < 255) {
- retval = (uint8_t)idx;
- } else {
- retval = BTA_AG_INVALID_CHLD;
- }
- }
-
- return (retval);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_parse_bac
- *
- * Description Parse AT+BAC parameter string.
- *
- * Returns Returns bitmap of supported codecs.
- *
- ******************************************************************************/
-static tBTA_AG_PEER_CODEC bta_ag_parse_bac(tBTA_AG_SCB* p_scb, char* p_s,
- char* p_end) {
- tBTA_AG_PEER_CODEC retval = BTM_SCO_CODEC_NONE;
- uint16_t uuid_codec;
- char* p;
-
- while (p_s) {
- /* skip to comma delimiter */
- for (p = p_s; p < p_end && *p != ',' && *p != 0; p++)
- ;
-
- /* get integer value */
- if (p > p_end) {
- android_errorWriteLog(0x534e4554, "112860487");
- break;
- }
- bool cont = false; // Continue processing
- if (*p != 0) {
- *p = 0;
- cont = true;
- }
- uuid_codec = utl_str2int(p_s);
- switch (uuid_codec) {
- case UUID_CODEC_CVSD:
- retval |= BTM_SCO_CODEC_CVSD;
- break;
- case UUID_CODEC_MSBC:
- retval |= BTM_SCO_CODEC_MSBC;
- break;
- default:
- APPL_TRACE_ERROR("Unknown Codec UUID(%d) received", uuid_codec);
- break;
- }
-
- if (cont)
- p_s = p + 1;
- else
- break;
- }
-
- return (retval);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_process_unat_res
- *
- * Description Process the unat response data and remove extra carriage
- * return and line feed
- *
- *
- * Returns void
- *
- ******************************************************************************/
-
-static void bta_ag_process_unat_res(char* unat_result) {
- uint8_t j = 0;
- uint8_t pairs_of_nl_cr;
- char trim_data[BTA_AG_AT_MAX_LEN];
-
- uint8_t str_leng = strlen(unat_result);
-
- /* If no extra CR and LF, just return */
- if (str_leng < 4) return;
-
- /* Remove the carriage return and left feed */
- while (unat_result[0] == '\r' && unat_result[1] == '\n' &&
- unat_result[str_leng - 2] == '\r' &&
- unat_result[str_leng - 1] == '\n') {
- pairs_of_nl_cr = 1;
- for (int i = 0; i < (str_leng - 4 * pairs_of_nl_cr); i++) {
- trim_data[j++] = unat_result[i + pairs_of_nl_cr * 2];
- }
- /* Add EOF */
- trim_data[j] = '\0';
- str_leng = str_leng - 4;
- strlcpy(unat_result, trim_data, str_leng + 1);
- j = 0;
-
- if (str_leng < 4) return;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_inband_enabled
- *
- * Description Determine whether in-band ring can be used.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-bool bta_ag_inband_enabled(tBTA_AG_SCB* p_scb) {
- /* if feature is enabled and no other scbs connected */
- return p_scb->inband_enabled && !bta_ag_other_scb_open(p_scb);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_send_call_inds
- *
- * Description Send call and callsetup indicators.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_send_call_inds(tBTA_AG_SCB* p_scb, tBTA_AG_RES result) {
- uint8_t call;
-
- /* set new call and callsetup values based on BTA_AgResult */
- size_t callsetup = bta_ag_indicator_by_result_code(result);
-
- if (result == BTA_AG_END_CALL_RES) {
- call = BTA_AG_CALL_INACTIVE;
- } else if (result == BTA_AG_IN_CALL_CONN_RES ||
- result == BTA_AG_OUT_CALL_CONN_RES ||
- result == BTA_AG_IN_CALL_HELD_RES) {
- call = BTA_AG_CALL_ACTIVE;
- } else {
- call = p_scb->call_ind;
- }
-
- /* Send indicator function tracks if the values have actually changed */
- bta_ag_send_ind(p_scb, BTA_AG_IND_CALL, call, false);
- bta_ag_send_ind(p_scb, BTA_AG_IND_CALLSETUP, callsetup, false);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_at_hsp_cback
- *
- * Description AT command processing callback for HSP.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_at_hsp_cback(tBTA_AG_SCB* p_scb, uint16_t command_id,
- uint8_t arg_type, char* p_arg, char* p_end,
- int16_t int_arg) {
- APPL_TRACE_DEBUG("AT cmd:%d arg_type:%d arg:%d arg:%s", command_id, arg_type,
- int_arg, p_arg);
-
- bta_ag_send_ok(p_scb);
-
- tBTA_AG_VAL val = {};
- val.hdr.handle = bta_ag_scb_to_idx(p_scb);
- val.hdr.app_id = p_scb->app_id;
- val.num = (uint16_t)int_arg;
-
- if ((p_end - p_arg + 1) >= (long)sizeof(val.str)) {
- APPL_TRACE_ERROR("%s: p_arg is too long, send error and return", __func__);
- bta_ag_send_error(p_scb, BTA_AG_ERR_TEXT_TOO_LONG);
- android_errorWriteLog(0x534e4554, "112860487");
- return;
- }
- strlcpy(val.str, p_arg, sizeof(val.str));
-
- /* call callback with event */
- if (command_id & 0xff00) {
- LOG_WARN("Received value that exceeds data type - lost information");
- }
- tBTA_AG_EVT event = static_cast<tBTA_AG_EVT>(command_id);
- (*bta_ag_cb.p_cback)(event, (tBTA_AG*)&val);
-}
-
-static void remove_spaces(char* str) {
- char* dest_str = str;
-
- while (*str) {
- if (*str == ' ') {
- str++;
- } else {
- *dest_str++ = *str++;
- }
- }
- *dest_str = '\0';
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_find_empty_hf_ind)
- *
- * Description This function returns the index of an empty HF indicator
- * structure.
- *
- * Returns int : index of the empty HF indicator structure or
- * -1 if no empty indicator
- * is available.
- *
- ******************************************************************************/
-static int bta_ag_find_empty_hf_ind(tBTA_AG_SCB* p_scb) {
- for (int index = 0; index < BTA_AG_MAX_NUM_PEER_HF_IND; index++) {
- if (p_scb->peer_hf_indicators[index].ind_id == 0) return index;
- }
-
- return -1;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_find_hf_ind_by_id
- *
- * Description This function returns the index of the HF indicator
- * structure by the indicator id
- *
- * Returns int : index of the HF indicator structure
- * -1 if the indicator
- * was not found.
- *
- ******************************************************************************/
-static int bta_ag_find_hf_ind_by_id(tBTA_AG_HF_IND* p_hf_ind, int size,
- uint32_t ind_id) {
- for (int index = 0; index < size; index++) {
- if (p_hf_ind[index].ind_id == ind_id) return index;
- }
-
- return -1;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_parse_bind_set
- *
- * Description Parse AT+BIND set command and save the indicators
- *
- * Returns true if successful
- *
- ******************************************************************************/
-static bool bta_ag_parse_bind_set(tBTA_AG_SCB* p_scb, tBTA_AG_VAL val) {
- char* p_token = strtok(val.str, ",");
- if (p_token == nullptr) return false;
-
- while (p_token != nullptr) {
- uint16_t rcv_ind_id = atoi(p_token);
- int index = bta_ag_find_empty_hf_ind(p_scb);
- if (index == -1) {
- APPL_TRACE_WARNING("%s Can't save more indicators", __func__);
- return false;
- }
-
- p_scb->peer_hf_indicators[index].ind_id = rcv_ind_id;
- APPL_TRACE_DEBUG("%s peer_hf_ind[%d] = %d", __func__, index, rcv_ind_id);
-
- p_token = strtok(nullptr, ",");
- }
-
- return true;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_bind_response
- *
- * Description Send response for the AT+BIND command (HFP 1.7) received
- * from the headset based on the argument types.
- *
- * Returns Void
- *
- ******************************************************************************/
-static void bta_ag_bind_response(tBTA_AG_SCB* p_scb, uint8_t arg_type) {
- char buffer[BTA_AG_AT_MAX_LEN] = "";
-
- if (arg_type == BTA_AG_AT_TEST) {
- int index = 0;
- buffer[index++] = '(';
-
- for (uint32_t i = 0; i < bta_ag_local_hf_ind_cfg[0].ind_id; i++) {
- if (bta_ag_local_hf_ind_cfg[i + 1].is_supported) {
- /* Add ',' from second indicator */
- if (index > 1) buffer[index++] = ',';
- snprintf(&buffer[index++], 2, "%d",
- bta_ag_local_hf_ind_cfg[i + 1].ind_id);
- }
- }
-
- buffer[index++] = ')';
-
- bta_ag_send_result(p_scb, BTA_AG_BIND_RES, buffer, 0);
- bta_ag_send_ok(p_scb);
- } else if (arg_type == BTA_AG_AT_READ) {
- char* p = buffer;
-
- /* bta_ag_local_hf_ind_cfg[0].ind_id is used as BTA_AG_NUM_LOCAL_HF_IND */
- for (uint32_t i = 0; i < bta_ag_local_hf_ind_cfg[0].ind_id; i++) {
- if (i == BTA_AG_MAX_NUM_LOCAL_HF_IND) {
- APPL_TRACE_WARNING("%s No space for more HF indicators", __func__);
- break;
- }
-
- p_scb->local_hf_indicators[i].ind_id =
- bta_ag_local_hf_ind_cfg[i + 1].ind_id;
- p_scb->local_hf_indicators[i].is_supported =
- bta_ag_local_hf_ind_cfg[i + 1].is_supported;
- p_scb->local_hf_indicators[i].is_enable =
- bta_ag_local_hf_ind_cfg[i + 1].is_enable;
-
- int peer_index = bta_ag_find_hf_ind_by_id(
- p_scb->peer_hf_indicators, BTA_AG_MAX_NUM_PEER_HF_IND,
- p_scb->local_hf_indicators[i].ind_id);
-
- /* Check whether local and peer sides support this indicator */
- if (p_scb->local_hf_indicators[i].is_supported && peer_index != -1) {
- /* In the format of ind, state */
- p += utl_itoa((uint16_t)p_scb->local_hf_indicators[i].ind_id, p);
- *p++ = ',';
- p += utl_itoa((uint16_t)p_scb->local_hf_indicators[i].is_enable, p);
-
- bta_ag_send_result(p_scb, BTA_AG_BIND_RES, buffer, 0);
- // have to use memset here because assigning to "" will not zero
- // initialize the rest of the buffer
- memset(buffer, 0, sizeof(buffer));
- p = buffer;
- } else {
- /* If indicator is not supported, also set it to disable */
- p_scb->local_hf_indicators[i].is_enable = false;
- }
- }
-
- bta_ag_send_ok(p_scb);
-
- /* If the service level connection wan't already open, now it's open */
- if (!p_scb->svc_conn) {
- bta_ag_svc_conn_open(p_scb, tBTA_AG_DATA::kEmpty);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_parse_biev_response
- *
- * Description Send response for AT+BIEV command (HFP 1.7) received from
- * the headset based on the argument types.
- *
- * Returns true if the response was parsed successfully
- *
- ******************************************************************************/
-static bool bta_ag_parse_biev_response(tBTA_AG_SCB* p_scb, tBTA_AG_VAL* val) {
- char* p_token = strtok(val->str, ",");
- if (p_token == nullptr) return false;
- uint16_t rcv_ind_id = atoi(p_token);
-
- p_token = strtok(nullptr, ",");
- if (p_token == nullptr) return false;
- uint16_t rcv_ind_val = atoi(p_token);
-
- APPL_TRACE_DEBUG("%s BIEV indicator id %d, value %d", __func__, rcv_ind_id,
- rcv_ind_val);
-
- /* Check whether indicator ID is valid or not */
- if (rcv_ind_id > BTA_AG_NUM_LOCAL_HF_IND) {
- APPL_TRACE_WARNING("%s received invalid indicator id %d", __func__,
- rcv_ind_id);
- return false;
- }
-
- /* Check this indicator is support or not and enabled or not */
- int local_index = bta_ag_find_hf_ind_by_id(
- p_scb->local_hf_indicators, BTA_AG_MAX_NUM_LOCAL_HF_IND, rcv_ind_id);
- if (local_index == -1 ||
- !p_scb->local_hf_indicators[local_index].is_supported ||
- !p_scb->local_hf_indicators[local_index].is_enable) {
- APPL_TRACE_WARNING("%s indicator id %d not supported or disabled", __func__,
- rcv_ind_id);
- return false;
- }
-
- /* For each indicator ID, check whether the indicator value is in range */
- if (rcv_ind_val < bta_ag_local_hf_ind_cfg[rcv_ind_id].ind_min_val ||
- rcv_ind_val > bta_ag_local_hf_ind_cfg[rcv_ind_id].ind_max_val) {
- APPL_TRACE_WARNING("%s invalid ind_val %d", __func__, rcv_ind_val);
- return false;
- }
-
- val->lidx = rcv_ind_id;
- val->num = rcv_ind_val;
-
- return true;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_bind_timer_cback
- *
- * Description Handles bind timer callback
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_bind_timer_cback(void* data) {
- tBTA_AG_SCB* p_scb = (tBTA_AG_SCB*)data;
- bta_ag_svc_conn_open(p_scb, tBTA_AG_DATA::kEmpty);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_at_hfp_cback
- *
- * Description AT command processing callback for HFP.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type,
- char* p_arg, char* p_end, int16_t int_arg) {
- tBTA_AG_VAL val = {};
- tBTA_AG_SCB* ag_scb;
- uint32_t i, ind_id;
- uint32_t bia_masked_out;
- if (p_arg == nullptr) {
- LOG_WARN("p_arg is null for cmd 0x%x, send error and return", cmd);
- bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR);
- return;
- }
-
- APPL_TRACE_DEBUG("%s: AT command %d, arg_type %d, int_arg %d, arg %s",
- __func__, cmd, arg_type, int_arg, p_arg);
-
- val.hdr.handle = bta_ag_scb_to_idx(p_scb);
- val.hdr.app_id = p_scb->app_id;
- val.hdr.status = BTA_AG_SUCCESS;
- val.num = static_cast<uint32_t>(int_arg);
- val.bd_addr = p_scb->peer_addr;
-
- if ((p_end - p_arg + 1) >= (long)sizeof(val.str)) {
- LOG_ERROR("p_arg is too long for cmd 0x%x, send error and return", cmd);
- bta_ag_send_error(p_scb, BTA_AG_ERR_TEXT_TOO_LONG);
- android_errorWriteLog(0x534e4554, "112860487");
- return;
- }
- strlcpy(val.str, p_arg, sizeof(val.str));
-
- /**
- * Unless this this is a local event, by default we'll forward
- * the event code to the application.
- * If |event| is 0 at the end of this function, the application
- * callback is NOT invoked.
- */
- tBTA_AG_EVT event = BTA_AG_ENABLE_EVT;
- if (cmd < BTA_AG_LOCAL_EVT_FIRST) {
- event = static_cast<tBTA_AG_EVT>(cmd);
- }
-
- switch (cmd) {
- case BTA_AG_AT_A_EVT:
- case BTA_AG_SPK_EVT:
- case BTA_AG_MIC_EVT:
- case BTA_AG_AT_CBC_EVT:
- /* send OK */
- bta_ag_send_ok(p_scb);
- break;
-
- case BTA_AG_AT_CHUP_EVT:
- if (!bta_ag_sco_is_active_device(p_scb->peer_addr)) {
- LOG(WARNING) << __func__ << ": AT+CHUP rejected as " << p_scb->peer_addr
- << " is not the active device";
- event = BTA_AG_ENABLE_EVT;
- bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_ALLOWED);
- } else {
- bta_ag_send_ok(p_scb);
- }
- break;
-
- case BTA_AG_AT_BLDN_EVT:
- /* Do not send OK, App will send error or OK depending on
- ** last dial number enabled or not */
- break;
-
- case BTA_AG_AT_D_EVT:
- /* Do not send OK for Dial cmds
- ** Let application decide whether to send OK or ERROR*/
-
- /* if mem dial cmd, make sure string contains only digits */
- if (val.str[0] == '>') {
- /* Some car kits may add some unwanted space characters in the
- ** input string. This workaround will trim the unwanted chars. */
- remove_spaces(val.str + 1);
-
- if (!utl_isintstr(val.str + 1)) {
- event = BTA_AG_ENABLE_EVT;
- bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_DSTR);
- }
- } else if (val.str[0] == 'V') /* ATDV : Dial VoIP Call */
- {
- /* We do not check string. Code will be added later if needed. */
- if (!((p_scb->peer_features & BTA_AG_PEER_FEAT_VOIP) &&
- (p_scb->features & BTA_AG_FEAT_VOIP))) {
- event = BTA_AG_ENABLE_EVT;
- bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
- }
- }
- /* If dial cmd, make sure string contains only dial digits
- ** Dial digits are 0-9, A-C, *, #, + */
- else {
- /* Some car kits may add some unwanted space characters in the
- ** input string. This workaround will trim the unwanted chars. */
- remove_spaces(val.str);
-
- if (!utl_isdialstr(val.str)) {
- event = BTA_AG_ENABLE_EVT;
- bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_DSTR);
- }
- }
- break;
-
- case BTA_AG_LOCAL_EVT_CCWA:
- /* store setting */
- p_scb->ccwa_enabled = (bool)int_arg;
-
- /* send OK */
- bta_ag_send_ok(p_scb);
- break;
-
- case BTA_AG_AT_CHLD_EVT:
- if (arg_type == BTA_AG_AT_TEST) {
- /* don't call callback */
- event = BTA_AG_ENABLE_EVT;
-
- /* send CHLD string */
- /* Form string based on supported 1.5 feature */
- if ((p_scb->peer_version >= HFP_VERSION_1_5) &&
- (p_scb->features & BTA_AG_FEAT_ECC) &&
- (p_scb->peer_features & BTA_AG_PEER_FEAT_ECC))
- bta_ag_send_result(p_scb, BTA_AG_IN_CALL_HELD_RES,
- p_bta_ag_cfg->chld_val_ecc, 0);
- else
- bta_ag_send_result(p_scb, BTA_AG_IN_CALL_HELD_RES,
- p_bta_ag_cfg->chld_val, 0);
-
- /* send OK */
- bta_ag_send_ok(p_scb);
-
- /* if service level conn. not already open and our features and
- ** peer features do not have HF Indicators, service level conn. now open
- */
- if (!p_scb->svc_conn &&
- !((p_scb->masked_features & BTA_AG_FEAT_HF_IND) &&
- (p_scb->peer_features & BTA_AG_PEER_FEAT_HF_IND))) {
- bta_ag_svc_conn_open(p_scb, tBTA_AG_DATA::kEmpty);
- } else {
- if (p_scb->peer_version >= HFP_VERSION_1_7 &&
- interop_match_addr(INTEROP_SLC_SKIP_BIND_COMMAND,
- &p_scb->peer_addr)) {
- alarm_set_on_mloop(p_scb->bind_timer, BTA_AG_BIND_TIMEOUT_MS,
- bta_ag_bind_timer_cback, p_scb);
- }
- }
- } else {
- val.idx = bta_ag_parse_chld(p_scb, val.str);
-
- if (val.idx == BTA_AG_INVALID_CHLD) {
- event = BTA_AG_ENABLE_EVT;
- bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
- break;
- }
- if (val.idx &&
- !((p_scb->features & BTA_AG_FEAT_ECC) &&
- (p_scb->peer_features & BTA_AG_PEER_FEAT_ECC))) {
- /* we do not support ECC, but HF is sending us a CHLD with call
- * index*/
- event = BTA_AG_ENABLE_EVT;
- bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
-
- } else {
- /* If it is swap between calls, set call held indicator to 3(out of
- *valid 0-2)
- ** Application will set it back to 1
- ** callheld indicator will be sent across to the peer. */
- if (val.str[0] == '2') {
- for (i = 0, ag_scb = &bta_ag_cb.scb[0]; i < BTA_AG_MAX_NUM_CLIENTS;
- i++, ag_scb++) {
- if (ag_scb->in_use) {
- if ((ag_scb->call_ind == BTA_AG_CALL_ACTIVE) &&
- (ag_scb->callsetup_ind == BTA_AG_CALLSETUP_NONE))
- ag_scb->callheld_ind = BTA_AG_CALLHELD_NOACTIVE + 1;
- }
- }
- }
- }
-
- /* Do not send OK. Let app decide after parsing the val str */
- /* bta_ag_send_ok(p_scb); */
- }
- break;
-
- case BTA_AG_AT_BIND_EVT:
- APPL_TRACE_DEBUG("%s BTA_AG_AT_BIND_EVT arg_type: %d", __func__,
- arg_type);
- alarm_cancel(p_scb->bind_timer);
- if (arg_type == BTA_AG_AT_SET) {
- if (bta_ag_parse_bind_set(p_scb, val)) {
- bta_ag_send_ok(p_scb);
- } else {
- event = BTA_AG_ENABLE_EVT; /* don't call callback */
- bta_ag_send_error(p_scb, BTA_AG_ERR_INVALID_INDEX);
- }
- } else {
- bta_ag_bind_response(p_scb, arg_type);
-
- /* Need not pass this command beyond BTIF.*/
- /* Stack handles it internally */
- event = BTA_AG_ENABLE_EVT; /* don't call callback */
- }
- break;
-
- case BTA_AG_AT_BIEV_EVT:
- if (bta_ag_parse_biev_response(p_scb, &val)) {
- bta_ag_send_ok(p_scb);
- } else {
- bta_ag_send_error(p_scb, BTA_AG_ERR_INVALID_INDEX);
- /* don't call callback receiving invalid indicator */
- event = BTA_AG_ENABLE_EVT;
- }
- break;
-
- case BTA_AG_AT_CIND_EVT:
- if (arg_type == BTA_AG_AT_TEST) {
- /* don't call callback */
- event = BTA_AG_ENABLE_EVT;
-
- /* send CIND string, send OK */
- bta_ag_send_result(p_scb, BTA_AG_CIND_RES, p_bta_ag_cfg->cind_info, 0);
- bta_ag_send_ok(p_scb);
- }
- break;
-
- case BTA_AG_LOCAL_EVT_CLIP:
- /* store setting, send OK */
- p_scb->clip_enabled = (bool)int_arg;
- bta_ag_send_ok(p_scb);
- break;
-
- case BTA_AG_LOCAL_EVT_CMER:
- /* if parsed ok store setting, send OK */
- if (bta_ag_parse_cmer(p_arg, p_end, &p_scb->cmer_enabled)) {
- bta_ag_send_ok(p_scb);
-
- /* if service level conn. not already open and our features and
- * peer features do not have 3-way or HF Indicators, service level conn.
- * now open */
- if (!p_scb->svc_conn &&
- !((p_scb->masked_features & BTA_AG_FEAT_3WAY) &&
- (p_scb->peer_features & BTA_AG_PEER_FEAT_3WAY)) &&
- !((p_scb->masked_features & BTA_AG_FEAT_HF_IND) &&
- (p_scb->peer_features & BTA_AG_PEER_FEAT_HF_IND))) {
- bta_ag_svc_conn_open(p_scb, tBTA_AG_DATA::kEmpty);
- }
- } else {
- bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR);
- }
- break;
-
- case BTA_AG_AT_VTS_EVT:
- /* check argument */
- if (strlen(p_arg) == 1) {
- bta_ag_send_ok(p_scb);
- } else {
- event = BTA_AG_ENABLE_EVT;
- bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR);
- }
- break;
-
- case BTA_AG_AT_BINP_EVT:
- /* if feature not set don't call callback, send ERROR */
- if (!(p_scb->features & BTA_AG_FEAT_VTAG)) {
- event = BTA_AG_ENABLE_EVT;
- bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
- }
- break;
-
- case BTA_AG_AT_BVRA_EVT:
- /* if feature not supported don't call callback, send ERROR. App will send
- * OK */
- if (!(p_scb->features & BTA_AG_FEAT_VREC)) {
- event = BTA_AG_ENABLE_EVT;
- bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
- }
- break;
-
- case BTA_AG_LOCAL_EVT_BRSF: {
- /* store peer features */
- p_scb->peer_features = (uint16_t)int_arg;
-
- if (p_scb->peer_version < HFP_VERSION_1_7) {
- p_scb->masked_features &= HFP_1_6_FEAT_MASK;
- }
-
- APPL_TRACE_DEBUG("%s BRSF HF: 0x%x, phone: 0x%x", __func__,
- p_scb->peer_features, p_scb->masked_features);
-
- /* send BRSF, send OK */
- bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_BRSF, nullptr,
- (int16_t)p_scb->masked_features);
- bta_ag_send_ok(p_scb);
- break;
- }
-
- case BTA_AG_AT_NREC_EVT:
- /* if feature send OK, else don't call callback, send ERROR */
- if (p_scb->features & BTA_AG_FEAT_ECNR) {
- bta_ag_send_ok(p_scb);
- } else {
- event = BTA_AG_ENABLE_EVT;
- bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
- }
- break;
-
- case BTA_AG_AT_BTRH_EVT:
- /* if feature send BTRH, send OK:, else don't call callback, send ERROR */
- if (p_scb->features & BTA_AG_FEAT_BTRH) {
- /* If set command; send response and notify app */
- if (arg_type == BTA_AG_AT_SET) {
- for (i = 0, ag_scb = &bta_ag_cb.scb[0]; i < BTA_AG_MAX_NUM_CLIENTS;
- i++, ag_scb++) {
- if (ag_scb->in_use) {
- bta_ag_send_result(ag_scb, BTA_AG_BTRH_RES, nullptr, int_arg);
- }
- }
- bta_ag_send_ok(p_scb);
- } else /* Read Command */
- {
- val.num = BTA_AG_BTRH_READ;
- }
- } else {
- event = BTA_AG_ENABLE_EVT;
- bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
- }
- break;
-
- case BTA_AG_AT_COPS_EVT:
- if (arg_type == BTA_AG_AT_SET) {
- /* don't call callback */
- event = BTA_AG_ENABLE_EVT;
-
- /* send OK */
- bta_ag_send_ok(p_scb);
- }
- break;
-
- case BTA_AG_LOCAL_EVT_CMEE:
- if (p_scb->features & BTA_AG_FEAT_EXTERR) {
- /* store setting */
- p_scb->cmee_enabled = (bool)int_arg;
-
- /* send OK */
- bta_ag_send_ok(p_scb);
- } else {
- bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
- }
- /* don't call callback */
- event = BTA_AG_ENABLE_EVT;
- break;
-
- case BTA_AG_AT_BIA_EVT:
- bia_masked_out = p_scb->bia_masked_out;
-
- /* Parse the indicator mask */
- for (i = 0, ind_id = 1; (val.str[i] != 0) && (ind_id <= 20);
- i++, ind_id++) {
- if (val.str[i] == ',') {
- continue;
- }
-
- if (val.str[i] == '0') {
- bia_masked_out |= ((uint32_t)1 << ind_id);
- } else if (val.str[i] == '1') {
- bia_masked_out &= ~((uint32_t)1 << ind_id);
- } else {
- break;
- }
-
- i++;
- if (val.str[i] != ',') {
- break;
- }
- }
- if (val.str[i] == 0) {
- p_scb->bia_masked_out = bia_masked_out;
- val.num = bia_masked_out;
- bta_ag_send_ok(p_scb);
- } else {
- event = BTA_AG_ENABLE_EVT;
- bta_ag_send_error(p_scb, BTA_AG_ERR_INVALID_INDEX);
- }
- break;
-
- case BTA_AG_AT_CNUM_EVT:
- break;
-
- case BTA_AG_AT_CLCC_EVT:
- if (!(p_scb->features & BTA_AG_FEAT_ECS)) {
- event = BTA_AG_ENABLE_EVT;
- bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
- }
- break;
-
- case BTA_AG_AT_BAC_EVT:
- bta_ag_send_ok(p_scb);
- p_scb->received_at_bac = true;
-
- /* store available codecs from the peer */
- if ((p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC) &&
- (p_scb->features & BTA_AG_FEAT_CODEC)) {
- p_scb->peer_codecs = bta_ag_parse_bac(p_scb, p_arg, p_end);
- p_scb->codec_updated = true;
-
- if (p_scb->peer_codecs & BTM_SCO_CODEC_MSBC) {
- p_scb->sco_codec = UUID_CODEC_MSBC;
- APPL_TRACE_DEBUG("Received AT+BAC, updating sco codec to MSBC");
- } else {
- p_scb->sco_codec = UUID_CODEC_CVSD;
- APPL_TRACE_DEBUG("Received AT+BAC, updating sco codec to CVSD");
- }
- /* The above logic sets the stack preferred codec based on local and
- peer codec
- capabilities. This can be overridden by the application depending on its
- preference
- using the bta_ag_setcodec API. We send the peer_codecs to the
- application. */
- val.num = p_scb->peer_codecs;
- /* Received BAC while in codec negotiation. */
- if ((bta_ag_cb.sco.state == BTA_AG_SCO_CODEC_ST) &&
- (bta_ag_cb.sco.p_curr_scb == p_scb)) {
- bta_ag_codec_negotiate(p_scb);
- }
- } else {
- p_scb->peer_codecs = BTM_SCO_CODEC_CVSD;
- APPL_TRACE_ERROR(
- "Unexpected CMD:AT+BAC, Codec Negotiation is not supported");
- }
- break;
-
- case BTA_AG_AT_BCS_EVT: {
- tBTA_AG_PEER_CODEC codec_type, codec_sent;
- bta_ag_send_ok(p_scb);
- alarm_cancel(p_scb->codec_negotiation_timer);
-
- switch (int_arg) {
- case UUID_CODEC_CVSD:
- codec_type = BTM_SCO_CODEC_CVSD;
- break;
- case UUID_CODEC_MSBC:
- codec_type = BTM_SCO_CODEC_MSBC;
- break;
- default:
- APPL_TRACE_ERROR("Unknown codec_uuid %d", int_arg);
- codec_type = 0xFFFF;
- break;
- }
-
- if (p_scb->codec_fallback)
- codec_sent = BTM_SCO_CODEC_CVSD;
- else
- codec_sent = p_scb->sco_codec;
-
- bta_ag_sco_codec_nego(p_scb, codec_type == codec_sent);
-
- /* send final codec info to callback */
- val.num = codec_sent;
- break;
- }
- case BTA_AG_LOCAL_EVT_BCC: {
- if (!bta_ag_sco_is_active_device(p_scb->peer_addr)) {
- LOG(WARNING) << __func__ << ": AT+BCC rejected as " << p_scb->peer_addr
- << " is not the active device";
- bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_ALLOWED);
- break;
- }
- bta_ag_send_ok(p_scb);
- bta_ag_sco_open(p_scb, tBTA_AG_DATA::kEmpty);
- break;
- }
- default:
- bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
- break;
- }
-
- /* call callback */
- if (event != BTA_AG_ENABLE_EVT) {
- (*bta_ag_cb.p_cback)(event, (tBTA_AG*)&val);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_at_err_cback
- *
- * Description AT command parser error callback.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_at_err_cback(tBTA_AG_SCB* p_scb, bool unknown, const char* p_arg) {
- if (unknown && (!strlen(p_arg))) {
- APPL_TRACE_DEBUG("Empty AT cmd string received");
- bta_ag_send_ok(p_scb);
- return;
- }
-
- tBTA_AG_VAL val = {};
- /* if unknown AT command and configured to pass these to app */
- if (unknown && (p_scb->features & BTA_AG_FEAT_UNAT)) {
- val.hdr.handle = bta_ag_scb_to_idx(p_scb);
- val.hdr.app_id = p_scb->app_id;
- val.hdr.status = BTA_AG_SUCCESS;
- val.num = 0;
- strlcpy(val.str, p_arg, sizeof(val.str));
- (*bta_ag_cb.p_cback)(BTA_AG_AT_UNAT_EVT, (tBTA_AG*)&val);
- } else {
- bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_hsp_result
- *
- * Description Handle API result for HSP connections.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_hsp_result(tBTA_AG_SCB* p_scb,
- const tBTA_AG_API_RESULT& result) {
- APPL_TRACE_DEBUG("bta_ag_hsp_result : res = %d", result.result);
-
- switch (result.result) {
- case BTA_AG_SPK_RES:
- case BTA_AG_MIC_RES:
- bta_ag_send_result(p_scb, result.result, nullptr, result.data.num);
- break;
-
- case BTA_AG_IN_CALL_RES:
- /* tell sys to stop av if any */
- bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
-
- /* if sco already opened or no inband ring send ring now */
- if (bta_ag_sco_is_open(p_scb) || !bta_ag_inband_enabled(p_scb) ||
- (p_scb->features & BTA_AG_FEAT_NOSCO)) {
- bta_ag_send_ring(p_scb, tBTA_AG_DATA::kEmpty);
- } else {
- /* else open sco, send ring after sco opened */
- /* HSPv1.2: AG shall not send RING if using in-band ring tone. */
- if (p_scb->peer_version >= HSP_VERSION_1_2) {
- p_scb->post_sco = BTA_AG_POST_SCO_NONE;
- } else {
- p_scb->post_sco = BTA_AG_POST_SCO_RING;
- }
- bta_ag_sco_open(p_scb, tBTA_AG_DATA::kEmpty);
- }
- break;
-
- case BTA_AG_IN_CALL_CONN_RES:
- case BTA_AG_OUT_CALL_ORIG_RES:
- /* if incoming call connected stop ring timer */
- if (result.result == BTA_AG_IN_CALL_CONN_RES) {
- alarm_cancel(p_scb->ring_timer);
- }
-
- if (!(p_scb->features & BTA_AG_FEAT_NOSCO)) {
- /* if audio connected to this scb AND sco is not opened, open sco */
- if (result.data.audio_handle == bta_ag_scb_to_idx(p_scb) &&
- !bta_ag_sco_is_open(p_scb)) {
- bta_ag_sco_open(p_scb, tBTA_AG_DATA::kEmpty);
- } else if (result.data.audio_handle == BTA_AG_HANDLE_NONE &&
- bta_ag_sco_is_open(p_scb)) {
- /* else if no audio at call close sco */
- bta_ag_sco_close(p_scb, tBTA_AG_DATA::kEmpty);
- }
- }
- break;
-
- case BTA_AG_END_CALL_RES:
- alarm_cancel(p_scb->ring_timer);
-
- /* close sco */
- if ((bta_ag_sco_is_open(p_scb) || bta_ag_sco_is_opening(p_scb)) &&
- !(p_scb->features & BTA_AG_FEAT_NOSCO)) {
- bta_ag_sco_close(p_scb, tBTA_AG_DATA::kEmpty);
- } else {
- /* if av got suspended by this call, let it resume. */
- bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
- }
- break;
-
- case BTA_AG_INBAND_RING_RES:
- p_scb->inband_enabled = result.data.state;
- APPL_TRACE_DEBUG("inband_enabled set to %d", p_scb->inband_enabled);
- break;
-
- case BTA_AG_UNAT_RES:
- if (result.data.ok_flag != BTA_AG_OK_ERROR) {
- if (result.data.str[0] != 0) {
- bta_ag_send_result(p_scb, result.result, result.data.str, 0);
- }
-
- if (result.data.ok_flag == BTA_AG_OK_DONE) bta_ag_send_ok(p_scb);
- } else {
- bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR);
- }
- break;
-
- default:
- /* ignore all others */
- break;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_hfp_result
- *
- * Description Handle API result for HFP connections.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_hfp_result(tBTA_AG_SCB* p_scb,
- const tBTA_AG_API_RESULT& result) {
- LOG_DEBUG("HFP connection result:%s", result.ToString().c_str());
-
- switch (result.result) {
- case BTA_AG_SPK_RES:
- case BTA_AG_MIC_RES:
- bta_ag_send_result(p_scb, result.result, nullptr, result.data.num);
- break;
-
- case BTA_AG_IN_CALL_RES: {
- /* tell sys to stop av if any */
- bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
-
- p_scb->clip[0] = 0;
- if (result.data.str[0] != 0) {
- snprintf(p_scb->clip, sizeof(p_scb->clip), "%s", result.data.str);
- }
- /* send callsetup indicator */
- if (p_scb->post_sco == BTA_AG_POST_SCO_CALL_END) {
- /* Need to sent 2 callsetup IND's(Call End and Incoming call) after SCO
- * close. */
- p_scb->post_sco = BTA_AG_POST_SCO_CALL_END_INCALL;
- } else {
- bta_ag_send_call_inds(p_scb, result.result);
-
- /* if sco already opened or no inband ring send ring now */
- if (bta_ag_sco_is_open(p_scb) || !bta_ag_inband_enabled(p_scb) ||
- (p_scb->features & BTA_AG_FEAT_NOSCO) ||
- (result.data.audio_handle != bta_ag_scb_to_idx(p_scb))) {
- bta_ag_send_ring(p_scb, tBTA_AG_DATA::kEmpty);
- } else {
- /* else open sco, send ring after sco opened */
- p_scb->post_sco = BTA_AG_POST_SCO_RING;
- bta_ag_sco_open(p_scb, tBTA_AG_DATA::kEmpty);
- }
- }
- break;
- }
- case BTA_AG_IN_CALL_CONN_RES:
- alarm_cancel(p_scb->ring_timer);
-
- /* if sco not opened and we need to open it, send indicators first
- ** then open sco.
- */
- bta_ag_send_call_inds(p_scb, result.result);
-
- if (!(p_scb->features & BTA_AG_FEAT_NOSCO)) {
- if (result.data.audio_handle == bta_ag_scb_to_idx(p_scb) &&
- !bta_ag_sco_is_open(p_scb)) {
- bta_ag_sco_open(p_scb, tBTA_AG_DATA::kEmpty);
- } else if ((result.data.audio_handle == BTA_AG_HANDLE_NONE) &&
- bta_ag_sco_is_open(p_scb)) {
- bta_ag_sco_close(p_scb, tBTA_AG_DATA::kEmpty);
- }
- }
- break;
-
- case BTA_AG_IN_CALL_HELD_RES:
- alarm_cancel(p_scb->ring_timer);
-
- bta_ag_send_call_inds(p_scb, result.result);
-
- break;
-
- case BTA_AG_OUT_CALL_ORIG_RES:
- bta_ag_send_call_inds(p_scb, result.result);
- if (result.data.audio_handle == bta_ag_scb_to_idx(p_scb) &&
- !(p_scb->features & BTA_AG_FEAT_NOSCO)) {
- bta_ag_sco_open(p_scb, tBTA_AG_DATA::kEmpty);
- }
- break;
-
- case BTA_AG_OUT_CALL_ALERT_RES:
- /* send indicators */
- bta_ag_send_call_inds(p_scb, result.result);
- if (result.data.audio_handle == bta_ag_scb_to_idx(p_scb) &&
- !(p_scb->features & BTA_AG_FEAT_NOSCO)) {
- bta_ag_sco_open(p_scb, tBTA_AG_DATA::kEmpty);
- }
- break;
-
- case BTA_AG_MULTI_CALL_RES:
- /* open SCO at SLC for this three way call */
- APPL_TRACE_DEBUG("Headset Connected in three way call");
- if (!(p_scb->features & BTA_AG_FEAT_NOSCO)) {
- if (result.data.audio_handle == bta_ag_scb_to_idx(p_scb)) {
- bta_ag_sco_open(p_scb, tBTA_AG_DATA::kEmpty);
- } else if (result.data.audio_handle == BTA_AG_HANDLE_NONE) {
- bta_ag_sco_close(p_scb, tBTA_AG_DATA::kEmpty);
- }
- }
- break;
-
- case BTA_AG_OUT_CALL_CONN_RES:
- /* send indicators */
- bta_ag_send_call_inds(p_scb, result.result);
-
- /* open or close sco */
- if (!(p_scb->features & BTA_AG_FEAT_NOSCO)) {
- if (result.data.audio_handle == bta_ag_scb_to_idx(p_scb)) {
- bta_ag_sco_open(p_scb, tBTA_AG_DATA::kEmpty);
- } else if (result.data.audio_handle == BTA_AG_HANDLE_NONE) {
- bta_ag_sco_close(p_scb, tBTA_AG_DATA::kEmpty);
- }
- }
- break;
-
- case BTA_AG_CALL_CANCEL_RES:
- /* send indicators */
- bta_ag_send_call_inds(p_scb, result.result);
- break;
-
- case BTA_AG_END_CALL_RES:
- alarm_cancel(p_scb->ring_timer);
-
- /* if sco open, close sco then send indicator values */
- if ((bta_ag_sco_is_open(p_scb) || bta_ag_sco_is_opening(p_scb)) &&
- !(p_scb->features & BTA_AG_FEAT_NOSCO)) {
- p_scb->post_sco = BTA_AG_POST_SCO_CALL_END;
- bta_ag_sco_close(p_scb, tBTA_AG_DATA::kEmpty);
- } else if (p_scb->post_sco == BTA_AG_POST_SCO_CALL_END_INCALL) {
- /* sco closing for outgoing call because of incoming call */
- /* Send only callsetup end indicator after sco close */
- p_scb->post_sco = BTA_AG_POST_SCO_CALL_END;
- } else {
- bta_ag_send_call_inds(p_scb, result.result);
-
- /* if av got suspended by this call, let it resume. */
- bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
- }
- break;
-
- case BTA_AG_INBAND_RING_RES:
- p_scb->inband_enabled = result.data.state;
- APPL_TRACE_DEBUG("inband_enabled set to %d", p_scb->inband_enabled);
- bta_ag_send_result(p_scb, result.result, nullptr, result.data.state);
- break;
-
- case BTA_AG_CIND_RES:
- /* store local values */
- p_scb->call_ind = result.data.str[0] - '0';
- p_scb->callsetup_ind = result.data.str[2] - '0';
- p_scb->service_ind = result.data.str[4] - '0';
- p_scb->signal_ind = result.data.str[6] - '0';
- p_scb->roam_ind = result.data.str[8] - '0';
- p_scb->battchg_ind = result.data.str[10] - '0';
- p_scb->callheld_ind = result.data.str[12] - '0';
- APPL_TRACE_DEBUG("cind call:%d callsetup:%d", p_scb->call_ind,
- p_scb->callsetup_ind);
-
- bta_ag_send_result(p_scb, result.result, result.data.str, 0);
- bta_ag_send_ok(p_scb);
- break;
-
- case BTA_AG_BINP_RES:
- case BTA_AG_CNUM_RES:
- case BTA_AG_CLCC_RES:
- case BTA_AG_COPS_RES:
- if (result.data.ok_flag != BTA_AG_OK_ERROR) {
- if (result.data.str[0] != 0) {
- bta_ag_send_result(p_scb, result.result, result.data.str, 0);
- }
-
- if (result.data.ok_flag == BTA_AG_OK_DONE) bta_ag_send_ok(p_scb);
- } else {
- bta_ag_send_error(p_scb, result.data.errcode);
- }
- break;
-
- case BTA_AG_UNAT_RES: {
- if (result.data.ok_flag != BTA_AG_OK_ERROR) {
- if (result.data.str[0] != 0) {
- tBTA_AG_API_RESULT result_copy(result);
- bta_ag_process_unat_res(result_copy.data.str);
- APPL_TRACE_DEBUG("BTA_AG_RES :%s", result_copy.data.str);
- bta_ag_send_result(p_scb, result_copy.result, result_copy.data.str,
- 0);
- }
- if (result.data.ok_flag == BTA_AG_OK_DONE) {
- bta_ag_send_ok(p_scb);
- }
- } else {
- bta_ag_send_error(p_scb, result.data.errcode);
- }
- break;
- }
-
- case BTA_AG_CALL_WAIT_RES:
- if (p_scb->ccwa_enabled) {
- bta_ag_send_result(p_scb, result.result, result.data.str, 0);
- }
- bta_ag_send_call_inds(p_scb, result.result);
- break;
-
- case BTA_AG_IND_RES:
- bta_ag_send_ind(p_scb, result.data.ind.id, result.data.ind.value, false);
- break;
-
- case BTA_AG_IND_RES_ON_DEMAND:
- bta_ag_send_ind(p_scb, result.data.ind.id, result.data.ind.value, true);
- break;
-
- case BTA_AG_BVRA_RES:
- bta_ag_send_result(p_scb, result.result, nullptr, result.data.state);
- break;
-
- case BTA_AG_BTRH_RES:
- if (result.data.ok_flag != BTA_AG_OK_ERROR) {
- /* Don't respond to read if not in response & hold state */
- if (result.data.num != BTA_AG_BTRH_NO_RESP) {
- bta_ag_send_result(p_scb, result.result, nullptr, result.data.num);
- }
-
- /* In case of a response to a read request we need to send OK */
- if (result.data.ok_flag == BTA_AG_OK_DONE) {
- bta_ag_send_ok(p_scb);
- }
- } else {
- bta_ag_send_error(p_scb, result.data.errcode);
- }
- break;
-
- case BTA_AG_BIND_RES: {
- /* Find whether ind_id is supported by local device or not */
- int local_index = bta_ag_find_hf_ind_by_id(p_scb->local_hf_indicators,
- BTA_AG_MAX_NUM_LOCAL_HF_IND,
- result.data.ind.id);
- if (local_index == -1) {
- APPL_TRACE_WARNING("%s Invalid HF Indicator ID %d", __func__,
- result.data.ind.id);
- return;
- }
-
- /* Find whether ind_id is supported by peer device or not */
- int peer_index = bta_ag_find_hf_ind_by_id(p_scb->peer_hf_indicators,
- BTA_AG_MAX_NUM_PEER_HF_IND,
- result.data.ind.id);
- if (peer_index == -1) {
- APPL_TRACE_WARNING("%s Invalid HF Indicator ID %d", __func__,
- result.data.ind.id);
- return;
- } else {
- /* If the current state is different from the one upper layer request
- change current state and send out the result */
- if (p_scb->local_hf_indicators[local_index].is_enable !=
- result.data.ind.on_demand) {
- char buffer[BTA_AG_AT_MAX_LEN] = {0};
- char* p = buffer;
-
- p_scb->local_hf_indicators[local_index].is_enable =
- result.data.ind.on_demand;
- p += utl_itoa(result.data.ind.id, p);
- *p++ = ',';
- p += utl_itoa(p_scb->local_hf_indicators[local_index].is_enable, p);
-
- bta_ag_send_result(p_scb, result.result, buffer, 0);
- } else {
- APPL_TRACE_DEBUG(
- "%s HF Indicator %d already %s", result.data.ind.id,
- (result.data.ind.on_demand) ? "Enabled" : "Disabled");
- }
- }
- break;
- }
- default:
- break;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_result
- *
- * Description Handle API result.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_result(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- if (p_scb->conn_service == BTA_AG_HSP) {
- bta_ag_hsp_result(p_scb, data.api_result);
- } else {
- bta_ag_hfp_result(p_scb, data.api_result);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_send_bcs
- *
- * Description Send +BCS AT command to peer.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_send_bcs(tBTA_AG_SCB* p_scb) {
- uint16_t codec_uuid;
-
- if (p_scb->codec_fallback) {
- codec_uuid = UUID_CODEC_CVSD;
- } else {
- switch (p_scb->sco_codec) {
- case BTM_SCO_CODEC_NONE:
- codec_uuid = UUID_CODEC_CVSD;
- break;
- case BTM_SCO_CODEC_CVSD:
- codec_uuid = UUID_CODEC_CVSD;
- break;
- case BTM_SCO_CODEC_MSBC:
- codec_uuid = UUID_CODEC_MSBC;
- break;
- default:
- APPL_TRACE_ERROR("bta_ag_send_bcs: unknown codec %d, use CVSD",
- p_scb->sco_codec);
- codec_uuid = UUID_CODEC_CVSD;
- break;
- }
- }
-
- /* send +BCS */
- APPL_TRACE_DEBUG("send +BCS codec is %d", codec_uuid);
- bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_BCS, nullptr, codec_uuid);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_send_ring
- *
- * Description Send RING result code to peer.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_send_ring(tBTA_AG_SCB* p_scb,
- UNUSED_ATTR const tBTA_AG_DATA& data) {
- if ((p_scb->conn_service == BTA_AG_HFP) &&
- p_scb->callsetup_ind != BTA_AG_CALLSETUP_INCOMING) {
- LOG(WARNING) << __func__ << ": don't send RING, conn_service="
- << std::to_string(p_scb->conn_service)
- << ", callsetup_ind=" << std::to_string(p_scb->callsetup_ind);
- return;
- }
- /* send RING */
- bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_RING, nullptr, 0);
-
- /* if HFP and clip enabled and clip data send CLIP */
- if (p_scb->conn_service == BTA_AG_HFP && p_scb->clip_enabled &&
- p_scb->clip[0] != 0) {
- bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_CLIP, p_scb->clip, 0);
- }
-
- bta_sys_start_timer(p_scb->ring_timer, BTA_AG_RING_TIMEOUT_MS,
- BTA_AG_RING_TIMEOUT_EVT, bta_ag_scb_to_idx(p_scb));
-}
diff --git a/bta/ag/bta_ag_int.h b/bta/ag/bta_ag_int.h
deleted file mode 100644
index b1dd804..0000000
--- a/bta/ag/bta_ag_int.h
+++ /dev/null
@@ -1,411 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the private interface file for the BTA audio gateway.
- *
- ******************************************************************************/
-#ifndef BTA_AG_INT_H
-#define BTA_AG_INT_H
-
-#include <cstdint>
-
-#include "bta/ag/bta_ag_at.h"
-#include "bta/include/bta_ag_api.h"
-#include "bta/include/bta_api.h"
-#include "bta/sys/bta_sys.h"
-#include "stack/include/bt_hdr.h"
-#include "types/raw_address.h"
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-/* Time to wait for retry in case of collision */
-#ifndef BTA_AG_COLLISION_TIMEOUT_MS
-#define BTA_AG_COLLISION_TIMEOUT_MS (2 * 1000) /* 2 seconds */
-#endif
-
-/* RFCOMM MTU SIZE */
-#define BTA_AG_MTU 256
-
-/* Max number of peer and local HF indicators */
-#define BTA_AG_MAX_NUM_PEER_HF_IND 20
-#define BTA_AG_MAX_NUM_LOCAL_HF_IND 4
-
-/* Internal profile indexes */
-#define BTA_AG_HSP 0 /* index for HSP */
-#define BTA_AG_HFP 1 /* index for HFP */
-#define BTA_AG_NUM_IDX 2 /* number of profile indexes */
-
-/* profile role for connection */
-#define BTA_AG_ACP 0 /* accepted connection */
-#define BTA_AG_INT 1 /* initiating connection */
-
-#define BTA_AG_SDP_FEAT_SPEC \
- (BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECNR | BTA_AG_FEAT_VREC | \
- BTA_AG_FEAT_INBAND | BTA_AG_FEAT_VTAG)
-
-/* Timeout for alarm in 2018 toyota camry carkit workaround */
-#define BTA_AG_BIND_TIMEOUT_MS 500
-
-enum {
- /* these events are handled by the state machine */
- BTA_AG_API_REGISTER_EVT = BTA_SYS_EVT_START(BTA_ID_AG),
- BTA_AG_API_DEREGISTER_EVT,
- BTA_AG_API_OPEN_EVT,
- BTA_AG_API_CLOSE_EVT,
- BTA_AG_API_AUDIO_OPEN_EVT,
- BTA_AG_API_AUDIO_CLOSE_EVT,
- BTA_AG_API_RESULT_EVT,
- BTA_AG_API_SETCODEC_EVT,
- BTA_AG_RFC_OPEN_EVT,
- BTA_AG_RFC_CLOSE_EVT,
- BTA_AG_RFC_SRV_CLOSE_EVT,
- BTA_AG_RFC_DATA_EVT,
- BTA_AG_SCO_OPEN_EVT,
- BTA_AG_SCO_CLOSE_EVT,
- BTA_AG_DISC_ACP_RES_EVT,
- BTA_AG_DISC_INT_RES_EVT,
- BTA_AG_DISC_OK_EVT,
- BTA_AG_DISC_FAIL_EVT,
- BTA_AG_RING_TIMEOUT_EVT,
- BTA_AG_SVC_TIMEOUT_EVT,
- BTA_AG_COLLISION_EVT,
- BTA_AG_MAX_EVT,
-};
-
-/* Actions to perform after a SCO event */
-enum {
- BTA_AG_POST_SCO_NONE, /* no action */
- BTA_AG_POST_SCO_CLOSE_RFC, /* close RFCOMM channel after SCO closes */
- BTA_AG_POST_SCO_RING, /* send RING result code after SCO opens */
- BTA_AG_POST_SCO_CALL_CONN, /* send call indicators after SCO opens/closes */
- BTA_AG_POST_SCO_CALL_ORIG, /* send call indicators after SCO closes */
- BTA_AG_POST_SCO_CALL_END, /* send call indicators after SCO closes */
- BTA_AG_POST_SCO_CALL_END_INCALL /* send call indicators for end call &
- incoming call after SCO closes */
-};
-
-/* sco states */
-typedef enum : uint8_t {
- BTA_AG_SCO_SHUTDOWN_ST, /* no sco listening, all sco connections closed */
- BTA_AG_SCO_LISTEN_ST, /* sco listening */
- BTA_AG_SCO_CODEC_ST, /* sco codec negotiation */
- BTA_AG_SCO_OPENING_ST, /* sco connection opening */
- BTA_AG_SCO_OPEN_CL_ST, /* opening sco connection being closed */
- BTA_AG_SCO_OPEN_XFER_ST, /* opening sco connection being transferred */
- BTA_AG_SCO_OPEN_ST, /* sco open */
- BTA_AG_SCO_CLOSING_ST, /* sco closing */
- BTA_AG_SCO_CLOSE_OP_ST, /* closing sco being opened */
- BTA_AG_SCO_CLOSE_XFER_ST, /* closing sco being transferred */
- BTA_AG_SCO_SHUTTING_ST /* sco shutting down */
-} tBTA_AG_SCO;
-
-/*****************************************************************************
- * Data types
- ****************************************************************************/
-
-/* data type for BTA_AG_API_REGISTER_EVT */
-typedef struct {
- char p_name[2][BTA_SERVICE_NAME_LEN + 1];
- tBTA_SERVICE_MASK services;
- tBTA_AG_FEAT features;
- uint8_t app_id;
-} tBTA_AG_API_REGISTER;
-
-/* data type for BTA_AG_API_OPEN_EVT */
-typedef struct {
- RawAddress bd_addr;
-} tBTA_AG_API_OPEN;
-
-/* data type for BTA_AG_API_RESULT_EVT */
-typedef struct {
- tBTA_AG_RES result;
- tBTA_AG_RES_DATA data;
- std::string ToString() const {
- return base::StringPrintf("result:%s", bta_ag_result_text(result).c_str());
- }
-} tBTA_AG_API_RESULT;
-
-/* data type for BTA_AG_API_SETCODEC_EVT */
-typedef struct {
- tBTA_AG_PEER_CODEC codec;
-} tBTA_AG_API_SETCODEC;
-
-/* data type for BTA_AG_DISC_RESULT_EVT */
-typedef struct {
- uint16_t status;
-} tBTA_AG_DISC_RESULT;
-
-/* data type for RFCOMM events */
-typedef struct {
- uint16_t port_handle;
-} tBTA_AG_RFC;
-
-/* union of all event datatypes */
-union tBTA_AG_DATA {
- tBTA_AG_API_REGISTER api_register;
- tBTA_AG_API_OPEN api_open;
- tBTA_AG_API_RESULT api_result;
- tBTA_AG_API_SETCODEC api_setcodec;
- tBTA_AG_DISC_RESULT disc_result;
- tBTA_AG_RFC rfc;
- static const tBTA_AG_DATA kEmpty;
-
- /**
- * Check if two tBTA_AG_DATA are equal in memory
- *
- * @param rhs other tBTA_AG_DATA
- * @return true if both unions are equal in memory
- */
- bool operator==(const tBTA_AG_DATA& rhs) const {
- return (std::memcmp(this, &rhs, sizeof(tBTA_AG_DATA)) == 0);
- }
-
- /**
- * Check if this union is empty by comparing it to the kEmpty constant
- *
- * @return true if this union is empty
- */
- bool IsEmpty() const { return *this == kEmpty; }
-};
-
-/* type for each profile */
-typedef struct {
- uint32_t sdp_handle;
- uint8_t scn;
-} tBTA_AG_PROFILE;
-
-typedef enum {
- BTA_AG_SCO_MSBC_SETTINGS_T2 = 0, /* preferred/default when codec is mSBC */
- BTA_AG_SCO_MSBC_SETTINGS_T1,
-} tBTA_AG_SCO_MSBC_SETTINGS;
-
-/* type for each service control block */
-struct tBTA_AG_SCB {
- char clip[BTA_AG_AT_MAX_LEN + 1]; /* number string used for CLIP */
- uint16_t serv_handle[BTA_AG_NUM_IDX]; /* RFCOMM server handles */
- tBTA_AG_AT_CB at_cb; /* AT command interpreter */
- RawAddress peer_addr; /* peer bd address */
- tSDP_DISCOVERY_DB* p_disc_db; /* pointer to discovery database */
- tBTA_SERVICE_MASK reg_services; /* services specified in register API */
- tBTA_SERVICE_MASK open_services; /* services specified in open API */
- uint16_t conn_handle; /* RFCOMM handle of connected service */
- tBTA_AG_FEAT features; /* features registered by application */
- tBTA_AG_FEAT masked_features; /* local BRSF features for this connection */
- tBTA_AG_PEER_FEAT peer_features; /* peer device features */
- uint16_t peer_sdp_features; /* peer device SDP features */
- uint16_t peer_version; /* profile version of peer device */
- uint16_t hsp_version; /* HSP profile version before SDP */
- uint16_t sco_idx; /* SCO handle */
- bool in_use; /* scb in use */
- bool dealloc; /* true if service shutting down */
- bool clip_enabled; /* set to true if HF enables CLIP reporting */
- bool ccwa_enabled; /* set to true if HF enables CCWA reporting */
- bool cmer_enabled; /* set to true if HF enables CMER reporting */
- bool cmee_enabled; /* set to true if HF enables CME ERROR reporting */
- bool inband_enabled; /* set to true if inband ring enabled */
- bool svc_conn; /* set to true when service level connection up */
- uint8_t state; /* state machine state */
- uint8_t conn_service; /* connected service */
- uint8_t peer_scn; /* peer scn */
- uint8_t app_id; /* application id */
- uint8_t role; /* initiator/acceptor role */
- uint8_t post_sco; /* action to perform after sco event */
- uint8_t call_ind; /* CIEV call indicator value */
- uint8_t callsetup_ind; /* CIEV callsetup indicator value */
- uint8_t service_ind; /* CIEV service indicator value */
- uint8_t signal_ind; /* CIEV signal indicator value */
- uint8_t roam_ind; /* CIEV roam indicator value */
- uint8_t battchg_ind; /* CIEV battery charge indicator value */
- uint8_t callheld_ind; /* CIEV call held indicator value */
- uint32_t bia_masked_out; /* indicators HF does not want us to send */
- alarm_t* bind_timer; /* Timer for toyota camry 2018 carkit workaround */
- alarm_t* collision_timer;
- alarm_t* ring_timer;
- alarm_t* codec_negotiation_timer;
- bool received_at_bac; /* indicate AT+BAC is received at least once */
- tBTA_AG_PEER_CODEC peer_codecs; /* codecs for eSCO supported by the peer */
- tBTA_AG_PEER_CODEC sco_codec; /* codec to be used for eSCO connection */
- tBTA_AG_PEER_CODEC
- inuse_codec; /* codec being used for the current SCO connection */
- bool codec_updated; /* set to true whenever the app updates codec type */
- bool codec_fallback; /* If sco nego fails for mSBC, fallback to CVSD */
- tBTA_AG_SCO_MSBC_SETTINGS
- codec_msbc_settings; /* settings to be used for the impending eSCO */
-
- tBTA_AG_HF_IND
- peer_hf_indicators[BTA_AG_MAX_NUM_PEER_HF_IND]; /* Peer supported
- HF indicators */
- tBTA_AG_HF_IND
- local_hf_indicators[BTA_AG_MAX_NUM_LOCAL_HF_IND]; /* Local supported
- HF indicators */
-
- std::string ToString() const {
- return base::StringPrintf(
- "codec_updated=%d, codec_fallback=%d, "
- "sco_codec=%d, peer_codec=%d, msbc_settings=%d, device=%s",
- codec_updated, codec_fallback, sco_codec, peer_codecs,
- codec_msbc_settings, peer_addr.ToString().c_str());
- }
-};
-
-/* type for sco data */
-typedef struct {
- tBTM_ESCO_CONN_REQ_EVT_DATA conn_data; /* SCO data for pending conn request */
- tBTA_AG_SCB* p_curr_scb; /* SCB associated with SCO connection */
- tBTA_AG_SCB* p_xfer_scb; /* SCB associated with SCO transfer */
- uint16_t cur_idx; /* SCO handle */
- tBTA_AG_SCO state; /* SCO state variable */
- bool is_local; /* SCO connection initiated locally or remotely */
-} tBTA_AG_SCO_CB;
-
-/* type for AG control block */
-typedef struct {
- tBTA_AG_SCB scb[BTA_AG_MAX_NUM_CLIENTS]; /* service control blocks */
- tBTA_AG_PROFILE profile[BTA_AG_NUM_IDX]; /* profile-specific data */
- tBTA_AG_SCO_CB sco; /* SCO data */
- tBTA_AG_CBACK* p_cback; /* application callback */
-} tBTA_AG_CB;
-
-/*****************************************************************************
- * Global data
- ****************************************************************************/
-
-/* constant lookup tables */
-extern const uint16_t bta_ag_uuid[BTA_AG_NUM_IDX];
-extern const uint8_t bta_ag_sec_id[BTA_AG_NUM_IDX];
-extern const tBTA_AG_AT_CMD* bta_ag_at_tbl[BTA_AG_NUM_IDX];
-
-/* control block declaration */
-extern tBTA_AG_CB bta_ag_cb;
-
-/* config struct */
-extern const tBTA_AG_CFG* p_bta_ag_cfg;
-extern const tBTA_AG_HF_IND bta_ag_local_hf_ind_cfg[];
-
-/*****************************************************************************
- * Function prototypes
- ****************************************************************************/
-bool bta_ag_hdl_event(BT_HDR_RIGID* p_msg);
-
-/* API functions */
-extern void bta_ag_api_enable(tBTA_AG_CBACK* p_cback);
-extern void bta_ag_api_disable();
-extern void bta_ag_api_set_active_device(const RawAddress& new_active_device);
-extern void bta_ag_api_register(tBTA_SERVICE_MASK services,
- tBTA_AG_FEAT features,
- const std::vector<std::string>& service_names,
- uint8_t app_id);
-extern void bta_ag_api_result(uint16_t handle, tBTA_AG_RES result,
- const tBTA_AG_RES_DATA& result_data);
-
-/* main functions */
-extern void bta_ag_scb_dealloc(tBTA_AG_SCB* p_scb);
-extern uint16_t bta_ag_scb_to_idx(tBTA_AG_SCB* p_scb);
-extern tBTA_AG_SCB* bta_ag_scb_by_idx(uint16_t idx);
-extern uint8_t bta_ag_service_to_idx(tBTA_SERVICE_MASK services);
-extern uint16_t bta_ag_idx_by_bdaddr(const RawAddress* peer_addr);
-extern bool bta_ag_other_scb_open(tBTA_AG_SCB* p_curr_scb);
-extern bool bta_ag_scb_open(tBTA_AG_SCB* p_curr_scb);
-extern void bta_ag_sm_execute(tBTA_AG_SCB* p_scb, uint16_t event,
- const tBTA_AG_DATA& data);
-extern void bta_ag_sm_execute_by_handle(uint16_t handle, uint16_t event,
- const tBTA_AG_DATA& data);
-extern void bta_ag_collision_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
- uint8_t app_id, const RawAddress& peer_addr);
-extern void bta_ag_resume_open(tBTA_AG_SCB* p_scb);
-
-/* SDP functions */
-extern bool bta_ag_add_record(uint16_t service_uuid, const char* p_service_name,
- uint8_t scn, tBTA_AG_FEAT features,
- uint32_t sdp_handle);
-extern void bta_ag_create_records(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_del_records(tBTA_AG_SCB* p_scb);
-extern bool bta_ag_sdp_find_attr(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service);
-extern void bta_ag_do_disc(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service);
-extern void bta_ag_free_db(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-
-/* RFCOMM functions */
-extern void bta_ag_start_servers(tBTA_AG_SCB* p_scb,
- tBTA_SERVICE_MASK services);
-extern void bta_ag_close_servers(tBTA_AG_SCB* p_scb,
- tBTA_SERVICE_MASK services);
-extern bool bta_ag_is_server_closed(tBTA_AG_SCB* p_scb);
-extern void bta_ag_rfc_do_close(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_rfc_do_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-
-/* SCO functions */
-extern bool bta_ag_sco_is_active_device(const RawAddress& bd_addr);
-extern bool bta_ag_sco_is_open(tBTA_AG_SCB* p_scb);
-extern bool bta_ag_sco_is_opening(tBTA_AG_SCB* p_scb);
-extern void bta_ag_sco_conn_rsp(tBTA_AG_SCB* p_scb,
- tBTM_ESCO_CONN_REQ_EVT_DATA* data);
-
-/* AT command functions */
-extern void bta_ag_at_hsp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd,
- uint8_t arg_type, char* p_arg, char* p_end,
- int16_t int_arg);
-extern void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd,
- uint8_t arg_type, char* p_arg, char* p_end,
- int16_t int_arg);
-extern void bta_ag_at_err_cback(tBTA_AG_SCB* p_scb, bool unknown,
- const char* p_arg);
-extern bool bta_ag_inband_enabled(tBTA_AG_SCB* p_scb);
-extern void bta_ag_send_call_inds(tBTA_AG_SCB* p_scb, tBTA_AG_RES result);
-
-/* Action functions */
-extern void bta_ag_register(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_deregister(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_start_dereg(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_start_close(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_start_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_disc_int_res(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_disc_acp_res(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_disc_fail(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_open_fail(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_rfc_fail(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_rfc_close(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_rfc_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_rfc_acp_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_rfc_data(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_sco_listen(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_sco_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_sco_close(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_sco_shutdown(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_sco_conn_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_sco_conn_close(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_post_sco_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_post_sco_close(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_svc_conn_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_result(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_setcodec(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_send_ring(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
-extern void bta_ag_handle_collision(tBTA_AG_SCB* p_scb,
- const tBTA_AG_DATA& data);
-
-/* Internal utility functions */
-extern void bta_ag_sco_codec_nego(tBTA_AG_SCB* p_scb, bool result);
-extern void bta_ag_codec_negotiate(tBTA_AG_SCB* p_scb);
-extern void bta_ag_send_bcs(tBTA_AG_SCB* p_scb);
-extern void bta_ag_set_sco_allowed(bool value);
-extern const RawAddress& bta_ag_get_active_device();
-extern void bta_clear_active_device();
-
-#endif /* BTA_AG_INT_H */
diff --git a/bta/ag/bta_ag_main.cc b/bta/ag/bta_ag_main.cc
deleted file mode 100644
index eb7e9d9..0000000
--- a/bta/ag/bta_ag_main.cc
+++ /dev/null
@@ -1,780 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the main implementation file for the BTA audio gateway.
- *
- ******************************************************************************/
-
-#include <string>
-#include <vector>
-
-#include "bta/ag/bta_ag_int.h"
-#include "main/shim/dumpsys.h"
-#include "osi/include/alarm.h"
-#include "osi/include/compat.h"
-#include "osi/include/log.h"
-#include "osi/include/osi.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/btm_api.h"
-#include "types/raw_address.h"
-
-#include <base/logging.h>
-
-/*****************************************************************************
- * Constants and types
- ****************************************************************************/
-/* state machine states */
-enum { BTA_AG_INIT_ST, BTA_AG_OPENING_ST, BTA_AG_OPEN_ST, BTA_AG_CLOSING_ST };
-
-#define CASE_RETURN_STR(const) \
- case const: \
- return #const;
-
-static const char* bta_ag_res_str(tBTA_AG_RES result) {
- switch (result) {
- CASE_RETURN_STR(BTA_AG_SPK_RES)
- CASE_RETURN_STR(BTA_AG_MIC_RES)
- CASE_RETURN_STR(BTA_AG_INBAND_RING_RES)
- CASE_RETURN_STR(BTA_AG_CIND_RES)
- CASE_RETURN_STR(BTA_AG_BINP_RES)
- CASE_RETURN_STR(BTA_AG_IND_RES)
- CASE_RETURN_STR(BTA_AG_BVRA_RES)
- CASE_RETURN_STR(BTA_AG_CNUM_RES)
- CASE_RETURN_STR(BTA_AG_BTRH_RES)
- CASE_RETURN_STR(BTA_AG_CLCC_RES)
- CASE_RETURN_STR(BTA_AG_COPS_RES)
- CASE_RETURN_STR(BTA_AG_IN_CALL_RES)
- CASE_RETURN_STR(BTA_AG_IN_CALL_CONN_RES)
- CASE_RETURN_STR(BTA_AG_CALL_WAIT_RES)
- CASE_RETURN_STR(BTA_AG_OUT_CALL_ORIG_RES)
- CASE_RETURN_STR(BTA_AG_OUT_CALL_ALERT_RES)
- CASE_RETURN_STR(BTA_AG_OUT_CALL_CONN_RES)
- CASE_RETURN_STR(BTA_AG_CALL_CANCEL_RES)
- CASE_RETURN_STR(BTA_AG_END_CALL_RES)
- CASE_RETURN_STR(BTA_AG_IN_CALL_HELD_RES)
- CASE_RETURN_STR(BTA_AG_UNAT_RES)
- CASE_RETURN_STR(BTA_AG_MULTI_CALL_RES)
- CASE_RETURN_STR(BTA_AG_BIND_RES)
- CASE_RETURN_STR(BTA_AG_IND_RES_ON_DEMAND)
- default:
- return "Unknown AG Result";
- }
-}
-
-static const char* bta_ag_evt_str(uint16_t event) {
- switch (event) {
- CASE_RETURN_STR(BTA_AG_API_REGISTER_EVT)
- CASE_RETURN_STR(BTA_AG_API_DEREGISTER_EVT)
- CASE_RETURN_STR(BTA_AG_API_OPEN_EVT)
- CASE_RETURN_STR(BTA_AG_API_CLOSE_EVT)
- CASE_RETURN_STR(BTA_AG_API_AUDIO_OPEN_EVT)
- CASE_RETURN_STR(BTA_AG_API_AUDIO_CLOSE_EVT)
- CASE_RETURN_STR(BTA_AG_API_RESULT_EVT)
- CASE_RETURN_STR(BTA_AG_API_SETCODEC_EVT)
- CASE_RETURN_STR(BTA_AG_RFC_OPEN_EVT)
- CASE_RETURN_STR(BTA_AG_RFC_CLOSE_EVT)
- CASE_RETURN_STR(BTA_AG_RFC_SRV_CLOSE_EVT)
- CASE_RETURN_STR(BTA_AG_RFC_DATA_EVT)
- CASE_RETURN_STR(BTA_AG_SCO_OPEN_EVT)
- CASE_RETURN_STR(BTA_AG_SCO_CLOSE_EVT)
- CASE_RETURN_STR(BTA_AG_DISC_ACP_RES_EVT)
- CASE_RETURN_STR(BTA_AG_DISC_INT_RES_EVT)
- CASE_RETURN_STR(BTA_AG_DISC_OK_EVT)
- CASE_RETURN_STR(BTA_AG_DISC_FAIL_EVT)
- CASE_RETURN_STR(BTA_AG_RING_TIMEOUT_EVT)
- CASE_RETURN_STR(BTA_AG_SVC_TIMEOUT_EVT)
- CASE_RETURN_STR(BTA_AG_COLLISION_EVT)
- default:
- return "Unknown AG Event";
- }
-}
-
-static const char* bta_ag_state_str(uint8_t state) {
- switch (state) {
- CASE_RETURN_STR(BTA_AG_INIT_ST)
- CASE_RETURN_STR(BTA_AG_OPENING_ST)
- CASE_RETURN_STR(BTA_AG_OPEN_ST)
- CASE_RETURN_STR(BTA_AG_CLOSING_ST)
- default:
- return "Unknown AG State";
- }
-}
-
-/*****************************************************************************
- * Global data
- ****************************************************************************/
-
-/* AG control block */
-tBTA_AG_CB bta_ag_cb;
-const tBTA_AG_DATA tBTA_AG_DATA::kEmpty = {};
-
-/*******************************************************************************
- *
- * Function bta_ag_scb_alloc
- *
- * Description Allocate an AG service control block.
- *
- *
- * Returns pointer to the scb, or NULL if none could be allocated.
- *
- ******************************************************************************/
-static tBTA_AG_SCB* bta_ag_scb_alloc(void) {
- tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0];
- int i;
-
- for (i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++, p_scb++) {
- if (!p_scb->in_use) {
- /* initialize variables */
- p_scb->in_use = true;
- p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
- p_scb->received_at_bac = false;
- p_scb->codec_updated = false;
- p_scb->codec_fallback = false;
- p_scb->peer_codecs = BTM_SCO_CODEC_CVSD;
- p_scb->sco_codec = BTM_SCO_CODEC_CVSD;
- p_scb->peer_version = HFP_HSP_VERSION_UNKNOWN;
- p_scb->hsp_version = HSP_VERSION_1_2;
- p_scb->peer_sdp_features = 0;
- /* set up timers */
- p_scb->ring_timer = alarm_new("bta_ag.scb_ring_timer");
- p_scb->collision_timer = alarm_new("bta_ag.scb_collision_timer");
- p_scb->codec_negotiation_timer =
- alarm_new("bta_ag.scb_codec_negotiation_timer");
- /* set eSCO mSBC setting to T2 as the preferred */
- p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
- APPL_TRACE_DEBUG("bta_ag_scb_alloc %d", bta_ag_scb_to_idx(p_scb));
- break;
- }
- }
-
- if (i == BTA_AG_MAX_NUM_CLIENTS) {
- /* out of scbs */
- p_scb = nullptr;
- APPL_TRACE_WARNING("%s: Out of scbs", __func__);
- }
- return p_scb;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_scb_dealloc
- *
- * Description Deallocate a service control block.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_scb_dealloc(tBTA_AG_SCB* p_scb) {
- uint8_t idx;
- bool allocated = false;
-
- APPL_TRACE_DEBUG("bta_ag_scb_dealloc %d", bta_ag_scb_to_idx(p_scb));
-
- /* stop and free timers */
- alarm_free(p_scb->ring_timer);
- alarm_free(p_scb->codec_negotiation_timer);
- alarm_free(p_scb->collision_timer);
-
- /* initialize control block */
- *p_scb = {};
- p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
-
- /* If all scbs are deallocated, callback with disable event */
- if (!bta_sys_is_register(BTA_ID_AG)) {
- for (idx = 0; idx < BTA_AG_MAX_NUM_CLIENTS; idx++) {
- if (bta_ag_cb.scb[idx].in_use) {
- allocated = true;
- break;
- }
- }
-
- if (!allocated) {
- (*bta_ag_cb.p_cback)(BTA_AG_DISABLE_EVT, nullptr);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_scb_to_idx
- *
- * Description Given a pointer to an scb, return its index.
- *
- *
- * Returns Index of scb starting from 1
- *
- ******************************************************************************/
-uint16_t bta_ag_scb_to_idx(tBTA_AG_SCB* p_scb) {
- /* use array arithmetic to determine index */
- return static_cast<uint16_t>(p_scb - bta_ag_cb.scb + 1);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_scb_by_idx
- *
- * Description Given an scb index return pointer to scb.
- *
- *
- * Returns Pointer to scb or NULL if not allocated.
- *
- ******************************************************************************/
-tBTA_AG_SCB* bta_ag_scb_by_idx(uint16_t idx) {
- tBTA_AG_SCB* p_scb;
-
- /* verify index */
- if (idx > 0 && idx <= BTA_AG_MAX_NUM_CLIENTS) {
- p_scb = &bta_ag_cb.scb[idx - 1];
- if (!p_scb->in_use) {
- p_scb = nullptr;
- APPL_TRACE_WARNING("ag scb idx %d not allocated", idx);
- }
- } else {
- p_scb = nullptr;
- APPL_TRACE_DEBUG("ag scb idx %d out of range", idx);
- }
- return p_scb;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_service_to_idx
- *
- * Description Given a BTA service mask convert to profile index.
- *
- *
- * Returns Profile ndex of scb.
- *
- ******************************************************************************/
-uint8_t bta_ag_service_to_idx(tBTA_SERVICE_MASK services) {
- if (services & BTA_HFP_SERVICE_MASK) {
- return BTA_AG_HFP;
- } else {
- return BTA_AG_HSP;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_idx_by_bdaddr
- *
- * Description Find SCB associated with peer BD address.
- *
- *
- * Returns Index of SCB or zero if none found.
- *
- ******************************************************************************/
-uint16_t bta_ag_idx_by_bdaddr(const RawAddress* peer_addr) {
- tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0];
- if (peer_addr != nullptr) {
- for (uint16_t i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++, p_scb++) {
- if (p_scb->in_use && *peer_addr == p_scb->peer_addr) {
- return (i + 1);
- }
- }
- }
-
- /* no scb found */
- APPL_TRACE_WARNING("No ag scb for peer addr");
- return 0;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_other_scb_open
- *
- * Description Check whether any other scb is in open state.
- *
- *
- * Returns true if another scb is in open state, false otherwise.
- *
- ******************************************************************************/
-bool bta_ag_other_scb_open(tBTA_AG_SCB* p_curr_scb) {
- tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0];
- for (int i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++, p_scb++) {
- if (p_scb->in_use && p_scb != p_curr_scb &&
- p_scb->state == BTA_AG_OPEN_ST) {
- return true;
- }
- }
- /* no other scb found */
- APPL_TRACE_DEBUG("No other ag scb open");
- return false;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_scb_open
- *
- * Description Check whether given scb is in open state.
- *
- *
- * Returns true if scb is in open state, false otherwise.
- *
- ******************************************************************************/
-bool bta_ag_scb_open(tBTA_AG_SCB* p_curr_scb) {
- return p_curr_scb && p_curr_scb->in_use &&
- p_curr_scb->state == BTA_AG_OPEN_ST;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_collision_cback
- *
- * Description Get notified about collision.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status, uint8_t id,
- UNUSED_ATTR uint8_t app_id,
- const RawAddress& peer_addr) {
- /* Check if we have opening scb for the peer device. */
- uint16_t handle = bta_ag_idx_by_bdaddr(&peer_addr);
- tBTA_AG_SCB* p_scb = bta_ag_scb_by_idx(handle);
-
- if (p_scb && (p_scb->state == BTA_AG_OPENING_ST)) {
- if (id == BTA_ID_SYS) {
- LOG(WARNING) << __func__ << ": AG found collision (ACL) for handle "
- << unsigned(handle) << " device " << peer_addr;
- } else if (id == BTA_ID_AG) {
- LOG(WARNING) << __func__ << ": AG found collision (RFCOMM) for handle "
- << unsigned(handle) << " device " << peer_addr;
- } else {
- LOG(WARNING) << __func__ << ": AG found collision (UNKNOWN) for handle "
- << unsigned(handle) << " device " << peer_addr;
- }
- bta_ag_sm_execute(p_scb, BTA_AG_COLLISION_EVT, tBTA_AG_DATA::kEmpty);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_resume_open
- *
- * Description Resume opening process.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_resume_open(tBTA_AG_SCB* p_scb) {
- if (p_scb->state == BTA_AG_INIT_ST) {
- LOG(INFO) << __func__ << ": Resume connection to " << p_scb->peer_addr
- << ", handle" << bta_ag_scb_to_idx(p_scb);
- tBTA_AG_DATA open_data = {.api_open = {.bd_addr = p_scb->peer_addr}};
- bta_ag_sm_execute(p_scb, BTA_AG_API_OPEN_EVT, open_data);
- } else {
- VLOG(1) << __func__ << ": device " << p_scb->peer_addr
- << " is already in state " << std::to_string(p_scb->state);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_api_enable
- *
- * Description Handle an API enable event.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_api_enable(tBTA_AG_CBACK* p_cback) {
- /* initialize control block */
- for (tBTA_AG_SCB& scb : bta_ag_cb.scb) {
- alarm_free(scb.ring_timer);
- alarm_free(scb.codec_negotiation_timer);
- alarm_free(scb.collision_timer);
- scb = {};
- }
-
- /* store callback function */
- bta_ag_cb.p_cback = p_cback;
-
- /* call init call-out */
- BTM_WriteVoiceSettings(AG_VOICE_SETTINGS);
-
- bta_sys_collision_register(BTA_ID_AG, bta_ag_collision_cback);
-
- /* call callback with enable event */
- (*bta_ag_cb.p_cback)(BTA_AG_ENABLE_EVT, nullptr);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_api_disable
- *
- * Description Handle an API disable event.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_api_disable() {
- /* deregister all scbs in use */
- tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0];
- bool do_dereg = false;
- int i;
-
- if (!bta_sys_is_register(BTA_ID_AG)) {
- APPL_TRACE_ERROR("BTA AG is already disabled, ignoring ...");
- return;
- }
-
- /* De-register with BTA system manager */
- bta_sys_deregister(BTA_ID_AG);
-
- for (i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++, p_scb++) {
- if (p_scb->in_use) {
- bta_ag_sm_execute(p_scb, BTA_AG_API_DEREGISTER_EVT, tBTA_AG_DATA::kEmpty);
- do_dereg = true;
- }
- }
-
- if (!do_dereg) {
- /* Done, send callback evt to app */
- (*bta_ag_cb.p_cback)(BTA_AG_DISABLE_EVT, nullptr);
- }
-
- bta_sys_collision_register(BTA_ID_AG, nullptr);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_api_register
- *
- * Description Handle an API event registers a new service.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_api_register(tBTA_SERVICE_MASK services, tBTA_AG_FEAT features,
- const std::vector<std::string>& service_names,
- uint8_t app_id) {
- tBTA_AG_SCB* p_scb = bta_ag_scb_alloc();
- if (p_scb) {
- APPL_TRACE_DEBUG("bta_ag_api_register: p_scb 0x%08x ", p_scb);
- tBTA_AG_DATA data = {};
- data.api_register.features = features;
- data.api_register.services = services;
- data.api_register.app_id = app_id;
- for (int i = 0; i < BTA_AG_NUM_IDX; i++) {
- if (!service_names[i].empty()) {
- strlcpy(data.api_register.p_name[i], service_names[i].c_str(),
- BTA_SERVICE_NAME_LEN);
- } else {
- data.api_register.p_name[i][0] = 0;
- }
- }
- bta_ag_sm_execute(p_scb, BTA_AG_API_REGISTER_EVT, data);
- } else {
- tBTA_AG bta_ag = {};
- bta_ag.reg.status = BTA_AG_FAIL_RESOURCES;
- (*bta_ag_cb.p_cback)(BTA_AG_REGISTER_EVT, &bta_ag);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_api_result
- *
- * Description Handle an API result event.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_api_result(uint16_t handle, tBTA_AG_RES result,
- const tBTA_AG_RES_DATA& result_data) {
- tBTA_AG_DATA event_data = {};
- event_data.api_result.result = result;
- event_data.api_result.data = result_data;
- tBTA_AG_SCB* p_scb;
- if (handle != BTA_AG_HANDLE_ALL) {
- p_scb = bta_ag_scb_by_idx(handle);
- if (p_scb) {
- LOG_DEBUG("Audio gateway event for one client handle:%hu scb:%s", handle,
- p_scb->ToString().c_str());
- bta_ag_sm_execute(p_scb, static_cast<uint16_t>(BTA_AG_API_RESULT_EVT),
- event_data);
- } else {
- LOG_WARN(
- "Received audio gateway event for unknown AG control block "
- "handle:%hu",
- handle);
- }
- } else {
- int i;
- for (i = 0, p_scb = &bta_ag_cb.scb[0]; i < BTA_AG_MAX_NUM_CLIENTS;
- i++, p_scb++) {
- if (p_scb->in_use && p_scb->svc_conn) {
- LOG_DEBUG("Audio gateway event for all clients scb:%s",
- p_scb->ToString().c_str());
- bta_ag_sm_execute(p_scb, static_cast<uint16_t>(BTA_AG_API_RESULT_EVT),
- event_data);
- }
- }
- }
-}
-
-static void bta_ag_better_state_machine(tBTA_AG_SCB* p_scb, uint16_t event,
- const tBTA_AG_DATA& data) {
- switch (p_scb->state) {
- case BTA_AG_INIT_ST:
- switch (event) {
- case BTA_AG_API_REGISTER_EVT:
- bta_ag_register(p_scb, data);
- break;
- case BTA_AG_API_DEREGISTER_EVT:
- bta_ag_deregister(p_scb, data);
- break;
- case BTA_AG_API_OPEN_EVT:
- p_scb->state = BTA_AG_OPENING_ST;
- bta_ag_start_open(p_scb, data);
- break;
- case BTA_AG_RFC_OPEN_EVT:
- p_scb->state = BTA_AG_OPEN_ST;
- bta_ag_rfc_acp_open(p_scb, data);
- bta_ag_sco_listen(p_scb, data);
- break;
- case BTA_AG_SCO_OPEN_EVT:
- bta_ag_sco_conn_open(p_scb, data);
- break;
- case BTA_AG_SCO_CLOSE_EVT:
- bta_ag_sco_conn_close(p_scb, data);
- break;
- case BTA_AG_DISC_ACP_RES_EVT:
- bta_ag_free_db(p_scb, data);
- break;
- default:
- LOG_ERROR("unknown event %d at state %d", event, p_scb->state);
- break;
- }
- break;
- case BTA_AG_OPENING_ST:
- switch (event) {
- case BTA_AG_API_DEREGISTER_EVT:
- p_scb->state = BTA_AG_CLOSING_ST;
- bta_ag_rfc_do_close(p_scb, data);
- bta_ag_start_dereg(p_scb, data);
- break;
- case BTA_AG_API_OPEN_EVT:
- bta_ag_open_fail(p_scb, data);
- break;
- case BTA_AG_API_CLOSE_EVT:
- p_scb->state = BTA_AG_CLOSING_ST;
- bta_ag_rfc_do_close(p_scb, data);
- break;
- case BTA_AG_RFC_OPEN_EVT:
- p_scb->state = BTA_AG_OPEN_ST;
- bta_ag_rfc_open(p_scb, data);
- bta_ag_sco_listen(p_scb, data);
- break;
- case BTA_AG_RFC_CLOSE_EVT:
- p_scb->state = BTA_AG_INIT_ST;
- bta_ag_rfc_fail(p_scb, data);
- break;
- case BTA_AG_SCO_OPEN_EVT:
- bta_ag_sco_conn_open(p_scb, data);
- break;
- case BTA_AG_SCO_CLOSE_EVT:
- bta_ag_sco_conn_close(p_scb, data);
- break;
- case BTA_AG_DISC_INT_RES_EVT:
- bta_ag_disc_int_res(p_scb, data);
- break;
- case BTA_AG_DISC_OK_EVT:
- bta_ag_rfc_do_open(p_scb, data);
- break;
- case BTA_AG_DISC_FAIL_EVT:
- p_scb->state = BTA_AG_INIT_ST;
- bta_ag_disc_fail(p_scb, data);
- break;
- case BTA_AG_COLLISION_EVT:
- p_scb->state = BTA_AG_INIT_ST;
- bta_ag_handle_collision(p_scb, data);
- break;
- default:
- LOG_ERROR("unknown event %d at state %d", event, p_scb->state);
- break;
- }
- break;
- case BTA_AG_OPEN_ST:
- switch (event) {
- case BTA_AG_API_DEREGISTER_EVT:
- p_scb->state = BTA_AG_CLOSING_ST;
- bta_ag_start_close(p_scb, data);
- bta_ag_start_dereg(p_scb, data);
- break;
- case BTA_AG_API_OPEN_EVT:
- bta_ag_open_fail(p_scb, data);
- break;
- case BTA_AG_API_CLOSE_EVT:
- p_scb->state = BTA_AG_CLOSING_ST;
- bta_ag_start_close(p_scb, data);
- break;
- case BTA_AG_API_AUDIO_OPEN_EVT:
- bta_ag_sco_open(p_scb, data);
- break;
- case BTA_AG_API_AUDIO_CLOSE_EVT:
- bta_ag_sco_close(p_scb, data);
- break;
- case BTA_AG_API_RESULT_EVT:
- bta_ag_result(p_scb, data);
- break;
- case BTA_AG_API_SETCODEC_EVT:
- bta_ag_setcodec(p_scb, data);
- break;
- case BTA_AG_RFC_CLOSE_EVT:
- p_scb->state = BTA_AG_INIT_ST;
- bta_ag_rfc_close(p_scb, data);
- break;
- case BTA_AG_RFC_DATA_EVT:
- bta_ag_rfc_data(p_scb, data);
- break;
- case BTA_AG_SCO_OPEN_EVT:
- bta_ag_sco_conn_open(p_scb, data);
- bta_ag_post_sco_open(p_scb, data);
- break;
- case BTA_AG_SCO_CLOSE_EVT:
- bta_ag_sco_conn_close(p_scb, data);
- bta_ag_post_sco_close(p_scb, data);
- break;
- case BTA_AG_DISC_ACP_RES_EVT:
- bta_ag_disc_acp_res(p_scb, data);
- break;
- case BTA_AG_RING_TIMEOUT_EVT:
- bta_ag_send_ring(p_scb, data);
- break;
- case BTA_AG_SVC_TIMEOUT_EVT:
- p_scb->state = BTA_AG_CLOSING_ST;
- bta_ag_start_close(p_scb, data);
- break;
- default:
- LOG_ERROR("unknown event %d at state %d", event, p_scb->state);
- break;
- }
- break;
- case BTA_AG_CLOSING_ST:
- switch (event) {
- case BTA_AG_API_DEREGISTER_EVT:
- bta_ag_start_dereg(p_scb, data);
- break;
- case BTA_AG_API_OPEN_EVT:
- bta_ag_open_fail(p_scb, data);
- break;
- case BTA_AG_RFC_CLOSE_EVT:
- p_scb->state = BTA_AG_INIT_ST;
- bta_ag_rfc_close(p_scb, data);
- break;
- case BTA_AG_SCO_OPEN_EVT:
- bta_ag_sco_conn_open(p_scb, data);
- break;
- case BTA_AG_SCO_CLOSE_EVT:
- bta_ag_sco_conn_close(p_scb, data);
- bta_ag_post_sco_close(p_scb, data);
- break;
- case BTA_AG_DISC_ACP_RES_EVT:
- bta_ag_free_db(p_scb, data);
- break;
- case BTA_AG_DISC_INT_RES_EVT:
- p_scb->state = BTA_AG_INIT_ST;
- bta_ag_free_db(p_scb, data);
- break;
- default:
- LOG_ERROR("unknown event %d at state %d", event, p_scb->state);
- break;
- }
- break;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_sm_execute
- *
- * Description State machine event handling function for AG
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_sm_execute(tBTA_AG_SCB* p_scb, uint16_t event,
- const tBTA_AG_DATA& data) {
- uint16_t previous_event = event;
- uint8_t previous_state = p_scb->state;
-
- LOG_DEBUG(
- "Execute AG event handle:0x%04x bd_addr:%s state:%s[0x%02x]"
- " event:%s[0x%04x] result:%s[0x%02x]",
- bta_ag_scb_to_idx(p_scb), PRIVATE_ADDRESS(p_scb->peer_addr),
- bta_ag_state_str(p_scb->state), p_scb->state, bta_ag_evt_str(event),
- event, bta_ag_res_str(data.api_result.result), data.api_result.result);
-
- bta_ag_better_state_machine(p_scb, event, data);
-
- if (p_scb->state != previous_state) {
- LOG_DEBUG(
- "State changed handle:0x%04x bd_addr:%s "
- "state_change:%s[0x%02x]->%s[0x%02x]"
- " event:%s[0x%04x] result:%s[0x%02x]",
- bta_ag_scb_to_idx(p_scb), PRIVATE_ADDRESS(p_scb->peer_addr),
- bta_ag_state_str(previous_state), previous_state,
- bta_ag_state_str(p_scb->state), p_scb->state,
- bta_ag_evt_str(previous_event), previous_event,
- bta_ag_res_str(data.api_result.result), data.api_result.result);
- }
-}
-
-void bta_ag_sm_execute_by_handle(uint16_t handle, uint16_t event,
- const tBTA_AG_DATA& data) {
- tBTA_AG_SCB* p_scb = bta_ag_scb_by_idx(handle);
- if (p_scb) {
- LOG_DEBUG("AG state machine event:%s[0x%04x] handle:0x%04x",
- bta_ag_evt_str(event), event, handle);
- bta_ag_sm_execute(p_scb, event, data);
- }
-}
-
-/**
- * Handles event from bta_sys_sendmsg(). It is here to support legacy alarm
- * implementation that is mainly for timeouts.
- *
- * @param p_msg event message
- * @return True to free p_msg, or False if p_msg is freed within this function
- */
-bool bta_ag_hdl_event(BT_HDR_RIGID* p_msg) {
- switch (p_msg->event) {
- case BTA_AG_RING_TIMEOUT_EVT:
- case BTA_AG_SVC_TIMEOUT_EVT:
- bta_ag_sm_execute_by_handle(p_msg->layer_specific, p_msg->event,
- tBTA_AG_DATA::kEmpty);
- break;
- default:
- LOG(FATAL) << __func__ << ": bad event " << p_msg->event
- << " layer_specific=" << p_msg->layer_specific;
- break;
- }
- return true;
-}
diff --git a/bta/ag/bta_ag_rfc.cc b/bta/ag/bta_ag_rfc.cc
deleted file mode 100644
index 7d08e25..0000000
--- a/bta/ag/bta_ag_rfc.cc
+++ /dev/null
@@ -1,380 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2004-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains the audio gateway functions controlling the RFCOMM
- * connections.
- *
- ******************************************************************************/
-
-#include <base/bind.h>
-#include <base/logging.h>
-
-#include <cstring>
-
-#include "bta/ag/bta_ag_int.h"
-#include "osi/include/osi.h"
-#include "stack/include/btu.h" // do_in_main_thread
-#include "stack/include/port_api.h"
-#include "types/raw_address.h"
-
-/* Event mask for RfCOMM port callback */
-#define BTA_AG_PORT_EV_MASK PORT_EV_RXCHAR
-
-/* each scb has its own rfcomm callbacks */
-void bta_ag_port_cback_1(uint32_t code, uint16_t port_handle);
-void bta_ag_port_cback_2(uint32_t code, uint16_t port_handle);
-void bta_ag_port_cback_3(uint32_t code, uint16_t port_handle);
-void bta_ag_port_cback_4(uint32_t code, uint16_t port_handle);
-void bta_ag_port_cback_5(uint32_t code, uint16_t port_handle);
-void bta_ag_port_cback_6(uint32_t code, uint16_t port_handle);
-void bta_ag_mgmt_cback_1(uint32_t code, uint16_t port_handle);
-void bta_ag_mgmt_cback_2(uint32_t code, uint16_t port_handle);
-void bta_ag_mgmt_cback_3(uint32_t code, uint16_t port_handle);
-void bta_ag_mgmt_cback_4(uint32_t code, uint16_t port_handle);
-void bta_ag_mgmt_cback_5(uint32_t code, uint16_t port_handle);
-void bta_ag_mgmt_cback_6(uint32_t code, uint16_t port_handle);
-
-/* rfcomm callback function tables */
-typedef tPORT_CALLBACK* tBTA_AG_PORT_CBACK;
-const tBTA_AG_PORT_CBACK bta_ag_port_cback_tbl[] = {
- bta_ag_port_cback_1, bta_ag_port_cback_2, bta_ag_port_cback_3,
- bta_ag_port_cback_4, bta_ag_port_cback_5, bta_ag_port_cback_6};
-
-const tBTA_AG_PORT_CBACK bta_ag_mgmt_cback_tbl[] = {
- bta_ag_mgmt_cback_1, bta_ag_mgmt_cback_2, bta_ag_mgmt_cback_3,
- bta_ag_mgmt_cback_4, bta_ag_mgmt_cback_5, bta_ag_mgmt_cback_6};
-
-/*******************************************************************************
- *
- * Function bta_ag_port_cback
- *
- * Description RFCOMM Port callback
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_port_cback(UNUSED_ATTR uint32_t code, uint16_t port_handle,
- uint16_t handle) {
- tBTA_AG_SCB* p_scb = bta_ag_scb_by_idx(handle);
- if (p_scb != nullptr) {
- /* ignore port events for port handles other than connected handle */
- if (port_handle != p_scb->conn_handle) {
- APPL_TRACE_ERROR(
- "ag_port_cback ignoring handle:%d conn_handle = %d other handle = %d",
- port_handle, p_scb->conn_handle, handle);
- return;
- }
- if (!bta_ag_scb_open(p_scb)) {
- LOG(ERROR) << __func__ << ": rfcomm data on an unopened control block "
- << handle << " peer_addr " << p_scb->peer_addr << " state "
- << std::to_string(p_scb->state);
- }
- do_in_main_thread(FROM_HERE,
- base::Bind(&bta_ag_sm_execute_by_handle, handle,
- BTA_AG_RFC_DATA_EVT, tBTA_AG_DATA::kEmpty));
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_mgmt_cback
- *
- * Description RFCOMM management callback
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_mgmt_cback(uint32_t code, uint16_t port_handle,
- uint16_t handle) {
- tBTA_AG_SCB* p_scb = bta_ag_scb_by_idx(handle);
- APPL_TRACE_DEBUG("%s: code=%d, port_handle=%d, scb_handle=%d, p_scb=0x%08x",
- __func__, code, port_handle, handle, p_scb);
- if (p_scb == nullptr) {
- LOG(WARNING) << __func__ << ": cannot find scb, code=" << code
- << ", port_handle=" << port_handle << ", handle=" << handle;
- return;
- }
- /* ignore close event for port handles other than connected handle */
- if ((code != PORT_SUCCESS) && (port_handle != p_scb->conn_handle)) {
- LOG(WARNING) << __func__ << ": ignore open failure for unmatched "
- << "port_handle " << port_handle << ", scb_handle=" << handle;
- return;
- }
- uint16_t event;
- if (code == PORT_SUCCESS) {
- bool found_handle = false;
- if (p_scb->conn_handle) {
- /* Outgoing connection */
- if (port_handle == p_scb->conn_handle) {
- found_handle = true;
- }
- } else {
- /* Incoming connection */
- for (uint16_t service_port_handle : p_scb->serv_handle) {
- if (port_handle == service_port_handle) {
- found_handle = true;
- break;
- }
- }
- }
- if (!found_handle) {
- LOG(ERROR) << __func__ << ": port opened successfully, but port_handle "
- << port_handle << " is unknown"
- << ", scb_handle=" << handle;
- return;
- }
- event = BTA_AG_RFC_OPEN_EVT;
- } else if (port_handle == p_scb->conn_handle) {
- /* distinguish server close events */
- event = BTA_AG_RFC_CLOSE_EVT;
- } else {
- event = BTA_AG_RFC_SRV_CLOSE_EVT;
- }
-
- tBTA_AG_DATA data = {};
- data.rfc.port_handle = port_handle;
- do_in_main_thread(
- FROM_HERE, base::Bind(&bta_ag_sm_execute_by_handle, handle, event, data));
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_port_cback_1 to 6
- * bta_ag_mgmt_cback_1 to 6
- *
- * Description RFCOMM callback functions. This is an easy way to
- * distinguish scb from the callback.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_mgmt_cback_1(uint32_t code, uint16_t port_handle) {
- bta_ag_mgmt_cback(code, port_handle, 1);
-}
-void bta_ag_mgmt_cback_2(uint32_t code, uint16_t port_handle) {
- bta_ag_mgmt_cback(code, port_handle, 2);
-}
-void bta_ag_mgmt_cback_3(uint32_t code, uint16_t port_handle) {
- bta_ag_mgmt_cback(code, port_handle, 3);
-}
-void bta_ag_mgmt_cback_4(uint32_t code, uint16_t port_handle) {
- bta_ag_mgmt_cback(code, port_handle, 4);
-}
-void bta_ag_mgmt_cback_5(uint32_t code, uint16_t port_handle) {
- bta_ag_mgmt_cback(code, port_handle, 5);
-}
-void bta_ag_mgmt_cback_6(uint32_t code, uint16_t port_handle) {
- bta_ag_mgmt_cback(code, port_handle, 6);
-}
-void bta_ag_port_cback_1(uint32_t code, uint16_t port_handle) {
- bta_ag_port_cback(code, port_handle, 1);
-}
-void bta_ag_port_cback_2(uint32_t code, uint16_t port_handle) {
- bta_ag_port_cback(code, port_handle, 2);
-}
-void bta_ag_port_cback_3(uint32_t code, uint16_t port_handle) {
- bta_ag_port_cback(code, port_handle, 3);
-}
-void bta_ag_port_cback_4(uint32_t code, uint16_t port_handle) {
- bta_ag_port_cback(code, port_handle, 4);
-}
-void bta_ag_port_cback_5(uint32_t code, uint16_t port_handle) {
- bta_ag_port_cback(code, port_handle, 5);
-}
-void bta_ag_port_cback_6(uint32_t code, uint16_t port_handle) {
- bta_ag_port_cback(code, port_handle, 6);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_setup_port
- *
- * Description Setup RFCOMM port for use by AG.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_setup_port(tBTA_AG_SCB* p_scb, uint16_t handle) {
- int port_callback_index = bta_ag_scb_to_idx(p_scb) - 1;
- CHECK_GE(port_callback_index, 0)
- << "invalid callback index, handle=" << handle << ", bd_addr"
- << p_scb->peer_addr;
- CHECK_LT(port_callback_index,
- static_cast<int>(sizeof(bta_ag_port_cback_tbl) /
- sizeof(bta_ag_port_cback_tbl[0])))
- << "callback index out of bound, handle=" << handle << ", bd_addr"
- << p_scb->peer_addr;
- PORT_SetEventMask(handle, BTA_AG_PORT_EV_MASK);
- PORT_SetEventCallback(handle, bta_ag_port_cback_tbl[port_callback_index]);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_start_servers
- *
- * Description Setup RFCOMM servers for use by AG.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_start_servers(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK services) {
- services >>= BTA_HSP_SERVICE_ID;
- for (int i = 0; i < BTA_AG_NUM_IDX && services != 0; i++, services >>= 1) {
- /* if service is set in mask */
- if (services & 1) {
- int management_callback_index = bta_ag_scb_to_idx(p_scb) - 1;
- CHECK_GE(management_callback_index, 0)
- << "invalid callback index, services=" << loghex(services)
- << ", bd_addr=" << p_scb->peer_addr;
- CHECK_LT(management_callback_index,
- static_cast<int>(sizeof(bta_ag_mgmt_cback_tbl) /
- sizeof(bta_ag_mgmt_cback_tbl[0])))
- << "callback index out of bound, services=" << loghex(services)
- << ", bd_addr" << p_scb->peer_addr;
- int status = RFCOMM_CreateConnectionWithSecurity(
- bta_ag_uuid[i], bta_ag_cb.profile[i].scn, true, BTA_AG_MTU,
- RawAddress::kAny, &(p_scb->serv_handle[i]),
- bta_ag_mgmt_cback_tbl[management_callback_index],
- BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
- if (status == PORT_SUCCESS) {
- bta_ag_setup_port(p_scb, p_scb->serv_handle[i]);
- } else {
- /* TODO: CR#137125 to handle to error properly */
- LOG(ERROR) << __func__ << ": RFCOMM_CreateConnectionWithSecurity ERROR "
- << status << ", p_scb=" << p_scb
- << ", services=" << loghex(services)
- << ", mgmt_cback_index=" << management_callback_index;
- }
- APPL_TRACE_DEBUG("%s: p_scb=0x%08x, services=0x%04x, mgmt_cback_index=%d",
- __func__, p_scb, services, management_callback_index);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_close_servers
- *
- * Description Close RFCOMM servers port for use by AG.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_close_servers(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK services) {
- services >>= BTA_HSP_SERVICE_ID;
- for (int i = 0; i < BTA_AG_NUM_IDX && services != 0; i++, services >>= 1) {
- /* if service is set in mask */
- if (services & 1) {
- RFCOMM_RemoveServer(p_scb->serv_handle[i]);
- p_scb->serv_handle[i] = 0;
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_is_server_closed
- *
- * Description Returns true if all servers are closed.
- *
- *
- * Returns true if all servers are closed, false otherwise
- *
- ******************************************************************************/
-bool bta_ag_is_server_closed(tBTA_AG_SCB* p_scb) {
- uint8_t xx;
- bool is_closed = true;
-
- for (xx = 0; xx < BTA_AG_NUM_IDX; xx++) {
- if (p_scb->serv_handle[xx] != 0) is_closed = false;
- }
-
- return is_closed;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_rfc_do_open
- *
- * Description Open an RFCOMM connection to the peer device.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_rfc_do_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- int management_callback_index = bta_ag_scb_to_idx(p_scb) - 1;
- int status = RFCOMM_CreateConnectionWithSecurity(
- bta_ag_uuid[p_scb->conn_service], p_scb->peer_scn, false, BTA_AG_MTU,
- p_scb->peer_addr, &(p_scb->conn_handle),
- bta_ag_mgmt_cback_tbl[management_callback_index],
- BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
- APPL_TRACE_DEBUG(
- "%s: p_scb=0x%08x, conn_handle=%d, mgmt_cback_index=%d,"
- " status=%d",
- __func__, p_scb, p_scb->conn_handle, management_callback_index, status);
- if (status == PORT_SUCCESS) {
- bta_ag_setup_port(p_scb, p_scb->conn_handle);
- } else {
- /* RFCOMM create connection failed; send ourselves RFCOMM close event */
- LOG(ERROR) << __func__ << ": RFCOMM_CreateConnection ERROR " << status
- << " for " << p_scb->peer_addr;
- bta_ag_sm_execute(p_scb, BTA_AG_RFC_CLOSE_EVT, data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_rfc_do_close
- *
- * Description Close RFCOMM connection.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_rfc_do_close(tBTA_AG_SCB* p_scb,
- UNUSED_ATTR const tBTA_AG_DATA& data) {
- if (p_scb->conn_handle) {
- RFCOMM_RemoveConnection(p_scb->conn_handle);
- } else {
- /* Close API was called while AG is in Opening state. */
- /* Need to trigger the state machine to send callback to the app */
- /* and move back to INIT state. */
- do_in_main_thread(
- FROM_HERE,
- base::Bind(&bta_ag_sm_execute_by_handle, bta_ag_scb_to_idx(p_scb),
- BTA_AG_RFC_CLOSE_EVT, tBTA_AG_DATA::kEmpty));
-
- /* Cancel SDP if it had been started. */
- /*
- if(p_scb->p_disc_db)
- {
- (void)SDP_CancelServiceSearch (p_scb->p_disc_db);
- }
- */
- }
-}
diff --git a/bta/ag/bta_ag_sco.cc b/bta/ag/bta_ag_sco.cc
deleted file mode 100644
index f33530a..0000000
--- a/bta/ag/bta_ag_sco.cc
+++ /dev/null
@@ -1,1347 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2004-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains functions for managing the SCO connection used in AG.
- *
- ******************************************************************************/
-
-#include <base/bind.h>
-#include <base/logging.h>
-#include <cstdint>
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bt_trace.h" // Legacy trace logging
-
-#include "bta/ag/bta_ag_int.h"
-#include "device/include/controller.h"
-#include "main/shim/dumpsys.h"
-#include "osi/include/log.h"
-#include "osi/include/osi.h" // UNUSED_ATTR
-#include "stack/btm/btm_sco.h"
-#include "stack/include/btm_api.h"
-#include "stack/include/btu.h" // do_in_main_thread
-#include "types/raw_address.h"
-
-/* Codec negotiation timeout */
-#ifndef BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS
-#define BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS (3 * 1000) /* 3 seconds */
-#endif
-
-static bool sco_allowed = true;
-static RawAddress active_device_addr = {};
-
-/* sco events */
-enum {
- BTA_AG_SCO_LISTEN_E, /* listen request */
- BTA_AG_SCO_OPEN_E, /* open request */
- BTA_AG_SCO_XFER_E, /* transfer request */
- BTA_AG_SCO_CN_DONE_E, /* codec negotiation done */
- BTA_AG_SCO_REOPEN_E, /* Retry with other codec when failed */
- BTA_AG_SCO_CLOSE_E, /* close request */
- BTA_AG_SCO_SHUTDOWN_E, /* shutdown request */
- BTA_AG_SCO_CONN_OPEN_E, /* sco open */
- BTA_AG_SCO_CONN_CLOSE_E, /* sco closed */
-};
-
-#define CASE_RETURN_STR(const) \
- case const: \
- return #const;
-
-static const char* bta_ag_sco_evt_str(uint8_t event) {
- switch (event) {
- CASE_RETURN_STR(BTA_AG_SCO_LISTEN_E)
- CASE_RETURN_STR(BTA_AG_SCO_OPEN_E)
- CASE_RETURN_STR(BTA_AG_SCO_XFER_E)
- CASE_RETURN_STR(BTA_AG_SCO_CN_DONE_E)
- CASE_RETURN_STR(BTA_AG_SCO_REOPEN_E)
- CASE_RETURN_STR(BTA_AG_SCO_CLOSE_E)
- CASE_RETURN_STR(BTA_AG_SCO_SHUTDOWN_E)
- CASE_RETURN_STR(BTA_AG_SCO_CONN_OPEN_E)
- CASE_RETURN_STR(BTA_AG_SCO_CONN_CLOSE_E)
- default:
- return "Unknown SCO Event";
- }
-}
-
-static const char* bta_ag_sco_state_str(uint8_t state) {
- switch (state) {
- CASE_RETURN_STR(BTA_AG_SCO_SHUTDOWN_ST)
- CASE_RETURN_STR(BTA_AG_SCO_LISTEN_ST)
- CASE_RETURN_STR(BTA_AG_SCO_CODEC_ST)
- CASE_RETURN_STR(BTA_AG_SCO_OPENING_ST)
- CASE_RETURN_STR(BTA_AG_SCO_OPEN_CL_ST)
- CASE_RETURN_STR(BTA_AG_SCO_OPEN_XFER_ST)
- CASE_RETURN_STR(BTA_AG_SCO_OPEN_ST)
- CASE_RETURN_STR(BTA_AG_SCO_CLOSING_ST)
- CASE_RETURN_STR(BTA_AG_SCO_CLOSE_OP_ST)
- CASE_RETURN_STR(BTA_AG_SCO_CLOSE_XFER_ST)
- CASE_RETURN_STR(BTA_AG_SCO_SHUTTING_ST)
- default:
- return "Unknown SCO State";
- }
-}
-
-/**
- * Check if bd_addr is the current active device.
- *
- * @param bd_addr target device address
- * @return True if bd_addr is the current active device, False otherwise or if
- * no active device is set (i.e. active_device_addr is empty)
- */
-bool bta_ag_sco_is_active_device(const RawAddress& bd_addr) {
- return !active_device_addr.IsEmpty() && active_device_addr == bd_addr;
-}
-
-static void bta_ag_create_pending_sco(tBTA_AG_SCB* p_scb, bool is_local);
-
-/*******************************************************************************
- *
- * Function bta_ag_sco_conn_cback
- *
- * Description BTM SCO connection callback.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_sco_conn_cback(uint16_t sco_idx) {
- uint16_t handle;
- tBTA_AG_SCB* p_scb;
-
- /* match callback to scb; first check current sco scb */
- if (bta_ag_cb.sco.p_curr_scb != nullptr && bta_ag_cb.sco.p_curr_scb->in_use) {
- handle = bta_ag_scb_to_idx(bta_ag_cb.sco.p_curr_scb);
- }
- /* then check for scb connected to this peer */
- else {
- /* Check if SLC is up */
- handle = bta_ag_idx_by_bdaddr(BTM_ReadScoBdAddr(sco_idx));
- p_scb = bta_ag_scb_by_idx(handle);
- if (p_scb && !p_scb->svc_conn) handle = 0;
- }
-
- if (handle != 0) {
- do_in_main_thread(FROM_HERE,
- base::Bind(&bta_ag_sm_execute_by_handle, handle,
- BTA_AG_SCO_OPEN_EVT, tBTA_AG_DATA::kEmpty));
- } else {
- /* no match found; disconnect sco, init sco variables */
- bta_ag_cb.sco.p_curr_scb = nullptr;
- bta_ag_cb.sco.state = BTA_AG_SCO_SHUTDOWN_ST;
- BTM_RemoveSco(sco_idx);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_sco_disc_cback
- *
- * Description BTM SCO disconnection callback.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_sco_disc_cback(uint16_t sco_idx) {
- uint16_t handle = 0;
-
- LOG_DEBUG(
- "sco_idx: 0x%x sco.state:%s", sco_idx,
- sco_state_text(static_cast<tSCO_STATE>(bta_ag_cb.sco.state)).c_str());
- LOG_DEBUG(
- " scb[0] in_use:%s sco_idx: 0x%x sco state:%s",
- logbool(bta_ag_cb.scb[0].in_use).c_str(), bta_ag_cb.scb[0].sco_idx,
- sco_state_text(static_cast<tSCO_STATE>(bta_ag_cb.scb[0].state)).c_str());
- LOG_DEBUG(
- " scb[1] in_use:%s sco_idx:0x%x sco state:%s",
- logbool(bta_ag_cb.scb[1].in_use).c_str(), bta_ag_cb.scb[1].sco_idx,
- sco_state_text(static_cast<tSCO_STATE>(bta_ag_cb.scb[1].state)).c_str());
-
- /* match callback to scb */
- if (bta_ag_cb.sco.p_curr_scb != nullptr && bta_ag_cb.sco.p_curr_scb->in_use) {
- /* We only care about callbacks for the active SCO */
- if (bta_ag_cb.sco.p_curr_scb->sco_idx != sco_idx) {
- if (bta_ag_cb.sco.p_curr_scb->sco_idx != 0xFFFF) return;
- }
- handle = bta_ag_scb_to_idx(bta_ag_cb.sco.p_curr_scb);
- }
-
- if (handle != 0) {
- /* Restore settings */
- if (bta_ag_cb.sco.p_curr_scb->inuse_codec == BTM_SCO_CODEC_MSBC) {
- /* Bypass vendor specific and voice settings if enhanced eSCO supported */
- if (!(controller_get_interface()
- ->supports_enhanced_setup_synchronous_connection())) {
- BTM_WriteVoiceSettings(BTM_VOICE_SETTING_CVSD);
- }
-
- /* If SCO open was initiated by AG and failed for mSBC T2, try mSBC T1
- * 'Safe setting' first. If T1 also fails, try CVSD */
- if (bta_ag_sco_is_opening(bta_ag_cb.sco.p_curr_scb)) {
- bta_ag_cb.sco.p_curr_scb->state = BTA_AG_SCO_CODEC_ST;
- if (bta_ag_cb.sco.p_curr_scb->codec_msbc_settings ==
- BTA_AG_SCO_MSBC_SETTINGS_T2) {
- APPL_TRACE_WARNING(
- "%s: eSCO/SCO failed to open, falling back to mSBC T1 settings",
- __func__);
- bta_ag_cb.sco.p_curr_scb->codec_msbc_settings =
- BTA_AG_SCO_MSBC_SETTINGS_T1;
- } else {
- APPL_TRACE_WARNING(
- "%s: eSCO/SCO failed to open, falling back to CVSD", __func__);
- bta_ag_cb.sco.p_curr_scb->codec_fallback = true;
- }
- }
- } else if (bta_ag_sco_is_opening(bta_ag_cb.sco.p_curr_scb)) {
- APPL_TRACE_ERROR("%s: eSCO/SCO failed to open, no more fall back",
- __func__);
- }
-
- bta_ag_cb.sco.p_curr_scb->inuse_codec = BTM_SCO_CODEC_NONE;
-
- do_in_main_thread(FROM_HERE,
- base::Bind(&bta_ag_sm_execute_by_handle, handle,
- BTA_AG_SCO_CLOSE_EVT, tBTA_AG_DATA::kEmpty));
- } else {
- /* no match found */
- APPL_TRACE_DEBUG("no scb for ag_sco_disc_cback");
-
- /* sco could be closed after scb dealloc'ed */
- if (bta_ag_cb.sco.p_curr_scb != nullptr) {
- bta_ag_cb.sco.p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX;
- bta_ag_cb.sco.p_curr_scb = nullptr;
- bta_ag_cb.sco.state = BTA_AG_SCO_SHUTDOWN_ST;
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_remove_sco
- *
- * Description Removes the specified SCO from the system.
- * If only_active is true, then SCO is only removed if
- * connected
- *
- * Returns bool - true if SCO removal was started
- *
- ******************************************************************************/
-static bool bta_ag_remove_sco(tBTA_AG_SCB* p_scb, bool only_active) {
- if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX) {
- if (!only_active || p_scb->sco_idx == bta_ag_cb.sco.cur_idx) {
- tBTM_STATUS status = BTM_RemoveSco(p_scb->sco_idx);
- LOG_DEBUG("Removed SCO index:0x%04x status:%s", p_scb->sco_idx,
- btm_status_text(status).c_str());
- if (status == BTM_CMD_STARTED) {
- /* SCO is connected; set current control block */
- bta_ag_cb.sco.p_curr_scb = p_scb;
- return true;
- } else if ((status == BTM_SUCCESS) || (status == BTM_UNKNOWN_ADDR)) {
- /* If no connection reset the SCO handle */
- p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
- }
- }
- }
- return false;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_esco_connreq_cback
- *
- * Description BTM eSCO connection requests and eSCO change requests
- * Only the connection requests are processed by BTA.
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_esco_connreq_cback(tBTM_ESCO_EVT event,
- tBTM_ESCO_EVT_DATA* p_data) {
- /* Only process connection requests */
- if (event == BTM_ESCO_CONN_REQ_EVT) {
- uint16_t sco_inx = p_data->conn_evt.sco_inx;
- const RawAddress* remote_bda = BTM_ReadScoBdAddr(sco_inx);
- tBTA_AG_SCB* p_scb = bta_ag_scb_by_idx(bta_ag_idx_by_bdaddr(remote_bda));
- if (remote_bda && bta_ag_sco_is_active_device(*remote_bda) && p_scb &&
- p_scb->svc_conn) {
- p_scb->sco_idx = sco_inx;
-
- /* If no other SCO active, allow this one */
- if (!bta_ag_cb.sco.p_curr_scb) {
- APPL_TRACE_EVENT("%s: Accept Conn Request (sco_inx 0x%04x)", __func__,
- sco_inx);
- bta_ag_sco_conn_rsp(p_scb, &p_data->conn_evt);
-
- bta_ag_cb.sco.state = BTA_AG_SCO_OPENING_ST;
- bta_ag_cb.sco.p_curr_scb = p_scb;
- bta_ag_cb.sco.cur_idx = p_scb->sco_idx;
- } else {
- /* Begin a transfer: Close current SCO before responding */
- APPL_TRACE_DEBUG("bta_ag_esco_connreq_cback: Begin XFER");
- bta_ag_cb.sco.p_xfer_scb = p_scb;
- bta_ag_cb.sco.conn_data = p_data->conn_evt;
- bta_ag_cb.sco.state = BTA_AG_SCO_OPEN_XFER_ST;
-
- if (!bta_ag_remove_sco(bta_ag_cb.sco.p_curr_scb, true)) {
- APPL_TRACE_ERROR(
- "%s: Nothing to remove,so accept Conn Request(sco_inx 0x%04x)",
- __func__, sco_inx);
- bta_ag_cb.sco.p_xfer_scb = nullptr;
- bta_ag_cb.sco.state = BTA_AG_SCO_LISTEN_ST;
-
- bta_ag_sco_conn_rsp(p_scb, &p_data->conn_evt);
- }
- }
- } else {
- LOG(WARNING) << __func__
- << ": reject incoming SCO connection, remote_bda="
- << (remote_bda ? *remote_bda : RawAddress::kEmpty)
- << ", active_bda=" << active_device_addr << ", current_bda="
- << (p_scb ? p_scb->peer_addr : RawAddress::kEmpty);
- BTM_EScoConnRsp(p_data->conn_evt.sco_inx, HCI_ERR_HOST_REJECT_RESOURCES,
- (enh_esco_params_t*)nullptr);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_cback_sco
- *
- * Description Call application callback function with SCO event.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_cback_sco(tBTA_AG_SCB* p_scb, tBTA_AG_EVT event) {
- tBTA_AG_HDR sco = {};
- sco.handle = bta_ag_scb_to_idx(p_scb);
- sco.app_id = p_scb->app_id;
- /* call close cback */
- (*bta_ag_cb.p_cback)(static_cast<tBTA_AG_EVT>(event), (tBTA_AG*)&sco);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_create_sco
- *
- * Description Create a SCO connection for a given control block
- * p_scb : Pointer to the target AG control block
- * is_orig : Whether to initiate or listen for SCO connection
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) {
- LOG_DEBUG("BEFORE %s", p_scb->ToString().c_str());
- tBTA_AG_PEER_CODEC esco_codec = BTM_SCO_CODEC_CVSD;
-
- if (!bta_ag_sco_is_active_device(p_scb->peer_addr)) {
- LOG(WARNING) << __func__ << ": device " << p_scb->peer_addr
- << " is not active, active_device=" << active_device_addr;
- if (bta_ag_cb.sco.p_curr_scb != nullptr &&
- bta_ag_cb.sco.p_curr_scb->in_use && p_scb == bta_ag_cb.sco.p_curr_scb) {
- do_in_main_thread(
- FROM_HERE, base::Bind(&bta_ag_sm_execute, p_scb, BTA_AG_SCO_CLOSE_EVT,
- tBTA_AG_DATA::kEmpty));
- }
- return;
- }
- /* Make sure this SCO handle is not already in use */
- if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX) {
- APPL_TRACE_ERROR("%s: device %s, index 0x%04x already in use!", __func__,
- p_scb->peer_addr.ToString().c_str(), p_scb->sco_idx);
- return;
- }
-
-#if (DISABLE_WBS == FALSE)
- if ((p_scb->sco_codec == BTM_SCO_CODEC_MSBC) && !p_scb->codec_fallback)
- esco_codec = BTM_SCO_CODEC_MSBC;
-#endif
-
- if (p_scb->codec_fallback) {
- p_scb->codec_fallback = false;
- /* Force AG to send +BCS for the next audio connection. */
- p_scb->codec_updated = true;
- /* Reset mSBC settings to T2 for the next audio connection */
- p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
- }
-
- /* Initialize eSCO parameters */
- enh_esco_params_t params = {};
- /* If WBS included, use CVSD by default, index is 0 for CVSD by
- * initialization. If eSCO codec is mSBC, index is T2 or T1 */
- if (esco_codec == BTM_SCO_CODEC_MSBC) {
- if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2) {
- params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T2);
- } else {
- params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T1);
- }
- } else {
- if (p_scb->features & BTA_AG_PEER_FEAT_ESCO_S4 &&
- (p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO_S4)) {
- // HFP >=1.7 eSCO
- params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S4);
- } else {
- // HFP <=1.6 eSCO
- params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S3);
- }
- }
-
- /* If initiating, setup parameters to start SCO/eSCO connection */
- if (is_orig) {
- bta_ag_cb.sco.is_local = true;
- /* Set eSCO Mode */
- BTM_SetEScoMode(¶ms);
- bta_ag_cb.sco.p_curr_scb = p_scb;
- /* save the current codec as sco_codec can be updated while SCO is open. */
- p_scb->inuse_codec = esco_codec;
-
- /* tell sys to stop av if any */
- bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
-
- /* Send pending commands to create SCO connection to peer */
- bta_ag_create_pending_sco(p_scb, bta_ag_cb.sco.is_local);
- LOG_DEBUG("Initiating AG SCO inx 0x%04x, pkt types 0x%04x", p_scb->sco_idx,
- params.packet_types);
- } else {
- /* Not initiating, go to listen mode */
- tBTM_STATUS btm_status = BTM_CreateSco(
- &p_scb->peer_addr, false, params.packet_types, &p_scb->sco_idx,
- bta_ag_sco_conn_cback, bta_ag_sco_disc_cback);
- if (btm_status == BTM_CMD_STARTED) {
- BTM_RegForEScoEvts(p_scb->sco_idx, bta_ag_esco_connreq_cback);
- }
- LOG_DEBUG("Listening AG SCO inx 0x%04x status:%s pkt types 0x%04x",
- p_scb->sco_idx, btm_status_text(btm_status).c_str(),
- params.packet_types);
- }
- LOG_DEBUG("AFTER %s", p_scb->ToString().c_str());
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_create_pending_sco
- *
- * Description This Function is called after the pre-SCO vendor setup is
- * done for the BTA to continue and send the HCI Commands for
- * creating/accepting SCO connection with peer based on the
- * is_local parameter.
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_create_pending_sco(tBTA_AG_SCB* p_scb, bool is_local) {
- tBTA_AG_PEER_CODEC esco_codec = p_scb->inuse_codec;
- enh_esco_params_t params = {};
- bta_ag_cb.sco.p_curr_scb = p_scb;
- bta_ag_cb.sco.cur_idx = p_scb->sco_idx;
-
- /* Local device requested SCO connection to peer */
- if (is_local) {
- if (esco_codec == BTM_SCO_CODEC_MSBC) {
- if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2) {
- params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T2);
- } else {
- params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T1);
- }
- } else {
- if (p_scb->features & BTA_AG_PEER_FEAT_ESCO_S4 &&
- (p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO_S4)) {
- // HFP >=1.7 eSCO
- params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S4);
- } else {
- // HFP <=1.6 eSCO
- params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S3);
- }
- }
-
- /* Bypass voice settings if enhanced SCO setup command is supported */
- if (!(controller_get_interface()
- ->supports_enhanced_setup_synchronous_connection())) {
- if (esco_codec == BTM_SCO_CODEC_MSBC) {
- BTM_WriteVoiceSettings(BTM_VOICE_SETTING_TRANS);
- } else {
- BTM_WriteVoiceSettings(BTM_VOICE_SETTING_CVSD);
- }
- }
-
- if (BTM_CreateSco(&p_scb->peer_addr, true, params.packet_types,
- &p_scb->sco_idx, bta_ag_sco_conn_cback,
- bta_ag_sco_disc_cback) == BTM_CMD_STARTED) {
- /* Initiating the connection, set the current sco handle */
- bta_ag_cb.sco.cur_idx = p_scb->sco_idx;
- }
- APPL_TRACE_DEBUG("%s: initiated SCO connection", __func__);
- } else {
- // Local device accepted SCO connection from peer(HF)
- // Because HF devices usually do not send AT+BAC and +BCS command,
- // and there is no plan to implement corresponding command handlers,
- // so we only accept CVSD connection from HF no matter what's
- // requested.
- if (p_scb->features & BTA_AG_PEER_FEAT_ESCO_S4 &&
- (p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO_S4)) {
- // HFP >=1.7 eSCO
- params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S4);
- } else {
- // HFP <=1.6 eSCO
- params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S3);
- }
-
- BTM_EScoConnRsp(p_scb->sco_idx, HCI_SUCCESS, ¶ms);
- APPL_TRACE_DEBUG("%s: listening for SCO connection", __func__);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_codec_negotiation_timer_cback
- *
- * Description
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_codec_negotiation_timer_cback(void* data) {
- LOG_WARN("Codec negotiation timeout");
- tBTA_AG_SCB* p_scb = (tBTA_AG_SCB*)data;
-
- /* Announce that codec negotiation failed. */
- bta_ag_sco_codec_nego(p_scb, false);
-
- /* call app callback */
- bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_codec_negotiate
- *
- * Description Initiate codec negotiation by sending AT command.
- * If not necessary, skip negotiation.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_codec_negotiate(tBTA_AG_SCB* p_scb) {
- bta_ag_cb.sco.p_curr_scb = p_scb;
- uint8_t* p_rem_feat = BTM_ReadRemoteFeatures(p_scb->peer_addr);
- bool sdp_wbs_support = p_scb->peer_sdp_features & BTA_AG_FEAT_WBS_SUPPORT;
-
- if (p_rem_feat == nullptr) {
- LOG_WARN("Skip codec negotiation, failed to read remote features");
- bta_ag_sco_codec_nego(p_scb, false);
- return;
- }
-
- // Workaround for misbehaving HFs, which indicate which one is not support on
- // Transparent Synchronous Data in Remote Supported Features, WBS in SDP and
- // and Codec Negotiation in BRSF. Fluoride will assume CVSD codec by default.
- // In Sony XAV AX100 car kit and Sony MW600 Headset case, which indicate
- // Transparent Synchronous Data and WBS support, but no codec negotiation
- // support, using mSBC codec can result background noise or no audio.
- // In Skullcandy JIB case, which indicate WBS and codec negotiation support,
- // but no Transparent Synchronous Data support, using mSBC codec can result
- // SCO setup fail by Firmware reject.
- if (!HCI_LMP_TRANSPNT_SUPPORTED(p_rem_feat) || !sdp_wbs_support ||
- !(p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC)) {
- LOG_INFO("Assume CVSD by default due to mask mismatch");
- p_scb->sco_codec = UUID_CODEC_CVSD;
- }
-
- if ((p_scb->codec_updated || p_scb->codec_fallback) &&
- (p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC)) {
- LOG_INFO("Starting codec negotiation");
- /* Change the power mode to Active until SCO open is completed. */
- bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
-
- /* Send +BCS to the peer */
- bta_ag_send_bcs(p_scb);
-
- /* Start timer to handle timeout */
- alarm_set_on_mloop(p_scb->codec_negotiation_timer,
- BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS,
- bta_ag_codec_negotiation_timer_cback, p_scb);
- } else {
- /* use same codec type as previous SCO connection, skip codec negotiation */
- LOG_INFO("Skip codec negotiation, using the same codec");
- bta_ag_sco_codec_nego(p_scb, true);
- }
-}
-
-static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) {
- tBTA_AG_SCO_CB* p_sco = &bta_ag_cb.sco;
- uint8_t previous_state = p_sco->state;
- LOG_INFO("device:%s index:0x%04x state:%s[%d] event:%s[%d]",
- PRIVATE_ADDRESS(p_scb->peer_addr), p_scb->sco_idx,
- bta_ag_sco_state_str(p_sco->state), p_sco->state,
- bta_ag_sco_evt_str(event), event);
-
- switch (p_sco->state) {
- case BTA_AG_SCO_SHUTDOWN_ST:
- switch (event) {
- case BTA_AG_SCO_LISTEN_E:
- /* create sco listen connection */
- bta_ag_create_sco(p_scb, false);
- p_sco->state = BTA_AG_SCO_LISTEN_ST;
- break;
-
- default:
- LOG_WARN("BTA_AG_SCO_SHUTDOWN_ST: Ignoring event %s[%d]",
- bta_ag_sco_evt_str(event), event);
- break;
- }
- break;
-
- case BTA_AG_SCO_LISTEN_ST:
- switch (event) {
- case BTA_AG_SCO_LISTEN_E:
- /* create sco listen connection (Additional channel) */
- bta_ag_create_sco(p_scb, false);
- break;
-
- case BTA_AG_SCO_OPEN_E:
- /* remove listening connection */
- bta_ag_remove_sco(p_scb, false);
-
-#if (DISABLE_WBS == FALSE)
- /* start codec negotiation */
- p_sco->state = BTA_AG_SCO_CODEC_ST;
- bta_ag_codec_negotiate(p_scb);
-#else
- bta_ag_create_sco(p_scb, true);
- p_sco->state = BTA_AG_SCO_OPENING_ST;
-#endif
- break;
-
- case BTA_AG_SCO_SHUTDOWN_E:
- /* remove listening connection */
- bta_ag_remove_sco(p_scb, false);
-
- if (p_scb == p_sco->p_curr_scb) p_sco->p_curr_scb = nullptr;
-
- /* If last SCO instance then finish shutting down */
- if (!bta_ag_other_scb_open(p_scb)) {
- p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
- }
- break;
-
- case BTA_AG_SCO_CLOSE_E:
- /* remove listening connection */
- /* Ignore the event. Keep listening SCO for the active SLC */
- LOG_WARN("BTA_AG_SCO_LISTEN_ST: Ignoring event %s[%d]",
- bta_ag_sco_evt_str(event), event);
- break;
-
- case BTA_AG_SCO_CONN_CLOSE_E:
- /* sco failed; create sco listen connection */
- bta_ag_create_sco(p_scb, false);
- p_sco->state = BTA_AG_SCO_LISTEN_ST;
- break;
-
- default:
- LOG_WARN("BTA_AG_SCO_LISTEN_ST: Ignoring event %s[%d]",
- bta_ag_sco_evt_str(event), event);
- break;
- }
- break;
-
- case BTA_AG_SCO_CODEC_ST:
- switch (event) {
- case BTA_AG_SCO_LISTEN_E:
- /* create sco listen connection (Additional channel) */
- bta_ag_create_sco(p_scb, false);
- break;
-
- case BTA_AG_SCO_CN_DONE_E:
- /* create sco connection to peer */
- bta_ag_create_sco(p_scb, true);
- p_sco->state = BTA_AG_SCO_OPENING_ST;
- break;
-
- case BTA_AG_SCO_XFER_E:
- /* save xfer scb */
- p_sco->p_xfer_scb = p_scb;
- p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
- break;
-
- case BTA_AG_SCO_SHUTDOWN_E:
- /* remove listening connection */
- bta_ag_remove_sco(p_scb, false);
-
- if (p_scb == p_sco->p_curr_scb) p_sco->p_curr_scb = nullptr;
-
- /* If last SCO instance then finish shutting down */
- if (!bta_ag_other_scb_open(p_scb)) {
- p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
- }
- break;
-
- case BTA_AG_SCO_CLOSE_E:
- /* sco open is not started yet. just go back to listening */
- p_sco->state = BTA_AG_SCO_LISTEN_ST;
- break;
-
- case BTA_AG_SCO_CONN_CLOSE_E:
- /* sco failed; create sco listen connection */
- bta_ag_create_sco(p_scb, false);
- p_sco->state = BTA_AG_SCO_LISTEN_ST;
- break;
-
- default:
- LOG_WARN("BTA_AG_SCO_CODEC_ST: Ignoring event %s[%d]",
- bta_ag_sco_evt_str(event), event);
- break;
- }
- break;
-
- case BTA_AG_SCO_OPENING_ST:
- switch (event) {
- case BTA_AG_SCO_LISTEN_E:
- /* second headset has now joined */
- /* create sco listen connection (Additional channel) */
- if (p_scb != p_sco->p_curr_scb) {
- bta_ag_create_sco(p_scb, false);
- }
- break;
-
-#if (DISABLE_WBS == FALSE)
- case BTA_AG_SCO_REOPEN_E:
- /* start codec negotiation */
- p_sco->state = BTA_AG_SCO_CODEC_ST;
- bta_ag_codec_negotiate(p_scb);
- break;
-#endif
-
- case BTA_AG_SCO_XFER_E:
- /* save xfer scb */
- p_sco->p_xfer_scb = p_scb;
- p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
- break;
-
- case BTA_AG_SCO_CLOSE_E:
- p_sco->state = BTA_AG_SCO_OPEN_CL_ST;
- break;
-
- case BTA_AG_SCO_SHUTDOWN_E:
- /* If not opening scb, just close it */
- if (p_scb != p_sco->p_curr_scb) {
- /* remove listening connection */
- bta_ag_remove_sco(p_scb, false);
- } else
- p_sco->state = BTA_AG_SCO_SHUTTING_ST;
-
- break;
-
- case BTA_AG_SCO_CONN_OPEN_E:
- p_sco->state = BTA_AG_SCO_OPEN_ST;
- break;
-
- case BTA_AG_SCO_CONN_CLOSE_E:
- /* sco failed; create sco listen connection */
- bta_ag_create_sco(p_scb, false);
- p_sco->state = BTA_AG_SCO_LISTEN_ST;
- break;
-
- default:
- LOG_WARN("BTA_AG_SCO_OPENING_ST: Ignoring event %s[%d]",
- bta_ag_sco_evt_str(event), event);
- break;
- }
- break;
-
- case BTA_AG_SCO_OPEN_CL_ST:
- switch (event) {
- case BTA_AG_SCO_XFER_E:
- /* save xfer scb */
- p_sco->p_xfer_scb = p_scb;
-
- p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
- break;
-
- case BTA_AG_SCO_OPEN_E:
- p_sco->state = BTA_AG_SCO_OPENING_ST;
- break;
-
- case BTA_AG_SCO_SHUTDOWN_E:
- /* If not opening scb, just close it */
- if (p_scb != p_sco->p_curr_scb) {
- /* remove listening connection */
- bta_ag_remove_sco(p_scb, false);
- } else
- p_sco->state = BTA_AG_SCO_SHUTTING_ST;
-
- break;
-
- case BTA_AG_SCO_CONN_OPEN_E:
- /* close sco connection */
- bta_ag_remove_sco(p_scb, true);
-
- p_sco->state = BTA_AG_SCO_CLOSING_ST;
- break;
-
- case BTA_AG_SCO_CONN_CLOSE_E:
- /* sco failed; create sco listen connection */
-
- p_sco->state = BTA_AG_SCO_LISTEN_ST;
- break;
-
- default:
- LOG_WARN("BTA_AG_SCO_OPEN_CL_ST: Ignoring event %s[%d]",
- bta_ag_sco_evt_str(event), event);
- break;
- }
- break;
-
- case BTA_AG_SCO_OPEN_XFER_ST:
- switch (event) {
- case BTA_AG_SCO_CLOSE_E:
- /* close sco connection */
- bta_ag_remove_sco(p_scb, true);
-
- p_sco->state = BTA_AG_SCO_CLOSING_ST;
- break;
-
- case BTA_AG_SCO_SHUTDOWN_E:
- /* remove all connection */
- bta_ag_remove_sco(p_scb, false);
- p_sco->state = BTA_AG_SCO_SHUTTING_ST;
-
- break;
-
- case BTA_AG_SCO_CONN_CLOSE_E:
- /* closed sco; place in listen mode and
- accept the transferred connection */
- bta_ag_create_sco(p_scb, false); /* Back into listen mode */
-
- /* Accept sco connection with xfer scb */
- bta_ag_sco_conn_rsp(p_sco->p_xfer_scb, &p_sco->conn_data);
- p_sco->state = BTA_AG_SCO_OPENING_ST;
- p_sco->p_curr_scb = p_sco->p_xfer_scb;
- p_sco->cur_idx = p_sco->p_xfer_scb->sco_idx;
- p_sco->p_xfer_scb = nullptr;
- break;
-
- default:
- LOG_WARN("BTA_AG_SCO_OPEN_XFER_ST: Ignoring event %s[%d]",
- bta_ag_sco_evt_str(event), event);
- break;
- }
- break;
-
- case BTA_AG_SCO_OPEN_ST:
- switch (event) {
- case BTA_AG_SCO_LISTEN_E:
- /* second headset has now joined */
- /* create sco listen connection (Additional channel) */
- if (p_scb != p_sco->p_curr_scb) {
- bta_ag_create_sco(p_scb, false);
- }
- break;
-
- case BTA_AG_SCO_XFER_E:
- /* close current sco connection */
- bta_ag_remove_sco(p_sco->p_curr_scb, true);
-
- /* save xfer scb */
- p_sco->p_xfer_scb = p_scb;
-
- p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
- break;
-
- case BTA_AG_SCO_CLOSE_E:
- /* close sco connection if active */
- if (bta_ag_remove_sco(p_scb, true)) {
- p_sco->state = BTA_AG_SCO_CLOSING_ST;
- }
- break;
-
- case BTA_AG_SCO_SHUTDOWN_E:
- /* remove all listening connections */
- bta_ag_remove_sco(p_scb, false);
-
- /* If SCO was active on this scb, close it */
- if (p_scb == p_sco->p_curr_scb) {
- p_sco->state = BTA_AG_SCO_SHUTTING_ST;
- }
- break;
-
- case BTA_AG_SCO_CONN_CLOSE_E:
- /* peer closed sco; create sco listen connection */
- bta_ag_create_sco(p_scb, false);
- p_sco->state = BTA_AG_SCO_LISTEN_ST;
- break;
-
- default:
- LOG_WARN("BTA_AG_SCO_OPEN_ST: Ignoring event %s[%d]",
- bta_ag_sco_evt_str(event), event);
- break;
- }
- break;
-
- case BTA_AG_SCO_CLOSING_ST:
- switch (event) {
- case BTA_AG_SCO_LISTEN_E:
- /* create sco listen connection (Additional channel) */
- if (p_scb != p_sco->p_curr_scb) {
- bta_ag_create_sco(p_scb, false);
- }
- break;
-
- case BTA_AG_SCO_OPEN_E:
- p_sco->state = BTA_AG_SCO_CLOSE_OP_ST;
- break;
-
- case BTA_AG_SCO_XFER_E:
- /* save xfer scb */
- p_sco->p_xfer_scb = p_scb;
-
- p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
- break;
-
- case BTA_AG_SCO_SHUTDOWN_E:
- /* If not closing scb, just close it */
- if (p_scb != p_sco->p_curr_scb) {
- /* remove listening connection */
- bta_ag_remove_sco(p_scb, false);
- } else
- p_sco->state = BTA_AG_SCO_SHUTTING_ST;
-
- break;
-
- case BTA_AG_SCO_CONN_CLOSE_E:
- /* peer closed sco; create sco listen connection */
- bta_ag_create_sco(p_scb, false);
-
- p_sco->state = BTA_AG_SCO_LISTEN_ST;
- break;
-
- default:
- LOG_WARN("BTA_AG_SCO_CLOSING_ST: Ignoring event %s[%d]",
- bta_ag_sco_evt_str(event), event);
- break;
- }
- break;
-
- case BTA_AG_SCO_CLOSE_OP_ST:
- switch (event) {
- case BTA_AG_SCO_CLOSE_E:
- p_sco->state = BTA_AG_SCO_CLOSING_ST;
- break;
-
- case BTA_AG_SCO_SHUTDOWN_E:
- p_sco->state = BTA_AG_SCO_SHUTTING_ST;
- break;
-
- case BTA_AG_SCO_CONN_CLOSE_E:
- /* start codec negotiation */
- p_sco->state = BTA_AG_SCO_CODEC_ST;
- bta_ag_codec_negotiate(p_scb);
- break;
-
- case BTA_AG_SCO_LISTEN_E:
- /* create sco listen connection (Additional channel) */
- if (p_scb != p_sco->p_curr_scb) {
- bta_ag_create_sco(p_scb, false);
- }
- break;
-
- default:
- LOG_WARN("BTA_AG_SCO_CLOSE_OP_ST: Ignoring event %s[%d]",
- bta_ag_sco_evt_str(event), event);
- break;
- }
- break;
-
- case BTA_AG_SCO_CLOSE_XFER_ST:
- switch (event) {
- case BTA_AG_SCO_CONN_OPEN_E:
- /* close sco connection so headset can be transferred
- Probably entered this state from "opening state" */
- bta_ag_remove_sco(p_scb, true);
- break;
-
- case BTA_AG_SCO_CLOSE_E:
- /* clear xfer scb */
- p_sco->p_xfer_scb = nullptr;
-
- p_sco->state = BTA_AG_SCO_CLOSING_ST;
- break;
-
- case BTA_AG_SCO_SHUTDOWN_E:
- /* clear xfer scb */
- p_sco->p_xfer_scb = nullptr;
-
- p_sco->state = BTA_AG_SCO_SHUTTING_ST;
- break;
-
- case BTA_AG_SCO_CONN_CLOSE_E: {
- /* closed sco; place old sco in listen mode,
- take current sco out of listen, and
- create originating sco for current */
- bta_ag_create_sco(p_scb, false);
- bta_ag_remove_sco(p_sco->p_xfer_scb, false);
-
-#if (DISABLE_WBS == FALSE)
- /* start codec negotiation */
- p_sco->state = BTA_AG_SCO_CODEC_ST;
- tBTA_AG_SCB* p_cn_scb = p_sco->p_xfer_scb;
- p_sco->p_xfer_scb = nullptr;
- bta_ag_codec_negotiate(p_cn_scb);
-#else
- /* create sco connection to peer */
- bta_ag_create_sco(p_sco->p_xfer_scb, true);
- p_sco->p_xfer_scb = nullptr;
- p_sco->state = BTA_AG_SCO_OPENING_ST;
-#endif
- break;
- }
-
- default:
- LOG_WARN(" BTA_AG_SCO_CLOSE_XFER_ST: Ignoring event %s[%d]",
- bta_ag_sco_evt_str(event), event);
- break;
- }
- break;
-
- case BTA_AG_SCO_SHUTTING_ST:
- switch (event) {
- case BTA_AG_SCO_CONN_OPEN_E:
- /* close sco connection; wait for conn close event */
- bta_ag_remove_sco(p_scb, true);
- break;
-
- case BTA_AG_SCO_CONN_CLOSE_E:
- /* If last SCO instance then finish shutting down */
- if (!bta_ag_other_scb_open(p_scb)) {
- p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
- } else /* Other instance is still listening */
- {
- p_sco->state = BTA_AG_SCO_LISTEN_ST;
- }
-
- /* If SCO closed for other HS which is not being disconnected,
- then create listen sco connection for it as scb still open */
- if (bta_ag_scb_open(p_scb)) {
- bta_ag_create_sco(p_scb, false);
- p_sco->state = BTA_AG_SCO_LISTEN_ST;
- }
-
- if (p_scb == p_sco->p_curr_scb) {
- p_sco->p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX;
- p_sco->p_curr_scb = nullptr;
- }
- break;
-
- case BTA_AG_SCO_LISTEN_E:
- /* create sco listen connection (Additional channel) */
- if (p_scb != p_sco->p_curr_scb) {
- bta_ag_create_sco(p_scb, false);
- }
- break;
-
- case BTA_AG_SCO_SHUTDOWN_E:
- if (!bta_ag_other_scb_open(p_scb)) {
- p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
- } else /* Other instance is still listening */
- {
- p_sco->state = BTA_AG_SCO_LISTEN_ST;
- }
-
- if (p_scb == p_sco->p_curr_scb) {
- p_sco->p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX;
- p_sco->p_curr_scb = nullptr;
- }
- break;
-
- default:
- LOG_WARN("BTA_AG_SCO_SHUTTING_ST: Ignoring event %s[%d]",
- bta_ag_sco_evt_str(event), event);
- break;
- }
- break;
-
- default:
- break;
- }
- if (p_sco->state != previous_state) {
- LOG_WARN(
- "SCO_state_change: [%s(0x%02x)]->[%s(0x%02x)] "
- "after event [%s(0x%02x)]",
- bta_ag_sco_state_str(previous_state), previous_state,
- bta_ag_sco_state_str(p_sco->state), p_sco->state,
- bta_ag_sco_evt_str(event), event);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_sco_is_open
- *
- * Description Check if sco is open for this scb.
- *
- *
- * Returns true if sco open for this scb, false otherwise.
- *
- ******************************************************************************/
-bool bta_ag_sco_is_open(tBTA_AG_SCB* p_scb) {
- return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_ST) &&
- (bta_ag_cb.sco.p_curr_scb == p_scb));
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_sco_is_opening
- *
- * Description Check if sco is in Opening state.
- *
- *
- * Returns true if sco is in Opening state for this scb, false
- * otherwise.
- *
- ******************************************************************************/
-bool bta_ag_sco_is_opening(tBTA_AG_SCB* p_scb) {
- return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST) &&
- (bta_ag_cb.sco.p_curr_scb == p_scb));
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_sco_listen
- *
- * Description
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_sco_listen(tBTA_AG_SCB* p_scb,
- UNUSED_ATTR const tBTA_AG_DATA& data) {
- LOG(INFO) << __func__ << ": " << p_scb->peer_addr;
- bta_ag_sco_event(p_scb, BTA_AG_SCO_LISTEN_E);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_sco_open
- *
- * Description
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_sco_open(tBTA_AG_SCB* p_scb, UNUSED_ATTR const tBTA_AG_DATA& data) {
- if (!sco_allowed) {
- LOG(INFO) << __func__ << ": not opening sco, by policy";
- return;
- }
- /* if another scb using sco, this is a transfer */
- if (bta_ag_cb.sco.p_curr_scb && bta_ag_cb.sco.p_curr_scb != p_scb) {
- LOG(INFO) << __func__ << ": transfer "
- << bta_ag_cb.sco.p_curr_scb->peer_addr << " -> "
- << p_scb->peer_addr;
- bta_ag_sco_event(p_scb, BTA_AG_SCO_XFER_E);
- } else {
- /* else it is an open */
- LOG(INFO) << __func__ << ": open " << p_scb->peer_addr;
- bta_ag_sco_event(p_scb, BTA_AG_SCO_OPEN_E);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_sco_close
- *
- * Description
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_sco_close(tBTA_AG_SCB* p_scb,
- UNUSED_ATTR const tBTA_AG_DATA& data) {
- /* if scb is in use */
- /* sco_idx is not allocated in SCO_CODEC_ST, still need to move to listen
- * state. */
- if ((p_scb->sco_idx != BTM_INVALID_SCO_INDEX) ||
- (bta_ag_cb.sco.state == BTA_AG_SCO_CODEC_ST)) {
- APPL_TRACE_DEBUG("bta_ag_sco_close: sco_inx = %d", p_scb->sco_idx);
- bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_sco_codec_nego
- *
- * Description Handles result of eSCO codec negotiation
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_sco_codec_nego(tBTA_AG_SCB* p_scb, bool result) {
- if (result) {
- /* Subsequent SCO connection will skip codec negotiation */
- LOG_INFO("Succeeded for index 0x%04x, device %s", p_scb->sco_idx,
- p_scb->peer_addr.ToString().c_str());
- p_scb->codec_updated = false;
- bta_ag_sco_event(p_scb, BTA_AG_SCO_CN_DONE_E);
- } else {
- /* codec negotiation failed */
- LOG_INFO("Failed for index 0x%04x, device %s", p_scb->sco_idx,
- p_scb->peer_addr.ToString().c_str());
- bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_sco_shutdown
- *
- * Description
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_sco_shutdown(tBTA_AG_SCB* p_scb,
- UNUSED_ATTR const tBTA_AG_DATA& data) {
- bta_ag_sco_event(p_scb, BTA_AG_SCO_SHUTDOWN_E);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_sco_conn_open
- *
- * Description
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_sco_conn_open(tBTA_AG_SCB* p_scb,
- UNUSED_ATTR const tBTA_AG_DATA& data) {
- bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_OPEN_E);
-
- bta_sys_sco_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
-
- /* call app callback */
- bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_OPEN_EVT);
-
- /* reset to mSBC T2 settings as the preferred */
- p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_sco_conn_close
- *
- * Description
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_sco_conn_close(tBTA_AG_SCB* p_scb,
- UNUSED_ATTR const tBTA_AG_DATA& data) {
- /* clear current scb */
- bta_ag_cb.sco.p_curr_scb = nullptr;
- p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
-
- /* codec_fallback is set when AG is initiator and connection failed for mSBC.
- * OR if codec is msbc and T2 settings failed, then retry Safe T1 settings */
- if (p_scb->svc_conn &&
- (p_scb->codec_fallback ||
- (p_scb->sco_codec == BTM_SCO_CODEC_MSBC &&
- p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T1))) {
- bta_ag_sco_event(p_scb, BTA_AG_SCO_REOPEN_E);
- } else {
- /* Indicate if the closing of audio is because of transfer */
- bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_CLOSE_E);
-
- bta_sys_sco_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
-
- /* if av got suspended by this call, let it resume. */
- /* In case call stays alive regardless of sco, av should not be affected. */
- if (((p_scb->call_ind == BTA_AG_CALL_INACTIVE) &&
- (p_scb->callsetup_ind == BTA_AG_CALLSETUP_NONE)) ||
- (p_scb->post_sco == BTA_AG_POST_SCO_CALL_END)) {
- bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
- }
-
- /* call app callback */
- bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
- p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_sco_conn_rsp
- *
- * Description Process the SCO connection request
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_sco_conn_rsp(tBTA_AG_SCB* p_scb,
- tBTM_ESCO_CONN_REQ_EVT_DATA* p_data) {
- bta_ag_cb.sco.is_local = false;
-
- APPL_TRACE_DEBUG("%s: eSCO %d, state %d", __func__,
- controller_get_interface()
- ->supports_enhanced_setup_synchronous_connection(),
- bta_ag_cb.sco.state);
-
- if (bta_ag_cb.sco.state == BTA_AG_SCO_LISTEN_ST ||
- bta_ag_cb.sco.state == BTA_AG_SCO_CLOSE_XFER_ST ||
- bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_XFER_ST) {
- /* tell sys to stop av if any */
- bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
- /* When HS initiated SCO, it cannot be WBS. */
- }
-
- /* If SCO open was initiated from HS, it must be CVSD */
- p_scb->inuse_codec = BTM_SCO_CODEC_NONE;
- /* Send pending commands to create SCO connection to peer */
- bta_ag_create_pending_sco(p_scb, bta_ag_cb.sco.is_local);
-}
-
-void bta_ag_set_sco_allowed(bool value) {
- sco_allowed = value;
- APPL_TRACE_DEBUG(sco_allowed ? "sco now allowed" : "sco now not allowed");
-}
-
-const RawAddress& bta_ag_get_active_device() { return active_device_addr; }
-
-void bta_clear_active_device() { active_device_addr = RawAddress::kEmpty; }
-
-void bta_ag_api_set_active_device(const RawAddress& new_active_device) {
- if (new_active_device.IsEmpty()) {
- APPL_TRACE_ERROR("%s: empty device", __func__);
- return;
- }
- active_device_addr = new_active_device;
-}
diff --git a/bta/ag/bta_ag_sdp.cc b/bta/ag/bta_ag_sdp.cc
deleted file mode 100644
index e9af15c..0000000
--- a/bta/ag/bta_ag_sdp.cc
+++ /dev/null
@@ -1,519 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains the audio gateway functions performing SDP
- * operations.
- *
- ******************************************************************************/
-
-#include <base/bind.h>
-#include <base/location.h>
-#include <base/logging.h>
-
-#include "bt_target.h" // Legacy stack config
-#include "bt_trace.h" // Legacy trace logging
-
-#include "bta/ag/bta_ag_int.h"
-#include "btif/include/btif_config.h"
-#include "osi/include/allocator.h"
-#include "stack/include/btm_api.h"
-#include "stack/include/btu.h" // do_in_main_thread
-#include "stack/include/port_api.h"
-#include "types/bluetooth/uuid.h"
-
-using bluetooth::Uuid;
-
-/* Number of protocol elements in protocol element list. */
-#define BTA_AG_NUM_PROTO_ELEMS 2
-
-/* Number of elements in service class id list. */
-#define BTA_AG_NUM_SVC_ELEMS 2
-
-/* size of database for service discovery */
-#ifndef BTA_AG_DISC_BUF_SIZE
-#define BTA_AG_DISC_BUF_SIZE BT_DEFAULT_BUFFER_SIZE
-#endif
-
-/* declare sdp callback functions */
-void bta_ag_sdp_cback_1(tSDP_RESULT);
-void bta_ag_sdp_cback_2(tSDP_RESULT);
-void bta_ag_sdp_cback_3(tSDP_RESULT);
-void bta_ag_sdp_cback_4(tSDP_RESULT);
-void bta_ag_sdp_cback_5(tSDP_RESULT);
-void bta_ag_sdp_cback_6(tSDP_RESULT);
-
-/* SDP callback function table */
-typedef tSDP_DISC_CMPL_CB* tBTA_AG_SDP_CBACK;
-const tBTA_AG_SDP_CBACK bta_ag_sdp_cback_tbl[] = {
- bta_ag_sdp_cback_1, bta_ag_sdp_cback_2, bta_ag_sdp_cback_3,
- bta_ag_sdp_cback_4, bta_ag_sdp_cback_5, bta_ag_sdp_cback_6};
-
-/*******************************************************************************
- *
- * Function bta_ag_sdp_cback
- *
- * Description SDP callback function.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ag_sdp_cback(uint16_t status, uint8_t idx) {
- APPL_TRACE_DEBUG("%s status:0x%x", __func__, status);
- tBTA_AG_SCB* p_scb = bta_ag_scb_by_idx(idx);
- if (p_scb) {
- uint16_t event;
- /* set event according to int/acp */
- if (p_scb->role == BTA_AG_ACP) {
- event = BTA_AG_DISC_ACP_RES_EVT;
- } else {
- event = BTA_AG_DISC_INT_RES_EVT;
- }
- tBTA_AG_DATA disc_result = {.disc_result = {.status = status}};
- do_in_main_thread(FROM_HERE, base::Bind(&bta_ag_sm_execute_by_handle, idx,
- event, disc_result));
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_sdp_cback_1 to 6
- *
- * Description SDP callback functions. Since there is no way to
- * distinguish scb from the callback we need separate
- * callbacks for each scb.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_sdp_cback_1(tSDP_STATUS status) { bta_ag_sdp_cback(status, 1); }
-void bta_ag_sdp_cback_2(tSDP_STATUS status) { bta_ag_sdp_cback(status, 2); }
-void bta_ag_sdp_cback_3(tSDP_STATUS status) { bta_ag_sdp_cback(status, 3); }
-void bta_ag_sdp_cback_4(tSDP_STATUS status) { bta_ag_sdp_cback(status, 4); }
-void bta_ag_sdp_cback_5(tSDP_STATUS status) { bta_ag_sdp_cback(status, 5); }
-void bta_ag_sdp_cback_6(tSDP_STATUS status) { bta_ag_sdp_cback(status, 6); }
-
-/******************************************************************************
- *
- * Function bta_ag_add_record
- *
- * Description This function is called by a server application to add
- * HSP or HFP information to an SDP record. Prior to
- * calling this function the application must call
- * SDP_CreateRecord() to create an SDP record.
- *
- * Returns true if function execution succeeded,
- * false if function execution failed.
- *
- *****************************************************************************/
-bool bta_ag_add_record(uint16_t service_uuid, const char* p_service_name,
- uint8_t scn, tBTA_AG_FEAT features,
- uint32_t sdp_handle) {
- tSDP_PROTOCOL_ELEM proto_elem_list[BTA_AG_NUM_PROTO_ELEMS];
- uint16_t svc_class_id_list[BTA_AG_NUM_SVC_ELEMS];
- uint16_t browse_list[] = {UUID_SERVCLASS_PUBLIC_BROWSE_GROUP};
- uint16_t version;
- uint16_t profile_uuid;
- uint8_t network;
- bool result = true;
- bool codec_supported = false;
- uint8_t buf[2];
-
- APPL_TRACE_DEBUG("%s uuid: %x", __func__, service_uuid);
-
- for (auto& proto_element : proto_elem_list) {
- proto_element = {};
- }
-
- /* add the protocol element sequence */
- proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
- proto_elem_list[0].num_params = 0;
- proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
- proto_elem_list[1].num_params = 1;
- proto_elem_list[1].params[0] = scn;
- result &=
- SDP_AddProtocolList(sdp_handle, BTA_AG_NUM_PROTO_ELEMS, proto_elem_list);
-
- /* add service class id list */
- svc_class_id_list[0] = service_uuid;
- svc_class_id_list[1] = UUID_SERVCLASS_GENERIC_AUDIO;
- result &= SDP_AddServiceClassIdList(sdp_handle, BTA_AG_NUM_SVC_ELEMS,
- svc_class_id_list);
-
- /* add profile descriptor list */
- if (service_uuid == UUID_SERVCLASS_AG_HANDSFREE) {
- profile_uuid = UUID_SERVCLASS_HF_HANDSFREE;
- version = BTA_HFP_VERSION;
- } else {
- profile_uuid = UUID_SERVCLASS_HEADSET;
- version = HSP_VERSION_1_2;
- }
- result &= SDP_AddProfileDescriptorList(sdp_handle, profile_uuid, version);
-
- /* add service name */
- if (p_service_name != nullptr && p_service_name[0] != 0) {
- result &= SDP_AddAttribute(
- sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
- (uint32_t)(strlen(p_service_name) + 1), (uint8_t*)p_service_name);
- }
-
- /* add features and network */
- if (service_uuid == UUID_SERVCLASS_AG_HANDSFREE) {
- network = (features & BTA_AG_FEAT_REJECT) ? 1 : 0;
- result &= SDP_AddAttribute(sdp_handle, ATTR_ID_DATA_STORES_OR_NETWORK,
- UINT_DESC_TYPE, 1, &network);
-
- if (features & BTA_AG_FEAT_CODEC) codec_supported = true;
-
- features &= BTA_AG_SDP_FEAT_SPEC;
-
- /* Codec bit position is different in SDP and in BRSF */
- if (codec_supported) features |= 0x0020;
-
- UINT16_TO_BE_FIELD(buf, features);
- result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_FEATURES,
- UINT_DESC_TYPE, 2, buf);
- }
-
- /* add browse group list */
- result &= SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1,
- browse_list);
-
- return result;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_create_records
- *
- * Description Create SDP records for registered services.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_create_records(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- int i;
- tBTA_SERVICE_MASK services;
-
- services = p_scb->reg_services >> BTA_HSP_SERVICE_ID;
- for (i = 0; i < BTA_AG_NUM_IDX && services != 0; i++, services >>= 1) {
- /* if service is set in mask */
- if (services & 1) {
- /* add sdp record if not already registered */
- if (bta_ag_cb.profile[i].sdp_handle == 0) {
- bta_ag_cb.profile[i].sdp_handle = SDP_CreateRecord();
- bta_ag_cb.profile[i].scn = BTM_AllocateSCN();
- bta_ag_add_record(bta_ag_uuid[i], data.api_register.p_name[i],
- bta_ag_cb.profile[i].scn, data.api_register.features,
- bta_ag_cb.profile[i].sdp_handle);
- bta_sys_add_uuid(bta_ag_uuid[i]);
- }
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_del_records
- *
- * Description Delete SDP records for any registered services.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_del_records(tBTA_AG_SCB* p_scb) {
- tBTA_AG_SCB* p = &bta_ag_cb.scb[0];
- tBTA_SERVICE_MASK services;
- tBTA_SERVICE_MASK others = 0;
- int i;
-
- /* get services of all other registered servers */
- for (i = 0; i < BTA_AG_NUM_IDX; i++, p++) {
- if (p_scb == p) {
- continue;
- }
-
- if (p->in_use && !p->dealloc) {
- others |= p->reg_services;
- }
- }
-
- others >>= BTA_HSP_SERVICE_ID;
- services = p_scb->reg_services >> BTA_HSP_SERVICE_ID;
- for (i = 0; i < BTA_AG_NUM_IDX && services != 0;
- i++, services >>= 1, others >>= 1) {
- /* if service registered for this scb and not registered for any other scb
- */
- if (((services & 1) == 1) && ((others & 1) == 0)) {
- APPL_TRACE_DEBUG("bta_ag_del_records %d", i);
- if (bta_ag_cb.profile[i].sdp_handle != 0) {
- SDP_DeleteRecord(bta_ag_cb.profile[i].sdp_handle);
- bta_ag_cb.profile[i].sdp_handle = 0;
- }
- BTM_FreeSCN(bta_ag_cb.profile[i].scn);
- RFCOMM_ClearSecurityRecord(bta_ag_cb.profile[i].scn);
- bta_sys_remove_uuid(bta_ag_uuid[i]);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_sdp_find_attr
- *
- * Description Process SDP discovery results to find requested attributes
- * for requested service.
- *
- *
- * Returns true if results found, false otherwise.
- *
- ******************************************************************************/
-bool bta_ag_sdp_find_attr(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) {
- tSDP_DISC_REC* p_rec = nullptr;
- tSDP_DISC_ATTR* p_attr;
- tSDP_PROTOCOL_ELEM pe;
- uint16_t uuid;
- bool result = false;
-
- if (service & BTA_HFP_SERVICE_MASK) {
- uuid = UUID_SERVCLASS_HF_HANDSFREE;
- /* If there is no cached peer version, use default one */
- if (p_scb->peer_version == HFP_HSP_VERSION_UNKNOWN) {
- p_scb->peer_version = HFP_VERSION_1_1; /* Default version */
- }
- } else if (service & BTA_HSP_SERVICE_MASK && p_scb->role == BTA_AG_INT) {
- uuid = UUID_SERVCLASS_HEADSET_HS;
- p_scb->peer_version = HSP_VERSION_1_2; /* Default version */
- } else {
- uuid = UUID_SERVCLASS_HEADSET_HS;
- p_scb->peer_version = HSP_VERSION_1_0;
- }
-
- /* loop through all records we found */
- while (true) {
- /* get next record; if none found, we're done */
- p_rec = SDP_FindServiceInDb(p_scb->p_disc_db, uuid, p_rec);
- if (p_rec == nullptr) {
- if (uuid == UUID_SERVCLASS_HEADSET_HS) {
- /* Search again in case the peer device uses the old HSP UUID */
- uuid = UUID_SERVCLASS_HEADSET;
- p_scb->peer_version = HSP_VERSION_1_0;
- p_rec = SDP_FindServiceInDb(p_scb->p_disc_db, uuid, p_rec);
- if (p_rec == nullptr) {
- break;
- }
- } else
- break;
- }
-
- /* get scn from proto desc list if initiator */
- if (p_scb->role == BTA_AG_INT) {
- if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
- p_scb->peer_scn = (uint8_t)pe.params[0];
- } else {
- continue;
- }
- }
-
- /* get profile version (if failure, version parameter is not updated) */
- uint16_t peer_version = HFP_HSP_VERSION_UNKNOWN;
- if (!SDP_FindProfileVersionInRec(p_rec, uuid, &peer_version)) {
- APPL_TRACE_WARNING("%s: Get peer_version failed, using default 0x%04x",
- __func__, p_scb->peer_version);
- peer_version = p_scb->peer_version;
- }
-
- if (service & BTA_HFP_SERVICE_MASK) {
- /* Update cached peer version if the new one is different */
- if (peer_version != p_scb->peer_version) {
- p_scb->peer_version = peer_version;
- if (btif_config_set_bin(
- p_scb->peer_addr.ToString(), HFP_VERSION_CONFIG_KEY,
- (const uint8_t*)&peer_version, sizeof(peer_version))) {
- btif_config_save();
- } else {
- APPL_TRACE_WARNING("%s: Failed to store peer HFP version for %s",
- __func__, p_scb->peer_addr.ToString().c_str());
- }
- }
- /* get features if HFP */
- p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES);
- if (p_attr != nullptr) {
- /* Found attribute. Get value. */
- /* There might be race condition between SDP and BRSF. */
- /* Do not update if we already received BRSF. */
- uint16_t sdp_features = p_attr->attr_value.v.u16;
- bool sdp_wbs_support = sdp_features & BTA_AG_FEAT_WBS_SUPPORT;
- if (!p_scb->received_at_bac && sdp_wbs_support) {
- // Workaround for misbehaving HFs (e.g. some Hyundai car kit) that:
- // 1. Indicate WBS support in SDP and codec negotiation in BRSF
- // 2. But do not send required AT+BAC command
- // Will assume mSBC is enabled and try codec negotiation by default
- p_scb->codec_updated = true;
- p_scb->peer_codecs = BTM_SCO_CODEC_CVSD & BTM_SCO_CODEC_MSBC;
- p_scb->sco_codec = UUID_CODEC_MSBC;
- }
- if (sdp_features != p_scb->peer_sdp_features) {
- p_scb->peer_sdp_features = sdp_features;
- if (btif_config_set_bin(
- p_scb->peer_addr.ToString(), HFP_SDP_FEATURES_CONFIG_KEY,
- (const uint8_t*)&sdp_features, sizeof(sdp_features))) {
- btif_config_save();
- } else {
- APPL_TRACE_WARNING(
- "%s: Failed to store peer HFP SDP Features for %s", __func__,
- p_scb->peer_addr.ToString().c_str());
- }
- }
- if (p_scb->peer_features == 0) {
- p_scb->peer_features = sdp_features & HFP_SDP_BRSF_FEATURES_MASK;
- }
- }
- } else {
- /* No peer version caching for HSP, use discovered one directly */
- p_scb->peer_version = peer_version;
- /* get features if HSP */
- p_attr =
- SDP_FindAttributeInRec(p_rec, ATTR_ID_REMOTE_AUDIO_VOLUME_CONTROL);
- if (p_attr != nullptr) {
- /* Remote volume control of HSP */
- if (p_attr->attr_value.v.u8)
- p_scb->peer_features |= BTA_AG_PEER_FEAT_VOL;
- else
- p_scb->peer_features &= ~BTA_AG_PEER_FEAT_VOL;
- }
- }
-
- /* found what we needed */
- result = true;
- break;
- }
- return result;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_do_disc
- *
- * Description Do service discovery.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_do_disc(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) {
- Uuid uuid_list[1];
- uint16_t num_uuid = 1;
- uint16_t attr_list[4];
- uint8_t num_attr;
-
- /* HFP initiator; get proto list and features */
- if (service & BTA_HFP_SERVICE_MASK && p_scb->role == BTA_AG_INT) {
- attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
- attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
- attr_list[2] = ATTR_ID_BT_PROFILE_DESC_LIST;
- attr_list[3] = ATTR_ID_SUPPORTED_FEATURES;
- num_attr = 4;
- uuid_list[0] = Uuid::From16Bit(UUID_SERVCLASS_HF_HANDSFREE);
- }
- /* HFP acceptor; get features */
- else if (service & BTA_HFP_SERVICE_MASK && p_scb->role == BTA_AG_ACP) {
- attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
- attr_list[1] = ATTR_ID_BT_PROFILE_DESC_LIST;
- attr_list[2] = ATTR_ID_SUPPORTED_FEATURES;
- num_attr = 3;
- uuid_list[0] = Uuid::From16Bit(UUID_SERVCLASS_HF_HANDSFREE);
- }
- /* HSP initiator; get proto list */
- else if (service & BTA_HSP_SERVICE_MASK && p_scb->role == BTA_AG_INT) {
- attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
- attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
- attr_list[2] = ATTR_ID_BT_PROFILE_DESC_LIST;
- attr_list[3] = ATTR_ID_REMOTE_AUDIO_VOLUME_CONTROL;
- num_attr = 4;
- // Although UUID_SERVCLASS_HEADSET_HS (0x1131) is to be used in HSP 1.2,
- // some HSP 1.2 implementations, such as PTS, still use
- // UUID_SERVCLASS_HEADSET (0x1108) to store its service record. However,
- // most of such devices are HSP 1.0 devices.
- if (p_scb->hsp_version >= HSP_VERSION_1_2) {
- uuid_list[0] = Uuid::From16Bit(UUID_SERVCLASS_HEADSET_HS);
- } else {
- uuid_list[0] = Uuid::From16Bit(UUID_SERVCLASS_HEADSET);
- }
- } else {
- /* HSP acceptor; get features */
- attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
- attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
- attr_list[2] = ATTR_ID_BT_PROFILE_DESC_LIST;
- attr_list[3] = ATTR_ID_REMOTE_AUDIO_VOLUME_CONTROL;
- num_attr = 4;
-
- if (p_scb->hsp_version >= HSP_VERSION_1_2) {
- uuid_list[0] = Uuid::From16Bit(UUID_SERVCLASS_HEADSET_HS);
- } else {
- /* Legacy from HSP v1.0 */
- uuid_list[0] = Uuid::From16Bit(UUID_SERVCLASS_HEADSET);
- }
- }
-
- if (p_scb->p_disc_db != nullptr) {
- android_errorWriteLog(0x534e4554, "174052148");
- LOG_ERROR("Discovery already in progress... returning.");
- return;
- }
-
- /* allocate buffer for sdp database */
- p_scb->p_disc_db = (tSDP_DISCOVERY_DB*)osi_malloc(BTA_AG_DISC_BUF_SIZE);
- /* set up service discovery database; attr happens to be attr_list len */
- if (SDP_InitDiscoveryDb(p_scb->p_disc_db, BTA_AG_DISC_BUF_SIZE, num_uuid,
- uuid_list, num_attr, attr_list)) {
- if (SDP_ServiceSearchAttributeRequest(
- p_scb->peer_addr, p_scb->p_disc_db,
- bta_ag_sdp_cback_tbl[bta_ag_scb_to_idx(p_scb) - 1])) {
- return;
- } else {
- LOG(ERROR) << __func__ << ": failed to start SDP discovery for "
- << p_scb->peer_addr;
- }
- } else {
- LOG(ERROR) << __func__ << ": failed to init SDP discovery database for "
- << p_scb->peer_addr;
- }
- // Failure actions
- bta_ag_free_db(p_scb, tBTA_AG_DATA::kEmpty);
- bta_ag_sm_execute(p_scb, BTA_AG_DISC_FAIL_EVT, tBTA_AG_DATA::kEmpty);
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_free_db
- *
- * Description Free discovery database.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ag_free_db(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
- osi_free_and_reset((void**)&p_scb->p_disc_db);
-}
diff --git a/bta/ar/bta_ar.cc b/bta/ar/bta_ar.cc
deleted file mode 100644
index ea6108f..0000000
--- a/bta/ar/bta_ar.cc
+++ /dev/null
@@ -1,239 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2008-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the implementation for the audio/video registration module.
- *
- ******************************************************************************/
-
-#include <cstdint>
-
-#include "bta/ar/bta_ar_int.h"
-#include "bta/sys/bta_sys.h"
-#include "stack/include/avct_api.h"
-#include "stack/include/avrc_api.h"
-#include "types/raw_address.h"
-
-/* AV control block */
-tBTA_AR_CB bta_ar_cb;
-
-/*******************************************************************************
- *
- * Function bta_ar_init
- *
- * Description This function is called to register to AVDTP.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ar_init(void) {
- /* initialize control block */
- memset(&bta_ar_cb, 0, sizeof(tBTA_AR_CB));
-}
-
-/*******************************************************************************
- *
- * Function bta_ar_reg_avdt
- *
- * Description This function is called to register to AVDTP.
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_ar_avdt_cback(uint8_t handle, const RawAddress& bd_addr,
- uint8_t event, tAVDT_CTRL* p_data,
- uint8_t scb_index) {
- /* route the AVDT registration callback to av or avk */
- if (bta_ar_cb.p_av_conn_cback)
- (*bta_ar_cb.p_av_conn_cback)(handle, bd_addr, event, p_data, scb_index);
-}
-
-/*******************************************************************************
- *
- * Function bta_ar_reg_avdt
- *
- * Description AR module registration to AVDT.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ar_reg_avdt(AvdtpRcb* p_reg, tAVDT_CTRL_CBACK* p_cback) {
- bta_ar_cb.p_av_conn_cback = p_cback;
- if (bta_ar_cb.avdt_registered == 0) {
- AVDT_Register(p_reg, bta_ar_avdt_cback);
- } else {
- APPL_TRACE_WARNING("%s: doesn't register again (registered:%d)", __func__,
- bta_ar_cb.avdt_registered);
- }
- bta_ar_cb.avdt_registered |= BTA_AR_AV_MASK;
-}
-
-/*******************************************************************************
- *
- * Function bta_ar_dereg_avdt
- *
- * Description This function is called to de-register from AVDTP.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ar_dereg_avdt() {
- bta_ar_cb.p_av_conn_cback = NULL;
- bta_ar_cb.avdt_registered &= ~BTA_AR_AV_MASK;
-
- if (bta_ar_cb.avdt_registered == 0) AVDT_Deregister();
-}
-
-/*******************************************************************************
- *
- * Function bta_ar_avdt_conn
- *
- * Description This function is called to let ar know that some AVDTP
- * profile is connected for this sys_id.
- * If the other sys modules started a timer for PENDING_EVT,
- * the timer can be stopped now.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ar_avdt_conn(tBTA_SYS_ID sys_id, const RawAddress& bd_addr,
- uint8_t scb_index) {
-}
-
-/*******************************************************************************
- *
- * Function bta_ar_reg_avct
- *
- * Description This function is called to register to AVCTP.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ar_reg_avct() {
- if (bta_ar_cb.avct_registered == 0) {
- AVCT_Register();
- }
- bta_ar_cb.avct_registered |= BTA_AR_AV_MASK;
-}
-
-/*******************************************************************************
- *
- * Function bta_ar_dereg_avct
- *
- * Description This function is called to deregister from AVCTP.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_ar_dereg_avct() {
- bta_ar_cb.avct_registered &= ~BTA_AR_AV_MASK;
-
- if (bta_ar_cb.avct_registered == 0) AVCT_Deregister();
-}
-
-/******************************************************************************
- *
- * Function bta_ar_reg_avrc
- *
- * Description This function is called to register an SDP record for AVRCP.
- *
- * Returns void
- *
- *****************************************************************************/
-void bta_ar_reg_avrc(uint16_t service_uuid, const char* service_name,
- const char* provider_name, uint16_t categories,
- bool browse_supported, uint16_t profile_version) {
- uint8_t mask = BTA_AR_AV_MASK;
- uint8_t temp[8], *p;
-
- if (!categories) return;
-
- if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) {
- if (bta_ar_cb.sdp_tg_handle == 0) {
- bta_ar_cb.tg_registered = mask;
- bta_ar_cb.sdp_tg_handle = SDP_CreateRecord();
- AVRC_AddRecord(service_uuid, service_name, provider_name, categories,
- bta_ar_cb.sdp_tg_handle, browse_supported,
- profile_version, 0);
- bta_sys_add_uuid(service_uuid);
- }
- /* only one TG is allowed (first-come, first-served).
- * If sdp_tg_handle is non-0, ignore this request */
- } else if ((service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) ||
- (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL)) {
- bta_ar_cb.ct_categories[mask - 1] = categories;
- categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1];
- if (bta_ar_cb.sdp_ct_handle == 0) {
- bta_ar_cb.sdp_ct_handle = SDP_CreateRecord();
- AVRC_AddRecord(service_uuid, service_name, provider_name, categories,
- bta_ar_cb.sdp_ct_handle, browse_supported,
- profile_version, 0);
- bta_sys_add_uuid(service_uuid);
- } else {
- /* multiple CTs are allowed.
- * Change supported categories on the second one */
- p = temp;
- UINT16_TO_BE_STREAM(p, categories);
- SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES,
- UINT_DESC_TYPE, (uint32_t)2, (uint8_t*)temp);
- }
- }
-}
-
-/******************************************************************************
- *
- * Function bta_ar_dereg_avrc
- *
- * Description This function is called to de-register/delete an SDP record
- * for AVRCP.
- *
- * Returns void
- *
- *****************************************************************************/
-void bta_ar_dereg_avrc(uint16_t service_uuid) {
- uint8_t mask = BTA_AR_AV_MASK;
- uint16_t categories = 0;
- uint8_t temp[8], *p;
-
- if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) {
- if (bta_ar_cb.sdp_tg_handle && mask == bta_ar_cb.tg_registered) {
- bta_ar_cb.tg_registered = 0;
- SDP_DeleteRecord(bta_ar_cb.sdp_tg_handle);
- bta_ar_cb.sdp_tg_handle = 0;
- bta_sys_remove_uuid(service_uuid);
- }
- } else if (service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) {
- if (bta_ar_cb.sdp_ct_handle) {
- bta_ar_cb.ct_categories[mask - 1] = 0;
- categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1];
- if (!categories) {
- /* no CT is still registered - cleaup */
- SDP_DeleteRecord(bta_ar_cb.sdp_ct_handle);
- bta_ar_cb.sdp_ct_handle = 0;
- bta_sys_remove_uuid(service_uuid);
- } else {
- /* change supported categories to the remaning one */
- p = temp;
- UINT16_TO_BE_STREAM(p, categories);
- SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES,
- UINT_DESC_TYPE, (uint32_t)2, (uint8_t*)temp);
- }
- }
- }
-}
diff --git a/bta/ar/bta_ar_int.h b/bta/ar/bta_ar_int.h
deleted file mode 100644
index c2676a7..0000000
--- a/bta/ar/bta_ar_int.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2008-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the private interface file for the BTA audio/video registration
- * module.
- *
- ******************************************************************************/
-#ifndef BTA_AR_INT_H
-#define BTA_AR_INT_H
-
-#include <cstdint>
-
-#include "bta/include/bta_av_api.h"
-#include "stack/include/avdt_api.h"
-
-#define BTA_AR_AV_MASK 0x01
-#define BTA_AR_AVK_MASK 0x02
-
-/* data associated with BTA_AR */
-typedef struct {
- tAVDT_CTRL_CBACK* p_av_conn_cback; /* av connection callback function */
- uint8_t avdt_registered;
- uint8_t avct_registered;
- uint32_t sdp_tg_handle;
- uint32_t sdp_ct_handle;
- uint16_t ct_categories[2];
- uint8_t tg_registered;
- tBTA_AV_HNDL hndl; /* Handle associated with the stream that rejected the
- connection. */
-} tBTA_AR_CB;
-
-/*****************************************************************************
- * Global data
- ****************************************************************************/
-
-/* control block declaration */
-extern tBTA_AR_CB bta_ar_cb;
-
-#endif /* BTA_AR_INT_H */
diff --git a/bta/av/bta_av_aact.cc b/bta/av/bta_av_aact.cc
deleted file mode 100644
index 2ef03fd..0000000
--- a/bta/av/bta_av_aact.cc
+++ /dev/null
@@ -1,3269 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2004-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains action functions for advanced audio/video stream
- * state machine. these functions are shared by both audio and video
- * streams.
- *
- ******************************************************************************/
-
-#define LOG_TAG "bt_bta_av"
-
-#include <base/strings/stringprintf.h>
-
-#include <cstdint>
-#include <cstring>
-#include <vector>
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bta/av/bta_av_int.h"
-#include "bta/include/bta_ar_api.h"
-#include "bta/include/bta_av_co.h"
-#include "btif/avrcp/avrcp_service.h"
-#include "btif/include/btif_av_co.h"
-#include "btif/include/btif_config.h"
-#include "btif/include/btif_storage.h"
-#include "device/include/interop.h"
-#include "main/shim/dumpsys.h"
-#include "osi/include/allocator.h"
-#include "osi/include/log.h"
-#include "osi/include/osi.h"
-#include "osi/include/properties.h"
-#include "stack/include/a2dp_sbc.h"
-#include "stack/include/acl_api.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/btm_api.h"
-#include "stack/include/btm_client_interface.h"
-#include "stack/include/l2c_api.h"
-#include "types/hci_role.h"
-#include "types/raw_address.h"
-
-namespace {
-
-constexpr char kBtmLogTag[] = "A2DP";
-
-}
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-
-/* the delay time in milliseconds to start service discovery on AVRCP */
-#ifndef BTA_AV_RC_DISC_TIME_VAL
-#define BTA_AV_RC_DISC_TIME_VAL 3500
-#endif
-
-/* the timer in milliseconds to guard against link busy and AVDT_CloseReq failed
- * to be sent */
-#ifndef BTA_AV_CLOSE_REQ_TIME_VAL
-#define BTA_AV_CLOSE_REQ_TIME_VAL 4000
-#endif
-
-/* number to retry on reconfigure failure - some headsets requirs this number to
- * be more than 1 */
-#ifndef BTA_AV_RECONFIG_RETRY
-#define BTA_AV_RECONFIG_RETRY 6
-#endif
-
-/* ACL quota we are letting FW use for A2DP Offload Tx. */
-#define BTA_AV_A2DP_OFFLOAD_XMIT_QUOTA 4
-
-static void bta_av_offload_codec_builder(tBTA_AV_SCB* p_scb,
- tBT_A2DP_OFFLOAD* p_a2dp_offload);
-
-/* state machine states */
-enum {
- BTA_AV_INIT_SST,
- BTA_AV_INCOMING_SST,
- BTA_AV_OPENING_SST,
- BTA_AV_OPEN_SST,
- BTA_AV_RCFG_SST,
- BTA_AV_CLOSING_SST
-};
-
-/* the call out functions for audio stream */
-const tBTA_AV_CO_FUNCTS bta_av_a2dp_cos = {bta_av_co_audio_init,
- bta_av_co_audio_disc_res,
- bta_av_co_audio_getconfig,
- bta_av_co_audio_setconfig,
- bta_av_co_audio_open,
- bta_av_co_audio_close,
- bta_av_co_audio_start,
- bta_av_co_audio_stop,
- bta_av_co_audio_source_data_path,
- bta_av_co_audio_delay,
- bta_av_co_audio_update_mtu,
- bta_av_co_get_scmst_info};
-
-/* these tables translate AVDT events to SSM events */
-static const uint16_t bta_av_stream_evt_ok[] = {
- BTA_AV_STR_DISC_OK_EVT, /* AVDT_DISCOVER_CFM_EVT */
- BTA_AV_STR_GETCAP_OK_EVT, /* AVDT_GETCAP_CFM_EVT */
- BTA_AV_STR_OPEN_OK_EVT, /* AVDT_OPEN_CFM_EVT */
- BTA_AV_STR_OPEN_OK_EVT, /* AVDT_OPEN_IND_EVT */
- BTA_AV_STR_CONFIG_IND_EVT, /* AVDT_CONFIG_IND_EVT */
- BTA_AV_STR_START_OK_EVT, /* AVDT_START_CFM_EVT */
- BTA_AV_STR_START_OK_EVT, /* AVDT_START_IND_EVT */
- BTA_AV_STR_SUSPEND_CFM_EVT, /* AVDT_SUSPEND_CFM_EVT */
- BTA_AV_STR_SUSPEND_CFM_EVT, /* AVDT_SUSPEND_IND_EVT */
- BTA_AV_STR_CLOSE_EVT, /* AVDT_CLOSE_CFM_EVT */
- BTA_AV_STR_CLOSE_EVT, /* AVDT_CLOSE_IND_EVT */
- BTA_AV_STR_RECONFIG_CFM_EVT, /* AVDT_RECONFIG_CFM_EVT */
- 0, /* AVDT_RECONFIG_IND_EVT */
- BTA_AV_STR_SECURITY_CFM_EVT, /* AVDT_SECURITY_CFM_EVT */
- BTA_AV_STR_SECURITY_IND_EVT, /* AVDT_SECURITY_IND_EVT */
- BTA_AV_STR_WRITE_CFM_EVT, /* AVDT_WRITE_CFM_EVT */
- BTA_AV_AVDT_CONNECT_EVT, /* AVDT_CONNECT_IND_EVT */
- BTA_AV_AVDT_DISCONNECT_EVT, /* AVDT_DISCONNECT_IND_EVT */
- BTA_AV_AVDT_RPT_CONN_EVT, /* AVDT_REPORT_CONN_EVT */
- BTA_AV_AVDT_RPT_CONN_EVT, /* AVDT_REPORT_DISCONN_EVT */
- BTA_AV_AVDT_DELAY_RPT_EVT, /* AVDT_DELAY_REPORT_EVT */
- BTA_AV_AVDT_DELAY_RPT_CFM_EVT, /* AVDT_DELAY_REPORT_CFM_EVT */
-};
-
-static const uint16_t bta_av_stream_evt_fail[] = {
- BTA_AV_STR_DISC_FAIL_EVT, /* AVDT_DISCOVER_CFM_EVT */
- BTA_AV_STR_GETCAP_FAIL_EVT, /* AVDT_GETCAP_CFM_EVT */
- BTA_AV_STR_OPEN_FAIL_EVT, /* AVDT_OPEN_CFM_EVT */
- BTA_AV_STR_OPEN_OK_EVT, /* AVDT_OPEN_IND_EVT */
- BTA_AV_STR_CONFIG_IND_EVT, /* AVDT_CONFIG_IND_EVT */
- BTA_AV_STR_START_FAIL_EVT, /* AVDT_START_CFM_EVT */
- BTA_AV_STR_START_OK_EVT, /* AVDT_START_IND_EVT */
- BTA_AV_STR_SUSPEND_CFM_EVT, /* AVDT_SUSPEND_CFM_EVT */
- BTA_AV_STR_SUSPEND_CFM_EVT, /* AVDT_SUSPEND_IND_EVT */
- BTA_AV_STR_CLOSE_EVT, /* AVDT_CLOSE_CFM_EVT */
- BTA_AV_STR_CLOSE_EVT, /* AVDT_CLOSE_IND_EVT */
- BTA_AV_STR_RECONFIG_CFM_EVT, /* AVDT_RECONFIG_CFM_EVT */
- 0, /* AVDT_RECONFIG_IND_EVT */
- BTA_AV_STR_SECURITY_CFM_EVT, /* AVDT_SECURITY_CFM_EVT */
- BTA_AV_STR_SECURITY_IND_EVT, /* AVDT_SECURITY_IND_EVT */
- BTA_AV_STR_WRITE_CFM_EVT, /* AVDT_WRITE_CFM_EVT */
- BTA_AV_AVDT_CONNECT_EVT, /* AVDT_CONNECT_IND_EVT */
- BTA_AV_AVDT_DISCONNECT_EVT, /* AVDT_DISCONNECT_IND_EVT */
- BTA_AV_AVDT_RPT_CONN_EVT, /* AVDT_REPORT_CONN_EVT */
- BTA_AV_AVDT_RPT_CONN_EVT, /* AVDT_REPORT_DISCONN_EVT */
- BTA_AV_AVDT_DELAY_RPT_EVT, /* AVDT_DELAY_REPORT_EVT */
- BTA_AV_AVDT_DELAY_RPT_CFM_EVT, /* AVDT_DELAY_REPORT_CFM_EVT */
-};
-
-/***********************************************
- *
- * Function bta_get_scb_handle
- *
- * Description gives the registered AVDT handle.by checking with sep_type.
- *
- *
- * Returns void
- **********************************************/
-static uint8_t bta_av_get_scb_handle(tBTA_AV_SCB* p_scb, uint8_t local_sep) {
- for (int i = 0; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) {
- if ((p_scb->seps[i].tsep == local_sep) &&
- A2DP_CodecTypeEquals(p_scb->seps[i].codec_info,
- p_scb->cfg.codec_info)) {
- return (p_scb->seps[i].av_handle);
- }
- }
- APPL_TRACE_DEBUG("%s: local sep_type %d not found", __func__, local_sep)
- return 0; /* return invalid handle */
-}
-
-/***********************************************
- *
- * Function bta_av_get_scb_sep_type
- *
- * Description gives the sep type by cross-checking with AVDT handle
- *
- *
- * Returns void
- **********************************************/
-static uint8_t bta_av_get_scb_sep_type(tBTA_AV_SCB* p_scb,
- uint8_t tavdt_handle) {
- for (int i = 0; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) {
- if (p_scb->seps[i].av_handle == tavdt_handle) return (p_scb->seps[i].tsep);
- }
- APPL_TRACE_DEBUG("%s: avdt_handle %d not found", __func__, tavdt_handle)
- return AVDT_TSEP_INVALID;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_save_addr
- *
- * Description copy the bd_addr and maybe reset the supported flags
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_av_save_addr(tBTA_AV_SCB* p_scb, const RawAddress& bd_addr) {
- APPL_TRACE_DEBUG("%s: peer=%s recfg_sup:%d, suspend_sup:%d", __func__,
- bd_addr.ToString().c_str(), p_scb->recfg_sup,
- p_scb->suspend_sup);
- if (p_scb->PeerAddress() != bd_addr) {
- LOG_INFO("%s: reset flags old_addr=%s new_addr=%s", __func__,
- p_scb->PeerAddress().ToString().c_str(),
- bd_addr.ToString().c_str());
- /* a new addr, reset the supported flags */
- p_scb->recfg_sup = true;
- p_scb->suspend_sup = true;
- }
-
- /* do this copy anyway, just in case the first addr matches
- * the control block one by accident */
- p_scb->OnConnected(bd_addr);
-}
-
-/*******************************************************************************
- *
- * Function notify_start_failed
- *
- * Description notify up-layer AV start failed
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void notify_start_failed(tBTA_AV_SCB* p_scb) {
- LOG_ERROR("%s: peer %s role:0x%x bta_channel:%d bta_handle:0x%x", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->role, p_scb->chnl,
- p_scb->hndl);
- tBTA_AV_START start;
- /* if start failed, clear role */
- p_scb->role &= ~BTA_AV_ROLE_START_INT;
- start.chnl = p_scb->chnl;
- start.status = BTA_AV_FAIL;
- start.initiator = true;
- start.hndl = p_scb->hndl;
-
- tBTA_AV bta_av_data;
- bta_av_data.start = start;
- (*bta_av_cb.p_cback)(BTA_AV_START_EVT, &bta_av_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_st_rc_timer
- *
- * Description start the AVRC timer if no RC connection & CT is supported &
- * RC is used or
- * as ACP (we do not really know if we want AVRC)
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_st_rc_timer(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- APPL_TRACE_DEBUG("%s: rc_handle:%d, use_rc: %d", __func__, p_scb->rc_handle,
- p_scb->use_rc);
- /* for outgoing RC connection as INT/CT */
- if ((p_scb->rc_handle == BTA_AV_RC_HANDLE_NONE) &&
- /* (bta_av_cb.features & BTA_AV_FEAT_RCCT) && */
- (p_scb->use_rc || (p_scb->role & BTA_AV_ROLE_AD_ACP))) {
- if ((p_scb->wait & BTA_AV_WAIT_ROLE_SW_BITS) == 0) {
- bta_sys_start_timer(p_scb->avrc_ct_timer, BTA_AV_RC_DISC_TIME_VAL,
- BTA_AV_AVRC_TIMER_EVT, p_scb->hndl);
- } else {
- p_scb->wait |= BTA_AV_WAIT_CHECK_RC;
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_next_getcap
- *
- * Description The function gets the capabilities of the next available
- * stream found in the discovery results.
- *
- * Returns true if we sent request to AVDT, false otherwise.
- *
- ******************************************************************************/
-static bool bta_av_next_getcap(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- int i;
- bool sent_cmd = false;
- uint16_t uuid_int = p_scb->uuid_int;
- uint8_t sep_requested = 0;
-
- if (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE)
- sep_requested = AVDT_TSEP_SNK;
- else if (uuid_int == UUID_SERVCLASS_AUDIO_SINK)
- sep_requested = AVDT_TSEP_SRC;
-
- for (i = p_scb->sep_info_idx; i < p_scb->num_seps; i++) {
- /* steam not in use, is a sink, and is the right media type (audio/video) */
- if ((!p_scb->sep_info[i].in_use) &&
- (p_scb->sep_info[i].tsep == sep_requested) &&
- (p_scb->sep_info[i].media_type == p_scb->media_type)) {
- p_scb->sep_info_idx = i;
-
- /* we got a stream; get its capabilities */
- bool get_all_cap = (p_scb->AvdtpVersion() >= AVDT_VERSION_1_3) &&
- (A2DP_GetAvdtpVersion() >= AVDT_VERSION_1_3);
- AVDT_GetCapReq(p_scb->PeerAddress(), p_scb->hdi, p_scb->sep_info[i].seid,
- &p_scb->peer_cap, &bta_av_proc_stream_evt, get_all_cap);
- sent_cmd = true;
- break;
- }
- }
-
- /* if no streams available then stream open fails */
- if (!sent_cmd) {
- APPL_TRACE_ERROR("%s: BTA_AV_STR_GETCAP_FAIL_EVT: peer_addr=%s", __func__,
- p_scb->PeerAddress().ToString().c_str());
- bta_av_ssm_execute(p_scb, BTA_AV_STR_GETCAP_FAIL_EVT, p_data);
- }
-
- return sent_cmd;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_proc_stream_evt
- *
- * Description Utility function to compose stream events.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_proc_stream_evt(uint8_t handle, const RawAddress& bd_addr,
- uint8_t event, tAVDT_CTRL* p_data,
- uint8_t scb_index) {
- CHECK_LT(scb_index, BTA_AV_NUM_STRS);
- tBTA_AV_SCB* p_scb = bta_av_cb.p_scb[scb_index];
- uint16_t sec_len = 0;
-
- APPL_TRACE_EVENT(
- "%s: peer_address: %s avdt_handle: %d event=0x%x scb_index=%d p_scb=%p",
- __func__, bd_addr.ToString().c_str(), handle, event, scb_index, p_scb);
-
- if (p_data) {
- if (event == AVDT_SECURITY_IND_EVT) {
- sec_len = (p_data->security_ind.len < BTA_AV_SECURITY_MAX_LEN)
- ? p_data->security_ind.len
- : BTA_AV_SECURITY_MAX_LEN;
- } else if (event == AVDT_SECURITY_CFM_EVT && p_data->hdr.err_code == 0) {
- sec_len = (p_data->security_cfm.len < BTA_AV_SECURITY_MAX_LEN)
- ? p_data->security_cfm.len
- : BTA_AV_SECURITY_MAX_LEN;
- }
- }
-
- if (p_scb) {
- tBTA_AV_STR_MSG* p_msg =
- (tBTA_AV_STR_MSG*)osi_malloc(sizeof(tBTA_AV_STR_MSG) + sec_len);
-
- /* copy event data, bd addr, and handle to event message buffer */
- p_msg->hdr.offset = 0;
-
- p_msg->bd_addr = bd_addr;
- p_msg->scb_index = scb_index;
- APPL_TRACE_EVENT("%s: stream event bd_addr: %s scb_index: %u", __func__,
- p_msg->bd_addr.ToString().c_str(), scb_index);
-
- if (p_data != NULL) {
- memcpy(&p_msg->msg, p_data, sizeof(tAVDT_CTRL));
- /* copy config params to event message buffer */
- switch (event) {
- case AVDT_CONFIG_IND_EVT:
- p_msg->cfg = *p_data->config_ind.p_cfg;
- break;
-
- case AVDT_SECURITY_IND_EVT:
- p_msg->msg.security_ind.p_data = (uint8_t*)(p_msg + 1);
- memcpy(p_msg->msg.security_ind.p_data, p_data->security_ind.p_data,
- sec_len);
- break;
-
- case AVDT_SECURITY_CFM_EVT:
- p_msg->msg.security_cfm.p_data = (uint8_t*)(p_msg + 1);
- if (p_data->hdr.err_code == 0) {
- memcpy(p_msg->msg.security_cfm.p_data, p_data->security_cfm.p_data,
- sec_len);
- }
- break;
-
- case AVDT_SUSPEND_IND_EVT:
- p_msg->msg.hdr.err_code = 0;
- break;
-
- case AVDT_CONNECT_IND_EVT:
- p_scb->recfg_sup = true;
- p_scb->suspend_sup = true;
- break;
-
- default:
- break;
- }
- } else {
- p_msg->msg.hdr.err_code = 0;
- }
-
- /* look up application event */
- if ((p_data == NULL) || (p_data->hdr.err_code == 0)) {
- p_msg->hdr.event = bta_av_stream_evt_ok[event];
- } else {
- p_msg->hdr.event = bta_av_stream_evt_fail[event];
- }
-
- p_msg->initiator = false;
- if (event == AVDT_SUSPEND_CFM_EVT) p_msg->initiator = true;
-
- APPL_TRACE_VERBOSE("%s: bta_handle:0x%x avdt_handle:%d", __func__,
- p_scb->hndl, handle);
- p_msg->hdr.layer_specific = p_scb->hndl;
- p_msg->handle = handle;
- p_msg->avdt_event = event;
- bta_sys_sendmsg(p_msg);
- }
-
- if (p_data) {
- bta_av_conn_cback(handle, bd_addr, event, p_data, scb_index);
- } else {
- APPL_TRACE_ERROR("%s: p_data is null", __func__);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_sink_data_cback
- *
- * Description This is the AVDTP callback function for sink stream events.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_sink_data_cback(uint8_t handle, BT_HDR* p_pkt, uint32_t time_stamp,
- uint8_t m_pt) {
- int index = 0;
- tBTA_AV_SCB* p_scb;
- APPL_TRACE_DEBUG(
- "%s: avdt_handle: %d pkt_len=0x%x offset = 0x%x "
- "number of frames 0x%x sequence number 0x%x",
- __func__, handle, p_pkt->len, p_pkt->offset,
- *((uint8_t*)(p_pkt + 1) + p_pkt->offset), p_pkt->layer_specific);
- /* Get SCB and correct sep type */
- for (index = 0; index < BTA_AV_NUM_STRS; index++) {
- p_scb = bta_av_cb.p_scb[index];
- if ((p_scb->avdt_handle == handle) &&
- (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK)) {
- break;
- }
- }
- if (index == BTA_AV_NUM_STRS) {
- /* cannot find correct handler */
- osi_free(p_pkt);
- return;
- }
- p_pkt->event = BTA_AV_SINK_MEDIA_DATA_EVT;
- p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback(
- p_scb->PeerAddress(), BTA_AV_SINK_MEDIA_DATA_EVT, (tBTA_AV_MEDIA*)p_pkt);
- /* Free the buffer: a copy of the packet has been delivered */
- osi_free(p_pkt);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_a2dp_sdp_cback
- *
- * Description A2DP service discovery callback.
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_av_a2dp_sdp_cback(bool found, tA2DP_Service* p_service,
- const RawAddress& peer_address) {
- APPL_TRACE_DEBUG("%s: peer %s : found=%s", __func__,
- peer_address.ToString().c_str(), (found) ? "true" : "false");
-
- tBTA_AV_SCB* p_scb = NULL;
- if (peer_address != RawAddress::kEmpty) {
- p_scb = bta_av_addr_to_scb(peer_address);
- }
- if (p_scb == NULL) {
- p_scb = bta_av_hndl_to_scb(bta_av_cb.handle);
- }
- if (p_scb == NULL) {
- APPL_TRACE_ERROR("%s: no scb found for SDP handle(0x%x)", __func__,
- bta_av_cb.handle);
- return;
- }
- if (bta_av_cb.handle != p_scb->hndl) {
- APPL_TRACE_WARNING("%s: SDP bta_handle expected=0x%x processing=0x%x",
- __func__, bta_av_cb.handle, p_scb->hndl);
- }
-
- if (!found) {
- APPL_TRACE_ERROR("%s: peer %s A2DP service discovery failed", __func__,
- p_scb->PeerAddress().ToString().c_str());
- }
- APPL_TRACE_DEBUG("%s: peer %s found=%s", __func__,
- p_scb->PeerAddress().ToString().c_str(),
- (found) ? "true" : "false");
-
- tBTA_AV_SDP_RES* p_msg =
- (tBTA_AV_SDP_RES*)osi_malloc(sizeof(tBTA_AV_SDP_RES));
- if (found) {
- p_msg->hdr.event = BTA_AV_SDP_DISC_OK_EVT;
- } else {
- p_msg->hdr.event = BTA_AV_SDP_DISC_FAIL_EVT;
- APPL_TRACE_ERROR("%s: BTA_AV_SDP_DISC_FAIL_EVT: peer_addr=%s", __func__,
- p_scb->PeerAddress().ToString().c_str());
- }
- if (found && (p_service != NULL)) {
- p_scb->SetAvdtpVersion(p_service->avdt_version);
- if (p_service->avdt_version != 0) {
- if (btif_config_set_bin(p_scb->PeerAddress().ToString(),
- AVDTP_VERSION_CONFIG_KEY,
- (const uint8_t*)&p_service->avdt_version,
- sizeof(p_service->avdt_version))) {
- btif_config_save();
- } else {
- APPL_TRACE_WARNING("%s: Failed to store peer AVDTP version for %s",
- __func__, p_scb->PeerAddress().ToString().c_str());
- }
- }
- } else {
- p_scb->SetAvdtpVersion(0);
- }
- p_msg->hdr.layer_specific = p_scb->hndl;
-
- bta_sys_sendmsg(p_msg);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_adjust_seps_idx
- *
- * Description adjust the sep_idx
- *
- * Returns
- *
- ******************************************************************************/
-static void bta_av_adjust_seps_idx(tBTA_AV_SCB* p_scb, uint8_t avdt_handle) {
- APPL_TRACE_DEBUG("%s: codec: %s", __func__,
- A2DP_CodecName(p_scb->cfg.codec_info));
- for (int i = 0; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) {
- APPL_TRACE_DEBUG("%s: avdt_handle: %d codec: %s", __func__,
- p_scb->seps[i].av_handle,
- A2DP_CodecName(p_scb->seps[i].codec_info));
- if (p_scb->seps[i].av_handle && (p_scb->seps[i].av_handle == avdt_handle) &&
- A2DP_CodecTypeEquals(p_scb->seps[i].codec_info,
- p_scb->cfg.codec_info)) {
- p_scb->sep_idx = i;
- p_scb->avdt_handle = p_scb->seps[i].av_handle;
- break;
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_switch_role
- *
- * Description Switch role was not started and a timer was started.
- * another attempt to switch role now - still opening.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_switch_role(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- tBTA_AV_RS_RES switch_res = BTA_AV_RS_NONE;
- tBTA_AV_API_OPEN* p_buf = &p_scb->q_info.open;
-
- APPL_TRACE_DEBUG("%s: peer %s wait:0x%x", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->wait);
- if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_RES_START)
- p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RETRY;
-
- /* clear the masks set when the timer is started */
- p_scb->wait &=
- ~(BTA_AV_WAIT_ROLE_SW_RES_OPEN | BTA_AV_WAIT_ROLE_SW_RES_START);
-
- if (p_scb->q_tag == BTA_AV_Q_TAG_OPEN) {
- if (bta_av_switch_if_needed(p_scb) ||
- !bta_av_link_role_ok(p_scb, A2DP_SET_MULTL_BIT)) {
- p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RES_OPEN;
- } else {
- /* this should not happen in theory. Just in case...
- * continue to do_disc_a2dp */
- switch_res = BTA_AV_RS_DONE;
- }
- } else {
- /* report failure on OPEN */
- APPL_TRACE_ERROR("%s: peer %s role switch failed (wait=0x%x)", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->wait);
- switch_res = BTA_AV_RS_FAIL;
- }
-
- if (switch_res != BTA_AV_RS_NONE) {
- if (bta_av_cb.rs_idx == (p_scb->hdi + 1)) {
- bta_av_cb.rs_idx = 0;
- }
- p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_RETRY;
- p_scb->q_tag = 0;
- p_buf->switch_res = switch_res;
- bta_av_do_disc_a2dp(p_scb, (tBTA_AV_DATA*)p_buf);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_role_res
- *
- * Description Handle the role changed event
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_role_res(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- bool initiator = false;
-
- APPL_TRACE_DEBUG("%s: peer %s q_tag:%d, wait:0x%x, role:0x%x", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->q_tag,
- p_scb->wait, p_scb->role);
- if (p_scb->role & BTA_AV_ROLE_START_INT) initiator = true;
-
- if (p_scb->q_tag == BTA_AV_Q_TAG_START) {
- if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_STARTED) {
- p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
- if (p_data->role_res.hci_status != HCI_SUCCESS) {
- p_scb->role &= ~BTA_AV_ROLE_START_INT;
- bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->PeerAddress());
- /* start failed because of role switch. */
- tBTA_AV_START start;
- start.chnl = p_scb->chnl;
- start.status = BTA_AV_FAIL_ROLE;
- start.hndl = p_scb->hndl;
- start.initiator = initiator;
- tBTA_AV bta_av_data;
- bta_av_data.start = start;
- (*bta_av_cb.p_cback)(BTA_AV_START_EVT, &bta_av_data);
- } else {
- bta_av_start_ok(p_scb, p_data);
- }
- } else if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_RES_START)
- p_scb->wait |= BTA_AV_WAIT_ROLE_SW_FAILED;
- } else if (p_scb->q_tag == BTA_AV_Q_TAG_OPEN) {
- if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_RES_OPEN) {
- p_scb->role &= ~BTA_AV_ROLE_START_INT;
- p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
-
- if (p_data->role_res.hci_status != HCI_SUCCESS) {
- /* Open failed because of role switch. */
- tBTA_AV_OPEN av_open;
- av_open.bd_addr = p_scb->PeerAddress();
- av_open.chnl = p_scb->chnl;
- av_open.hndl = p_scb->hndl;
- av_open.status = BTA_AV_FAIL_ROLE;
- if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC) {
- av_open.sep = AVDT_TSEP_SNK;
- } else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK) {
- av_open.sep = AVDT_TSEP_SRC;
- }
- tBTA_AV bta_av_data;
- bta_av_data.open = av_open;
- (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, &bta_av_data);
- } else {
- /* Continue av open process */
- p_scb->q_info.open.switch_res = BTA_AV_RS_DONE;
- bta_av_do_disc_a2dp(p_scb, (tBTA_AV_DATA*)&(p_scb->q_info.open));
- }
- } else {
- APPL_TRACE_WARNING(
- "%s: peer %s unexpected role switch event: q_tag = %d wait = 0x%x",
- __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->q_tag,
- p_scb->wait);
- }
- }
-
- APPL_TRACE_DEBUG("%s: peer %s wait:0x%x, role:0x%x", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->wait,
- p_scb->role);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_delay_co
- *
- * Description Call the delay call-out function to report the delay report
- * from SNK
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_delay_co(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- APPL_TRACE_DEBUG("%s: peer %s bta_handle:0x%x delay:%d", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->hndl,
- p_data->str_msg.msg.delay_rpt_cmd.delay);
- p_scb->p_cos->delay(p_scb->hndl, p_scb->PeerAddress(),
- p_data->str_msg.msg.delay_rpt_cmd.delay);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_do_disc_a2dp
- *
- * Description Do service discovery for A2DP.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_do_disc_a2dp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- bool ok_continue = false;
- tA2DP_SDP_DB_PARAMS db_params;
- uint16_t attr_list[] = {ATTR_ID_SERVICE_CLASS_ID_LIST,
- ATTR_ID_PROTOCOL_DESC_LIST,
- ATTR_ID_BT_PROFILE_DESC_LIST};
- uint16_t sdp_uuid = 0; /* UUID for which SDP has to be done */
-
- APPL_TRACE_DEBUG("%s: peer_addr: %s use_rc: %d switch_res:%d, oc:%d",
- __func__, p_data->api_open.bd_addr.ToString().c_str(),
- p_data->api_open.use_rc, p_data->api_open.switch_res,
- bta_av_cb.audio_open_cnt);
-
- memcpy(&(p_scb->open_api), &(p_data->api_open), sizeof(tBTA_AV_API_OPEN));
-
- switch (p_data->api_open.switch_res) {
- case BTA_AV_RS_NONE:
- if (bta_av_switch_if_needed(p_scb) ||
- !bta_av_link_role_ok(p_scb, A2DP_SET_MULTL_BIT)) {
- /* waiting for role switch result. save the api to control block */
- memcpy(&p_scb->q_info.open, &p_data->api_open,
- sizeof(tBTA_AV_API_OPEN));
- p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RES_OPEN;
- p_scb->q_tag = BTA_AV_Q_TAG_OPEN;
- } else {
- ok_continue = true;
- }
- break;
-
- case BTA_AV_RS_FAIL:
- /* report a new failure event */
- p_scb->open_status = BTA_AV_FAIL_ROLE;
- APPL_TRACE_ERROR("%s: BTA_AV_SDP_DISC_FAIL_EVT: peer_addr=%s", __func__,
- p_scb->PeerAddress().ToString().c_str());
- bta_av_ssm_execute(p_scb, BTA_AV_SDP_DISC_FAIL_EVT, NULL);
- break;
-
- case BTA_AV_RS_OK:
- p_data = (tBTA_AV_DATA*)&p_scb->q_info.open;
- /* continue to open if link role is ok */
- if (bta_av_link_role_ok(p_scb, A2DP_SET_MULTL_BIT)) {
- ok_continue = true;
- } else {
- p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RES_OPEN;
- }
- break;
-
- case BTA_AV_RS_DONE:
- ok_continue = true;
- break;
- }
-
- APPL_TRACE_DEBUG("%s: ok_continue: %d wait:0x%x, q_tag: %d", __func__,
- ok_continue, p_scb->wait, p_scb->q_tag);
- if (!ok_continue) return;
-
- /* clear the role switch bits */
- p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
-
- if (p_scb->wait & BTA_AV_WAIT_CHECK_RC) {
- p_scb->wait &= ~BTA_AV_WAIT_CHECK_RC;
- bta_sys_start_timer(p_scb->avrc_ct_timer, BTA_AV_RC_DISC_TIME_VAL,
- BTA_AV_AVRC_TIMER_EVT, p_scb->hndl);
- }
-
- /* store peer addr other parameters */
- bta_av_save_addr(p_scb, p_data->api_open.bd_addr);
- p_scb->use_rc = p_data->api_open.use_rc;
-
- bta_sys_app_open(BTA_ID_AV, p_scb->app_id, p_scb->PeerAddress());
-
- /* set up parameters */
- db_params.db_len = BTA_AV_DISC_BUF_SIZE;
- db_params.num_attr = 3;
- db_params.p_attrs = attr_list;
- p_scb->uuid_int = p_data->api_open.uuid;
- p_scb->sdp_discovery_started = true;
- if (p_scb->uuid_int == UUID_SERVCLASS_AUDIO_SINK)
- sdp_uuid = UUID_SERVCLASS_AUDIO_SOURCE;
- else if (p_scb->uuid_int == UUID_SERVCLASS_AUDIO_SOURCE)
- sdp_uuid = UUID_SERVCLASS_AUDIO_SINK;
-
- APPL_TRACE_DEBUG(
- "%s: Initiate SDP discovery for peer %s : uuid_int=0x%x "
- "sdp_uuid=0x%x",
- __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->uuid_int,
- sdp_uuid);
- tA2DP_STATUS find_service_status = A2DP_FindService(
- sdp_uuid, p_scb->PeerAddress(), &db_params, bta_av_a2dp_sdp_cback);
- if (find_service_status != A2DP_SUCCESS) {
- APPL_TRACE_ERROR(
- "%s: A2DP_FindService() failed for peer %s uuid_int=0x%x "
- "sdp_uuid=0x%x : status=%d",
- __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->uuid_int,
- sdp_uuid, find_service_status);
- bta_av_a2dp_sdp_cback(false, nullptr, p_scb->PeerAddress());
- } else {
- /* only one A2DP find service is active at a time */
- bta_av_cb.handle = p_scb->hndl;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_cleanup
- *
- * Description cleanup AV stream control block.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_cleanup(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- tBTA_AV_CONN_CHG msg;
- uint8_t role = BTA_AV_ROLE_AD_INT;
-
- LOG_INFO("%s peer %s", __func__, p_scb->PeerAddress().ToString().c_str());
-
- /* free any buffers */
- p_scb->sdp_discovery_started = false;
- p_scb->SetAvdtpVersion(0);
-
- /* initialize some control block variables */
- p_scb->open_status = BTA_AV_SUCCESS;
-
- /* if de-registering shut everything down */
- msg.hdr.layer_specific = p_scb->hndl;
- p_scb->started = false;
- p_scb->use_rtp_header_marker_bit = false;
- p_scb->cong = false;
- p_scb->role = role;
- p_scb->cur_psc_mask = 0;
- p_scb->wait = 0;
- p_scb->num_disc_snks = 0;
- p_scb->coll_mask = 0;
- alarm_cancel(p_scb->avrc_ct_timer);
- alarm_cancel(p_scb->link_signalling_timer);
- alarm_cancel(p_scb->accept_signalling_timer);
-
- /* TODO(eisenbach): RE-IMPLEMENT USING VSC OR HAL EXTENSION
- vendor_get_interface()->send_command(
- (vendor_opcode_t)BT_VND_OP_A2DP_OFFLOAD_STOP, (void*)&p_scb->l2c_cid);
- if (p_scb->offload_start_pending) {
- tBTA_AV_STATUS status = BTA_AV_FAIL_STREAM;
- tBTA_AV bta_av_data;
- bta_av_data.status = status;
- (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, &bta_av_data);
- }
- */
-
- if (p_scb->deregistering) {
- /* remove stream */
- for (int i = 0; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) {
- if (p_scb->seps[i].av_handle) AVDT_RemoveStream(p_scb->seps[i].av_handle);
- p_scb->seps[i].av_handle = 0;
- }
-
- bta_av_dereg_comp((tBTA_AV_DATA*)&msg);
- } else {
- /* report stream closed to main SM */
- msg.is_up = false;
- msg.peer_addr = p_scb->PeerAddress();
- bta_av_conn_chg((tBTA_AV_DATA*)&msg);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_free_sdb
- *
- * Description Free service discovery db buffer.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_free_sdb(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- p_scb->sdp_discovery_started = false;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_config_ind
- *
- * Description Handle a stream configuration indication from the peer.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_config_ind(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- tBTA_AV_CI_SETCONFIG setconfig{};
- tAVDT_SEP_INFO* p_info;
- const AvdtpSepConfig* p_evt_cfg = &p_data->str_msg.cfg;
- uint8_t psc_mask = (p_evt_cfg->psc_mask | p_scb->cfg.psc_mask);
- uint8_t
- local_sep; /* sep type of local handle on which connection was received */
- tBTA_AV_STR_MSG* p_msg = (tBTA_AV_STR_MSG*)p_data;
-
- local_sep = bta_av_get_scb_sep_type(p_scb, p_msg->handle);
- p_scb->avdt_label = p_data->str_msg.msg.hdr.label;
-
- APPL_TRACE_DEBUG("%s: peer %s bta_handle:0x%x local_sep:%d", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->hndl,
- local_sep);
- APPL_TRACE_DEBUG("%s: codec: %s", __func__,
- A2DP_CodecInfoString(p_evt_cfg->codec_info).c_str());
-
- memcpy(p_scb->cfg.codec_info, p_evt_cfg->codec_info, AVDT_CODEC_SIZE);
- bta_av_save_addr(p_scb, p_data->str_msg.bd_addr);
-
- /* Clear collision mask */
- p_scb->coll_mask = 0;
- alarm_cancel(p_scb->accept_signalling_timer);
-
- /* if no codec parameters in configuration, fail */
- if ((p_evt_cfg->num_codec == 0) ||
- /* or the peer requests for a service we do not support */
- ((psc_mask != p_scb->cfg.psc_mask) &&
- (psc_mask != (p_scb->cfg.psc_mask & ~AVDT_PSC_DELAY_RPT)))) {
- setconfig.hndl = p_scb->hndl; /* we may not need this */
- setconfig.err_code = AVDT_ERR_UNSUP_CFG;
- bta_av_ssm_execute(p_scb, BTA_AV_CI_SETCONFIG_FAIL_EVT,
- (tBTA_AV_DATA*)&setconfig);
- } else {
- p_info = &p_scb->sep_info[0];
- p_info->in_use = 0;
- p_info->media_type = p_scb->media_type;
- p_info->seid = p_data->str_msg.msg.config_ind.int_seid;
-
- /* Sep type of Peer will be oppsite role to our local sep */
- if (local_sep == AVDT_TSEP_SRC)
- p_info->tsep = AVDT_TSEP_SNK;
- else if (local_sep == AVDT_TSEP_SNK)
- p_info->tsep = AVDT_TSEP_SRC;
-
- p_scb->role |= BTA_AV_ROLE_AD_ACP;
- p_scb->cur_psc_mask = p_evt_cfg->psc_mask;
- if (bta_av_cb.features & BTA_AV_FEAT_RCTG)
- p_scb->use_rc = true;
- else
- p_scb->use_rc = false;
-
- p_scb->num_seps = 1;
- p_scb->sep_info_idx = 0;
- APPL_TRACE_DEBUG("%s: SEID: %d use_rc: %d cur_psc_mask:0x%x", __func__,
- p_info->seid, p_scb->use_rc, p_scb->cur_psc_mask);
- /* in case of A2DP SINK this is the first time peer data is being sent to
- * co functions */
- if (local_sep == AVDT_TSEP_SNK) {
- p_scb->p_cos->setcfg(p_scb->hndl, p_scb->PeerAddress(),
- p_evt_cfg->codec_info, p_info->seid,
- p_evt_cfg->num_protect, p_evt_cfg->protect_info,
- AVDT_TSEP_SNK, p_msg->handle);
- } else {
- p_scb->p_cos->setcfg(p_scb->hndl, p_scb->PeerAddress(),
- p_evt_cfg->codec_info, p_info->seid,
- p_evt_cfg->num_protect, p_evt_cfg->protect_info,
- AVDT_TSEP_SRC, p_msg->handle);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_disconnect_req
- *
- * Description Disconnect AVDTP connection.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_disconnect_req(tBTA_AV_SCB* p_scb,
- UNUSED_ATTR tBTA_AV_DATA* p_data) {
- tBTA_AV_RCB* p_rcb;
-
- APPL_TRACE_API("%s: conn_lcb: 0x%x peer_addr: %s", __func__,
- bta_av_cb.conn_lcb, p_scb->PeerAddress().ToString().c_str());
-
- alarm_cancel(p_scb->link_signalling_timer);
- alarm_cancel(p_scb->accept_signalling_timer);
- alarm_cancel(p_scb->avrc_ct_timer);
-
- // conn_lcb is the index bitmask of all used LCBs, and since LCB and SCB use
- // the same index, it should be safe to use SCB index here.
- if ((bta_av_cb.conn_lcb & (1 << p_scb->hdi)) != 0) {
- p_rcb = bta_av_get_rcb_by_shdl((uint8_t)(p_scb->hdi + 1));
- if (p_rcb) bta_av_del_rc(p_rcb);
- AVDT_DisconnectReq(p_scb->PeerAddress(), &bta_av_proc_stream_evt);
- } else {
- APPL_TRACE_WARNING("%s: conn_lcb=0x%x bta_handle=0x%x (hdi=%u) no link",
- __func__, bta_av_cb.conn_lcb, p_scb->hndl, p_scb->hdi);
- bta_av_ssm_execute(p_scb, BTA_AV_AVDT_DISCONNECT_EVT, NULL);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_security_req
- *
- * Description Send an AVDTP security request.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_security_req(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- if (bta_av_cb.features & BTA_AV_FEAT_PROTECT) {
- AVDT_SecurityReq(p_scb->avdt_handle, p_data->api_protect_req.p_data,
- p_data->api_protect_req.len);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_security_rsp
- *
- * Description Send an AVDTP security response.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_security_rsp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- if (bta_av_cb.features & BTA_AV_FEAT_PROTECT) {
- AVDT_SecurityRsp(p_scb->avdt_handle, p_scb->avdt_label,
- p_data->api_protect_rsp.error_code,
- p_data->api_protect_rsp.p_data,
- p_data->api_protect_rsp.len);
- } else {
- AVDT_SecurityRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_NSC, NULL,
- 0);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_setconfig_rsp
- *
- * Description setconfig is OK
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_setconfig_rsp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- uint8_t num = p_data->ci_setconfig.num_seid + 1;
- uint8_t avdt_handle = p_data->ci_setconfig.avdt_handle;
- uint8_t* p_seid = p_data->ci_setconfig.p_seid;
- int i;
- uint8_t local_sep;
-
- /* we like this codec_type. find the sep_idx */
- local_sep = bta_av_get_scb_sep_type(p_scb, avdt_handle);
- bta_av_adjust_seps_idx(p_scb, avdt_handle);
- LOG_INFO(
- "%s: peer %s bta_handle=0x%x avdt_handle=%d sep_idx=%d cur_psc_mask:0x%x",
- __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->hndl,
- p_scb->avdt_handle, p_scb->sep_idx, p_scb->cur_psc_mask);
-
- if ((AVDT_TSEP_SNK == local_sep) &&
- (p_data->ci_setconfig.err_code == AVDT_SUCCESS) &&
- (p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback != NULL)) {
- tBTA_AV_MEDIA av_sink_codec_info;
- av_sink_codec_info.avk_config.bd_addr = p_scb->PeerAddress();
- av_sink_codec_info.avk_config.codec_info = p_scb->cfg.codec_info;
- p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback(
- p_scb->PeerAddress(), BTA_AV_SINK_MEDIA_CFG_EVT, &av_sink_codec_info);
- }
-
- AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label,
- p_data->ci_setconfig.err_code, p_data->ci_setconfig.category);
-
- alarm_cancel(p_scb->link_signalling_timer);
-
- if (p_data->ci_setconfig.err_code == AVDT_SUCCESS) {
- p_scb->wait = BTA_AV_WAIT_ACP_CAPS_ON;
- if (p_data->ci_setconfig.recfg_needed)
- p_scb->role |= BTA_AV_ROLE_SUSPEND_OPT;
- APPL_TRACE_DEBUG("%s: recfg_needed:%d role:0x%x num:%d", __func__,
- p_data->ci_setconfig.recfg_needed, p_scb->role, num);
- /* callout module tells BTA the number of "good" SEPs and their SEIDs.
- * getcap on these SEID */
- p_scb->num_seps = num;
-
- if (p_scb->cur_psc_mask & AVDT_PSC_DELAY_RPT)
- p_scb->SetAvdtpVersion(AVDT_VERSION_1_3);
-
- if (A2DP_GetCodecType(p_scb->cfg.codec_info) == A2DP_MEDIA_CT_SBC ||
- num > 1) {
- /* if SBC is used by the SNK as INT, discover req is not sent in
- * bta_av_config_ind.
- * call disc_res now */
- /* this is called in A2DP SRC path only, In case of SINK we don't need it
- */
- if (local_sep == AVDT_TSEP_SRC)
- p_scb->p_cos->disc_res(p_scb->hndl, p_scb->PeerAddress(), num, num, 0,
- UUID_SERVCLASS_AUDIO_SOURCE);
- } else {
- /* we do not know the peer device and it is using non-SBC codec
- * we need to know all the SEPs on SNK */
- if (p_scb->uuid_int == 0) p_scb->uuid_int = p_scb->open_api.uuid;
- bta_av_discover_req(p_scb, NULL);
- return;
- }
-
- for (i = 1; i < num; i++) {
- APPL_TRACE_DEBUG("%s: sep_info[%d] SEID: %d", __func__, i, p_seid[i - 1]);
- /* initialize the sep_info[] to get capabilities */
- p_scb->sep_info[i].in_use = false;
- p_scb->sep_info[i].tsep = AVDT_TSEP_SNK;
- p_scb->sep_info[i].media_type = p_scb->media_type;
- p_scb->sep_info[i].seid = p_seid[i - 1];
- }
-
- /* only in case of local sep as SRC we need to look for other SEPs, In case
- * of SINK we don't */
- if (local_sep == AVDT_TSEP_SRC) {
- /* Make sure UUID has been initialized... */
- if (p_scb->uuid_int == 0) p_scb->uuid_int = p_scb->open_api.uuid;
- bta_av_next_getcap(p_scb, p_data);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_str_opened
- *
- * Description Stream opened OK (incoming/outgoing).
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_str_opened(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- tBTA_AV_CONN_CHG msg;
- char remote_name[BTM_MAX_REM_BD_NAME_LEN] = "";
- uint8_t* p;
-
- APPL_TRACE_DEBUG("%s: peer %s bta_handle: 0x%x", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->hndl);
-
- msg.hdr.layer_specific = p_scb->hndl;
- msg.is_up = true;
- msg.peer_addr = p_scb->PeerAddress();
- p_scb->l2c_cid = AVDT_GetL2CapChannel(p_scb->avdt_handle);
- bta_av_conn_chg((tBTA_AV_DATA*)&msg);
- /* set the congestion flag, so AV would not send media packets by accident */
- p_scb->cong = true;
- // Don't use AVDTP SUSPEND for restrict listed devices
- btif_storage_get_stored_remote_name(p_scb->PeerAddress(), remote_name);
- if (interop_match_name(INTEROP_DISABLE_AVDTP_SUSPEND, remote_name) ||
- interop_match_addr(INTEROP_DISABLE_AVDTP_SUSPEND,
- &p_scb->PeerAddress())) {
- LOG_INFO("%s: disable AVDTP SUSPEND: interop matched name %s address %s",
- __func__, remote_name, p_scb->PeerAddress().ToString().c_str());
- p_scb->suspend_sup = false;
- }
-
- p_scb->stream_mtu =
- p_data->str_msg.msg.open_ind.peer_mtu - AVDT_MEDIA_HDR_SIZE;
- APPL_TRACE_DEBUG("%s: l2c_cid: 0x%x stream_mtu: %d", __func__, p_scb->l2c_cid,
- p_scb->stream_mtu);
-
- /* Set the media channel as high priority */
- L2CA_SetTxPriority(p_scb->l2c_cid, L2CAP_CHNL_PRIORITY_HIGH);
- L2CA_SetChnlFlushability(p_scb->l2c_cid, true);
-
- bta_sys_conn_open(BTA_ID_AV, p_scb->app_id, p_scb->PeerAddress());
- memset(&p_scb->q_info, 0, sizeof(tBTA_AV_Q_INFO));
-
- p_scb->l2c_bufs = 0;
- p_scb->p_cos->open(p_scb->hndl, p_scb->PeerAddress(), p_scb->stream_mtu);
-
- {
- /* TODO check if other audio channel is open.
- * If yes, check if reconfig is needed
- * Rigt now we do not do this kind of checking.
- * BTA-AV is INT for 2nd audio connection.
- * The application needs to make sure the current codec_info is proper.
- * If one audio connection is open and another SNK attempts to connect to
- * AV,
- * the connection will be rejected.
- */
- /* check if other audio channel is started. If yes, start */
- tBTA_AV_OPEN open;
- open.bd_addr = p_scb->PeerAddress();
- open.chnl = p_scb->chnl;
- open.hndl = p_scb->hndl;
- open.status = BTA_AV_SUCCESS;
- open.edr = 0;
- p = BTM_ReadRemoteFeatures(p_scb->PeerAddress());
- if (p != NULL) {
- if (HCI_EDR_ACL_2MPS_SUPPORTED(p)) open.edr |= BTA_AV_EDR_2MBPS;
- if (HCI_EDR_ACL_3MPS_SUPPORTED(p)) {
- if (!interop_match_addr(INTEROP_2MBPS_LINK_ONLY,
- &p_scb->PeerAddress())) {
- open.edr |= BTA_AV_EDR_3MBPS;
- }
- }
- }
- bta_ar_avdt_conn(BTA_ID_AV, open.bd_addr, p_scb->hdi);
- if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC) {
- open.starting = false;
- open.sep = AVDT_TSEP_SNK;
- } else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK) {
- open.starting = bta_av_chk_start(p_scb);
- open.sep = AVDT_TSEP_SRC;
- }
-
- tBTA_AV bta_av_data;
- bta_av_data.open = open;
- (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, &bta_av_data);
- if (open.starting) {
- bta_av_ssm_execute(p_scb, BTA_AV_AP_START_EVT, NULL);
- }
- }
-
- // This code is used to pass PTS TC for AVDTP ABORT
- char value[PROPERTY_VALUE_MAX] = {0};
- if ((osi_property_get("bluetooth.pts.force_a2dp_abort", value, "false")) &&
- (!strcmp(value, "true"))) {
- APPL_TRACE_ERROR("%s: Calling AVDT_AbortReq", __func__);
- AVDT_AbortReq(p_scb->avdt_handle);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_security_ind
- *
- * Description Handle an AVDTP security indication.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_security_ind(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- p_scb->avdt_label = p_data->str_msg.msg.hdr.label;
-
- if (bta_av_cb.features & BTA_AV_FEAT_PROTECT) {
- tBTA_AV_PROTECT_REQ protect_req;
- protect_req.chnl = p_scb->chnl;
- protect_req.hndl = p_scb->hndl;
- protect_req.p_data = p_data->str_msg.msg.security_ind.p_data;
- protect_req.len = p_data->str_msg.msg.security_ind.len;
-
- tBTA_AV bta_av_data;
- bta_av_data.protect_req = protect_req;
- (*bta_av_cb.p_cback)(BTA_AV_PROTECT_REQ_EVT, &bta_av_data);
- }
- /* app doesn't support security indication; respond with failure */
- else {
- AVDT_SecurityRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_NSC, NULL,
- 0);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_security_cfm
- *
- * Description Handle an AVDTP security confirm.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_security_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- if (bta_av_cb.features & BTA_AV_FEAT_PROTECT) {
- tBTA_AV_PROTECT_RSP protect_rsp;
- protect_rsp.chnl = p_scb->chnl;
- protect_rsp.hndl = p_scb->hndl;
- protect_rsp.p_data = p_data->str_msg.msg.security_cfm.p_data;
- protect_rsp.len = p_data->str_msg.msg.security_cfm.len;
- protect_rsp.err_code = p_data->str_msg.msg.hdr.err_code;
-
- tBTA_AV bta_av_data;
- bta_av_data.protect_rsp = protect_rsp;
- (*bta_av_cb.p_cback)(BTA_AV_PROTECT_RSP_EVT, &bta_av_data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_do_close
- *
- * Description Close stream.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_do_close(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- APPL_TRACE_DEBUG("%s: p_scb->co_started=%d", __func__, p_scb->co_started);
-
- /* stop stream if started */
- if (p_scb->co_started) {
- bta_av_str_stopped(p_scb, NULL);
- }
- alarm_cancel(p_scb->link_signalling_timer);
-
- /* close stream */
- p_scb->started = false;
- p_scb->use_rtp_header_marker_bit = false;
-
- /* drop the buffers queued in L2CAP */
- L2CA_FlushChannel(p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL);
-
- AVDT_CloseReq(p_scb->avdt_handle);
- /* just in case that the link is congested, link is flow controled by peer or
- * for whatever reason the the close request can not be sent in time.
- * when this timer expires, AVDT_DisconnectReq will be called to disconnect
- * the link
- */
- bta_sys_start_timer(p_scb->avrc_ct_timer, BTA_AV_CLOSE_REQ_TIME_VAL,
- BTA_AV_API_CLOSE_EVT, p_scb->hndl);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_connect_req
- *
- * Description Connect AVDTP connection.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_connect_req(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- APPL_TRACE_DEBUG("%s: peer %s coll_mask=0x%02x", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->coll_mask);
- p_scb->sdp_discovery_started = false;
- if (p_scb->coll_mask & BTA_AV_COLL_INC_TMR) {
- /* SNK initiated L2C connection while SRC was doing SDP. */
- /* Wait until timeout to check if SNK starts signalling. */
- APPL_TRACE_WARNING("%s: coll_mask=0x%02x incoming timer is up", __func__,
- p_scb->coll_mask);
- p_scb->coll_mask |= BTA_AV_COLL_API_CALLED;
- APPL_TRACE_EVENT("%s: updated coll_mask=0x%02x", __func__,
- p_scb->coll_mask);
- return;
- }
-
- AVDT_ConnectReq(p_scb->PeerAddress(), p_scb->hdi, &bta_av_proc_stream_evt);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_sdp_failed
- *
- * Description Service discovery failed.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_sdp_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- APPL_TRACE_ERROR("%s: peer_addr=%s open_status=%d", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->open_status);
-
- if (p_scb->open_status == BTA_AV_SUCCESS) {
- p_scb->open_status = BTA_AV_FAIL_SDP;
- }
-
- p_scb->sdp_discovery_started = false;
- bta_av_str_closed(p_scb, p_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_disc_results
- *
- * Description Handle the AVDTP discover results. Search through the
- * results and find the first available stream, and get
- * its capabilities.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_disc_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- uint8_t num_snks = 0, num_srcs = 0, i;
- /* our uuid in case we initiate connection */
- uint16_t uuid_int = p_scb->uuid_int;
-
- APPL_TRACE_DEBUG("%s: peer %s bta_handle: 0x%x initiator UUID 0x%x", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->hndl,
- uuid_int);
-
- /* store number of stream endpoints returned */
- p_scb->num_seps = p_data->str_msg.msg.discover_cfm.num_seps;
-
- for (i = 0; i < p_scb->num_seps; i++) {
- /* steam not in use, is a sink, and is audio */
- if ((!p_scb->sep_info[i].in_use) &&
- (p_scb->sep_info[i].media_type == p_scb->media_type)) {
- if ((p_scb->sep_info[i].tsep == AVDT_TSEP_SNK) &&
- (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE))
- num_snks++;
-
- if ((p_scb->sep_info[i].tsep == AVDT_TSEP_SRC) &&
- (uuid_int == UUID_SERVCLASS_AUDIO_SINK))
- num_srcs++;
- }
- }
-
- p_scb->p_cos->disc_res(p_scb->hndl, p_scb->PeerAddress(), p_scb->num_seps,
- num_snks, num_srcs, uuid_int);
- p_scb->num_disc_snks = num_snks;
- p_scb->num_disc_srcs = num_srcs;
-
- /* if we got any */
- if (p_scb->num_seps > 0) {
- /* initialize index into discovery results */
- p_scb->sep_info_idx = 0;
-
- /* get the capabilities of the first available stream */
- bta_av_next_getcap(p_scb, p_data);
- }
- /* else we got discover response but with no streams; we're done */
- else {
- APPL_TRACE_ERROR("%s: BTA_AV_STR_DISC_FAIL_EVT: peer_addr=%s", __func__,
- p_scb->PeerAddress().ToString().c_str());
- bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, p_data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_disc_res_as_acp
- *
- * Description Handle the AVDTP discover results. Search through the
- * results and find the first available stream, and get
- * its capabilities.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_disc_res_as_acp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- uint8_t num_snks = 0, i;
-
- APPL_TRACE_DEBUG("%s: peer %s bta_handle: 0x%x", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->hndl);
-
- /* store number of stream endpoints returned */
- p_scb->num_seps = p_data->str_msg.msg.discover_cfm.num_seps;
-
- for (i = 0; i < p_scb->num_seps; i++) {
- /* steam is a sink, and is audio */
- if ((p_scb->sep_info[i].tsep == AVDT_TSEP_SNK) &&
- (p_scb->sep_info[i].media_type == p_scb->media_type)) {
- p_scb->sep_info[i].in_use = false;
- num_snks++;
- }
- }
- p_scb->p_cos->disc_res(p_scb->hndl, p_scb->PeerAddress(), p_scb->num_seps,
- num_snks, 0, UUID_SERVCLASS_AUDIO_SOURCE);
- p_scb->num_disc_snks = num_snks;
- p_scb->num_disc_srcs = 0;
-
- /* if we got any */
- if (p_scb->num_seps > 0) {
- /* initialize index into discovery results */
- p_scb->sep_info_idx = 0;
-
- /* get the capabilities of the first available stream */
- bta_av_next_getcap(p_scb, p_data);
- }
- /* else we got discover response but with no streams; we're done */
- else {
- APPL_TRACE_ERROR("%s: BTA_AV_STR_DISC_FAIL_EVT: peer_addr=%s", __func__,
- p_scb->PeerAddress().ToString().c_str());
- bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, p_data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_save_caps
- *
- * Description report the SNK SEP capabilities to application
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_save_caps(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- AvdtpSepConfig cfg;
- tAVDT_SEP_INFO* p_info = &p_scb->sep_info[p_scb->sep_info_idx];
- uint8_t old_wait = p_scb->wait;
- bool getcap_done = false;
-
- APPL_TRACE_DEBUG(
- "%s: peer %s bta_handle:0x%x num_seps:%d sep_info_idx:%d wait:0x%x",
- __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->hndl,
- p_scb->num_seps, p_scb->sep_info_idx, p_scb->wait);
- APPL_TRACE_DEBUG("%s: codec: %s", __func__,
- A2DP_CodecInfoString(p_scb->peer_cap.codec_info).c_str());
-
- cfg = p_scb->peer_cap;
- /* let application know the capability of the SNK */
- if (p_scb->p_cos->getcfg(p_scb->hndl, p_scb->PeerAddress(), cfg.codec_info,
- &p_scb->sep_info_idx, p_info->seid, &cfg.num_protect,
- cfg.protect_info) != A2DP_SUCCESS) {
- p_scb->sep_info_idx++;
- APPL_TRACE_DEBUG("%s: result: next sep_info_idx:%d", __func__,
- p_scb->sep_info_idx);
- } else {
- // All capabilities found
- getcap_done = true;
- APPL_TRACE_DEBUG("%s: result: done sep_info_idx:%d", __func__,
- p_scb->sep_info_idx);
- }
- APPL_TRACE_DEBUG("%s: codec: %s", __func__,
- A2DP_CodecInfoString(cfg.codec_info).c_str());
-
- if (p_scb->num_seps > p_scb->sep_info_idx && !getcap_done) {
- /* Some devices have seps at the end of the discover list, which is not */
- /* matching media type(video not audio). */
- /* In this case, we are done with getcap without sending another */
- /* request to AVDT. */
- if (!bta_av_next_getcap(p_scb, p_data)) getcap_done = true;
- } else {
- getcap_done = true;
- }
-
- if (getcap_done) {
- APPL_TRACE_DEBUG("%s: getcap_done: num_seps:%d sep_info_idx:%d wait:0x%x",
- __func__, p_scb->num_seps, p_scb->sep_info_idx,
- p_scb->wait);
- p_scb->wait &= ~(BTA_AV_WAIT_ACP_CAPS_ON | BTA_AV_WAIT_ACP_CAPS_STARTED);
- if (old_wait & BTA_AV_WAIT_ACP_CAPS_STARTED) {
- bta_av_start_ok(p_scb, NULL);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_set_use_rc
- *
- * Description set to use AVRC for this stream control block.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_set_use_rc(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- p_scb->use_rc = true;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_cco_close
- *
- * Description call close call-out function.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_cco_close(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- APPL_TRACE_DEBUG("%s: peer %s bta_handle:0x%x", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->hndl);
- p_scb->p_cos->close(p_scb->hndl, p_scb->PeerAddress());
-}
-
-/*******************************************************************************
- *
- * Function bta_av_open_failed
- *
- * Description Failed to open an AVDT stream
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_open_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- bool is_av_opened = false;
- tBTA_AV_SCB* p_opened_scb = NULL;
- uint8_t idx;
-
- APPL_TRACE_ERROR("%s: peer_addr=%s", __func__,
- p_scb->PeerAddress().ToString().c_str());
- p_scb->open_status = BTA_AV_FAIL_STREAM;
- bta_av_cco_close(p_scb, p_data);
-
- /* check whether there is already an opened audio or video connection with the
- * same device */
- for (idx = 0; (idx < BTA_AV_NUM_STRS) && (!is_av_opened); idx++) {
- p_opened_scb = bta_av_cb.p_scb[idx];
- if (p_opened_scb && (p_opened_scb->state == BTA_AV_OPEN_SST) &&
- (p_opened_scb->PeerAddress() == p_scb->PeerAddress()))
- is_av_opened = true;
- }
-
- /* if there is already an active AV connnection with the same bd_addr,
- don't send disconnect req, just report the open event with
- BTA_AV_FAIL_GET_CAP status */
- if (is_av_opened) {
- tBTA_AV_OPEN open;
- open.bd_addr = p_scb->PeerAddress();
- open.chnl = p_scb->chnl;
- open.hndl = p_scb->hndl;
- open.status = BTA_AV_FAIL_GET_CAP;
- open.starting = bta_av_chk_start(p_scb);
- open.edr = 0;
- /* set the state back to initial state */
- bta_av_set_scb_sst_init(p_scb);
-
- if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC) {
- open.sep = AVDT_TSEP_SNK;
- } else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK) {
- open.sep = AVDT_TSEP_SRC;
- }
-
- APPL_TRACE_ERROR(
- "%s: there is already an active connection: peer_addr=%s chnl=%d "
- "hndl=0x%x status=%d starting=%d edr=%d",
- __func__, open.bd_addr.ToString().c_str(), open.chnl, open.hndl,
- open.status, open.starting, open.edr);
-
- tBTA_AV bta_av_data;
- bta_av_data.open = open;
- (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, &bta_av_data);
- } else {
- AVDT_DisconnectReq(p_scb->PeerAddress(), &bta_av_proc_stream_evt);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_getcap_results
- *
- * Description Handle the AVDTP get capabilities results. Check the codec
- * type and see if it matches ours. If it does not, get the
- * capabilities of the next stream, if any.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_getcap_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- AvdtpSepConfig cfg = p_scb->cfg;
- uint8_t media_type = A2DP_GetMediaType(p_scb->peer_cap.codec_info);
- tAVDT_SEP_INFO* p_info = &p_scb->sep_info[p_scb->sep_info_idx];
-
- cfg.num_codec = 1;
- cfg.num_protect = p_scb->peer_cap.num_protect;
- memcpy(cfg.codec_info, p_scb->peer_cap.codec_info, AVDT_CODEC_SIZE);
- memcpy(cfg.protect_info, p_scb->peer_cap.protect_info, AVDT_PROTECT_SIZE);
-
- APPL_TRACE_DEBUG("%s: peer %s bta_handle:0x%x num_codec:%d psc_mask=0x%x",
- __func__, p_scb->PeerAddress().ToString().c_str(),
- p_scb->hndl, p_scb->peer_cap.num_codec, p_scb->cfg.psc_mask);
- APPL_TRACE_DEBUG("%s: media type 0x%x, 0x%x", __func__, media_type,
- p_scb->media_type);
- APPL_TRACE_DEBUG("%s: codec: %s", __func__,
- A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str());
-
- /* if codec present and we get a codec configuration */
- if ((p_scb->peer_cap.num_codec != 0) && (media_type == p_scb->media_type) &&
- (p_scb->p_cos->getcfg(p_scb->hndl, p_scb->PeerAddress(), cfg.codec_info,
- &p_scb->sep_info_idx, p_info->seid,
- &cfg.num_protect,
- cfg.protect_info) == A2DP_SUCCESS)) {
- /* UUID for which connection was initiatied */
- uint16_t uuid_int = p_scb->uuid_int;
-
- /* save copy of codec configuration */
- p_scb->cfg = cfg;
-
- APPL_TRACE_DEBUG("%s: result: sep_info_idx=%d", __func__,
- p_scb->sep_info_idx);
- APPL_TRACE_DEBUG("%s: codec: %s", __func__,
- A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str());
-
- APPL_TRACE_DEBUG("%s: initiator UUID = 0x%x", __func__, uuid_int);
- if (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE)
- bta_av_adjust_seps_idx(p_scb,
- bta_av_get_scb_handle(p_scb, AVDT_TSEP_SRC));
- else if (uuid_int == UUID_SERVCLASS_AUDIO_SINK)
- bta_av_adjust_seps_idx(p_scb,
- bta_av_get_scb_handle(p_scb, AVDT_TSEP_SNK));
- LOG_INFO("%s: sep_idx=%d avdt_handle=%d bta_handle=0x%x", __func__,
- p_scb->sep_idx, p_scb->avdt_handle, p_scb->hndl);
-
- /* use only the services peer supports */
- cfg.psc_mask &= p_scb->peer_cap.psc_mask;
- p_scb->cur_psc_mask = cfg.psc_mask;
- APPL_TRACE_DEBUG(
- "%s: peer %s bta_handle:0x%x sep_idx:%d sep_info_idx:%d "
- "cur_psc_mask:0x%x",
- __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->hndl,
- p_scb->sep_idx, p_scb->sep_info_idx, p_scb->cur_psc_mask);
-
- if ((uuid_int == UUID_SERVCLASS_AUDIO_SINK) &&
- (p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback != NULL)) {
- APPL_TRACE_DEBUG("%s: configure decoder for Sink connection", __func__);
- tBTA_AV_MEDIA av_sink_codec_info;
- av_sink_codec_info.avk_config.bd_addr = p_scb->PeerAddress();
- av_sink_codec_info.avk_config.codec_info = p_scb->cfg.codec_info;
- p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback(
- p_scb->PeerAddress(), BTA_AV_SINK_MEDIA_CFG_EVT, &av_sink_codec_info);
- }
-
- if (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE) {
- A2DP_AdjustCodec(cfg.codec_info);
- }
-
- /* open the stream */
- AVDT_OpenReq(p_scb->seps[p_scb->sep_idx].av_handle, p_scb->PeerAddress(),
- p_scb->hdi, p_scb->sep_info[p_scb->sep_info_idx].seid, &cfg);
- } else {
- /* try the next stream, if any */
- p_scb->sep_info_idx++;
- bta_av_next_getcap(p_scb, p_data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_setconfig_rej
- *
- * Description Send AVDTP set config reject.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_setconfig_rej(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- tBTA_AV_REJECT reject;
- uint8_t avdt_handle = p_data->ci_setconfig.avdt_handle;
-
- bta_av_adjust_seps_idx(p_scb, avdt_handle);
- LOG_INFO("%s: sep_idx=%d avdt_handle=%d bta_handle=0x%x", __func__,
- p_scb->sep_idx, p_scb->avdt_handle, p_scb->hndl);
- AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_UNSUP_CFG, 0);
-
- reject.bd_addr = p_data->str_msg.bd_addr;
- reject.hndl = p_scb->hndl;
-
- tBTA_AV bta_av_data;
- bta_av_data.reject = reject;
- (*bta_av_cb.p_cback)(BTA_AV_REJECT_EVT, &bta_av_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_discover_req
- *
- * Description Send an AVDTP discover request to the peer.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_discover_req(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- /* send avdtp discover request */
-
- AVDT_DiscoverReq(p_scb->PeerAddress(), p_scb->hdi, p_scb->sep_info,
- BTA_AV_NUM_SEPS, &bta_av_proc_stream_evt);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_conn_failed
- *
- * Description AVDTP connection failed.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_conn_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- APPL_TRACE_ERROR("%s: peer_addr=%s open_status=%d", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->open_status);
-
- p_scb->open_status = BTA_AV_FAIL_STREAM;
- bta_av_str_closed(p_scb, p_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_do_start
- *
- * Description Start stream.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_do_start(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- LOG_INFO(
- "A2dp stream start peer:%s sco_occupied:%s av_role:0x%x started:%s "
- "wait:0x%x",
- PRIVATE_ADDRESS(p_scb->PeerAddress()),
- logbool(bta_av_cb.sco_occupied).c_str(), p_scb->role,
- logbool(p_scb->started).c_str(), p_scb->wait);
- if (bta_av_cb.sco_occupied) {
- LOG_WARN("A2dp stream start failed");
- bta_av_start_failed(p_scb, p_data);
- return;
- }
-
- if (p_scb->started) {
- p_scb->role |= BTA_AV_ROLE_START_INT;
- if (p_scb->wait != 0) {
- LOG_WARN(
- "%s: peer %s start stream request ignored: "
- "already waiting: sco_occupied:%s role:0x%x started:%s wait:0x%x",
- __func__, p_scb->PeerAddress().ToString().c_str(),
- logbool(bta_av_cb.sco_occupied).c_str(), p_scb->role,
- logbool(p_scb->started).c_str(), p_scb->wait);
- return;
- }
- if (p_scb->role & BTA_AV_ROLE_SUSPEND) {
- notify_start_failed(p_scb);
- } else {
- bta_av_start_ok(p_scb, NULL);
- }
- return;
- }
-
- if ((p_scb->role & BTA_AV_ROLE_START_INT) != 0) {
- LOG_WARN(
- "%s: peer %s start stream request ignored: "
- "already initiated: sco_occupied:%s role:0x%x started:%s wait:0x%x",
- __func__, p_scb->PeerAddress().ToString().c_str(),
- logbool(bta_av_cb.sco_occupied).c_str(), p_scb->role,
- logbool(p_scb->started).c_str(), p_scb->wait);
- return;
- }
-
- p_scb->role |= BTA_AV_ROLE_START_INT;
- bta_sys_busy(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->PeerAddress());
- /* disallow role switch during streaming, only if we are the central role
- * i.e. allow role switch, if we are peripheral.
- * It would not hurt us, if the peer device wants us to be central
- * disable sniff mode unconditionally during streaming */
- tHCI_ROLE cur_role;
- if ((BTM_GetRole(p_scb->PeerAddress(), &cur_role) == BTM_SUCCESS) &&
- (cur_role == HCI_ROLE_CENTRAL)) {
- BTM_block_role_switch_and_sniff_mode_for(p_scb->PeerAddress());
- } else {
- BTM_block_sniff_mode_for(p_scb->PeerAddress());
- }
-
- uint16_t result = AVDT_StartReq(&p_scb->avdt_handle, 1);
- if (result != AVDT_SUCCESS) {
- LOG_ERROR("%s: AVDT_StartReq failed for peer %s result:%d", __func__,
- p_scb->PeerAddress().ToString().c_str(), result);
- bta_av_start_failed(p_scb, p_data);
- }
- LOG_INFO(
- "%s: peer %s start requested: sco_occupied:%s role:0x%x "
- "started:%s wait:0x%x",
- __func__, p_scb->PeerAddress().ToString().c_str(),
- logbool(bta_av_cb.sco_occupied).c_str(), p_scb->role,
- logbool(p_scb->started).c_str(), p_scb->wait);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_str_stopped
- *
- * Description Stream stopped.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_str_stopped(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- tBTA_AV_SUSPEND suspend_rsp;
- uint8_t start = p_scb->started;
- bool sus_evt = true;
- BT_HDR* p_buf;
-
- APPL_TRACE_ERROR(
- "%s: peer %s bta_handle:0x%x audio_open_cnt:%d, p_data %p start:%d",
- __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->hndl,
- bta_av_cb.audio_open_cnt, p_data, start);
-
- bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->PeerAddress());
- BTM_unblock_role_switch_and_sniff_mode_for(p_scb->PeerAddress());
-
- if (p_scb->co_started) {
- uint16_t handle = get_btm_client_interface().lifecycle.BTM_GetHCIConnHandle(
- p_scb->PeerAddress(), BT_TRANSPORT_BR_EDR);
- if (bta_av_cb.offload_started_acl_hdl == handle) {
- bta_av_vendor_offload_stop();
- bta_av_cb.offload_started_acl_hdl = HCI_INVALID_HANDLE;
- } else if (bta_av_cb.offload_start_pending_acl_hdl == handle) {
- APPL_TRACE_WARNING("%s: Stop pending offload start command", __func__);
- bta_av_vendor_offload_stop();
- bta_av_cb.offload_start_pending_acl_hdl = HCI_INVALID_HANDLE;
- }
-
- bta_av_stream_chg(p_scb, false);
- p_scb->co_started = false;
-
- p_scb->p_cos->stop(p_scb->hndl, p_scb->PeerAddress());
- }
-
- /* if q_info.a2dp_list is not empty, drop it now */
- if (BTA_AV_CHNL_AUDIO == p_scb->chnl) {
- while (!list_is_empty(p_scb->a2dp_list)) {
- p_buf = (BT_HDR*)list_front(p_scb->a2dp_list);
- list_remove(p_scb->a2dp_list, p_buf);
- osi_free(p_buf);
- }
-
- /* drop the audio buffers queued in L2CAP */
- if (p_data && p_data->api_stop.flush)
- L2CA_FlushChannel(p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL);
- }
-
- suspend_rsp.chnl = p_scb->chnl;
- suspend_rsp.hndl = p_scb->hndl;
-
- if (p_data && p_data->api_stop.suspend) {
- APPL_TRACE_DEBUG("%s: peer %s suspending: %d, sup:%d", __func__,
- p_scb->PeerAddress().ToString().c_str(), start,
- p_scb->suspend_sup);
- if ((start) && (p_scb->suspend_sup)) {
- sus_evt = false;
- p_scb->l2c_bufs = 0;
- AVDT_SuspendReq(&p_scb->avdt_handle, 1);
- }
-
- /* send SUSPEND_EVT event only if not in reconfiguring state and sus_evt is
- * true*/
- if ((sus_evt) && (p_scb->state != BTA_AV_RCFG_SST)) {
- suspend_rsp.status = BTA_AV_SUCCESS;
- suspend_rsp.initiator = true;
- tBTA_AV bta_av_data;
- bta_av_data.suspend = suspend_rsp;
- (*bta_av_cb.p_cback)(BTA_AV_SUSPEND_EVT, &bta_av_data);
- }
- } else {
- suspend_rsp.status = BTA_AV_SUCCESS;
- suspend_rsp.initiator = true;
- APPL_TRACE_EVENT("%s: status %d", __func__, suspend_rsp.status);
-
- // Send STOP_EVT event only if not in reconfiguring state.
- // However, we should send STOP_EVT if we are reconfiguring when taking
- // the Close->Configure->Open->Start path.
- if (p_scb->state != BTA_AV_RCFG_SST ||
- (p_data && p_data->api_stop.reconfig_stop)) {
- tBTA_AV bta_av_data;
- bta_av_data.suspend = suspend_rsp;
- (*bta_av_cb.p_cback)(BTA_AV_STOP_EVT, &bta_av_data);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_reconfig
- *
- * Description process the reconfigure request.
- * save the parameter in control block and
- * suspend, reconfigure or close the stream
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_reconfig(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- AvdtpSepConfig* p_cfg;
- tBTA_AV_API_STOP stop;
- tBTA_AV_API_RCFG* p_rcfg = &p_data->api_reconfig;
-
- APPL_TRACE_DEBUG("%s: r:%d, s:%d idx: %d (o:%d)", __func__, p_scb->recfg_sup,
- p_scb->suspend_sup, p_scb->rcfg_idx, p_scb->sep_info_idx);
-
- p_scb->num_recfg = 0;
- /* store the new configuration in control block */
- p_cfg = &p_scb->cfg;
-
- alarm_cancel(p_scb->avrc_ct_timer);
-
- LOG_DEBUG("p_scb->sep_info_idx=%d p_scb->rcfg_idx=%d p_rcfg->sep_info_idx=%d",
- p_scb->sep_info_idx, p_scb->rcfg_idx, p_rcfg->sep_info_idx);
- LOG_DEBUG("Peer capable codec: %s",
- A2DP_CodecInfoString(p_scb->peer_cap.codec_info).c_str());
- LOG_DEBUG("Current codec: %s",
- A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str());
- LOG_DEBUG("Reconfig codec: %s",
- A2DP_CodecInfoString(p_rcfg->codec_info).c_str());
-
- BTM_LogHistory(
- kBtmLogTag, p_scb->PeerAddress(), "Codec reconfig",
- base::StringPrintf("%s => %s", A2DP_CodecName(p_scb->cfg.codec_info),
- A2DP_CodecName(p_rcfg->codec_info)));
-
- p_cfg->num_protect = p_rcfg->num_protect;
- memcpy(p_cfg->codec_info, p_rcfg->codec_info, AVDT_CODEC_SIZE);
- memcpy(p_cfg->protect_info, p_rcfg->p_protect_info, p_rcfg->num_protect);
- p_scb->rcfg_idx = p_rcfg->sep_info_idx;
- p_cfg->psc_mask = p_scb->cur_psc_mask;
-
- // If the requested SEP index is same as the current one, then we
- // can Suspend->Reconfigure->Start.
- // Otherwise, we have to Close->Configure->Open->Start or
- // Close->Configure->Open for streams that are / are not started.
- if ((p_scb->rcfg_idx == p_scb->sep_info_idx) && p_rcfg->suspend &&
- p_scb->recfg_sup && p_scb->suspend_sup) {
- if (p_scb->started) {
- // Suspend->Reconfigure->Start
- stop.flush = false;
- stop.suspend = true;
- stop.reconfig_stop = false;
- bta_av_str_stopped(p_scb, (tBTA_AV_DATA*)&stop);
- } else {
- // Reconfigure
- APPL_TRACE_DEBUG("%s: reconfig", __func__);
- APPL_TRACE_DEBUG("%s: codec: %s", __func__,
- A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str());
- AVDT_ReconfigReq(p_scb->avdt_handle, &p_scb->cfg);
- p_scb->cfg.psc_mask = p_scb->cur_psc_mask;
- }
- } else {
- // Close the stream first, and then Configure it
- APPL_TRACE_DEBUG("%s: Close/Open started: %d state: %d num_protect: %d",
- __func__, p_scb->started, p_scb->state,
- p_cfg->num_protect);
- if (p_scb->started) {
- // Close->Configure->Open->Start
- if ((p_scb->rcfg_idx != p_scb->sep_info_idx) && p_scb->recfg_sup) {
- // Make sure we trigger STOP_EVT when taking the longer road to
- // reconfiguration, otherwise we don't call Start.
- stop.flush = false;
- stop.suspend = false;
- stop.reconfig_stop = true;
- bta_av_str_stopped(p_scb, (tBTA_AV_DATA*)&stop);
- } else {
- bta_av_str_stopped(p_scb, NULL);
- }
- p_scb->started = false;
- } else {
- // Close->Configure->Open
- bta_av_str_stopped(p_scb, NULL);
- }
- // Drop the buffers queued in L2CAP
- L2CA_FlushChannel(p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL);
- AVDT_CloseReq(p_scb->avdt_handle);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_data_path
- *
- * Description Handle stream data path.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_data_path(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- BT_HDR* p_buf = NULL;
- uint32_t timestamp;
- bool new_buf = false;
- uint8_t m_pt = 0x60;
- tAVDT_DATA_OPT_MASK opt;
-
- if (!p_scb->started) return;
-
- if (p_scb->cong) return;
-
- if (p_scb->use_rtp_header_marker_bit) {
- m_pt |= AVDT_MARKER_SET;
- }
-
- // Always get the current number of bufs que'd up
- p_scb->l2c_bufs =
- (uint8_t)L2CA_FlushChannel(p_scb->l2c_cid, L2CAP_FLUSH_CHANS_GET);
-
- if (!list_is_empty(p_scb->a2dp_list)) {
- p_buf = (BT_HDR*)list_front(p_scb->a2dp_list);
- list_remove(p_scb->a2dp_list, p_buf);
- /* use q_info.a2dp data, read the timestamp */
- timestamp = *(uint32_t*)(p_buf + 1);
- } else {
- new_buf = true;
- /* A2DP_list empty, call co_data, dup data to other channels */
- p_buf = p_scb->p_cos->data(p_scb->cfg.codec_info, ×tamp);
-
- if (p_buf) {
- /* use the offset area for the time stamp */
- *(uint32_t*)(p_buf + 1) = timestamp;
-
- /* dup the data to other channels */
- bta_av_dup_audio_buf(p_scb, p_buf);
- }
- }
-
- if (p_buf) {
- if (p_scb->l2c_bufs < (BTA_AV_QUEUE_DATA_CHK_NUM)) {
- /* There's a buffer, just queue it to L2CAP.
- * There's no need to increment it here, it is always read from
- * L2CAP (see above).
- */
-
- /* opt is a bit mask, it could have several options set */
- opt = AVDT_DATA_OPT_NONE;
- if (p_scb->no_rtp_header) {
- opt |= AVDT_DATA_OPT_NO_RTP;
- }
-
- //
- // Fragment the payload if larger than the MTU.
- // NOTE: The fragmentation is RTP-compatibie.
- //
- size_t extra_fragments_n = 0;
- if (p_buf->len > 0) {
- extra_fragments_n = (p_buf->len / p_scb->stream_mtu) +
- ((p_buf->len % p_scb->stream_mtu) ? 1 : 0) - 1;
- }
- std::vector<BT_HDR*> extra_fragments;
- extra_fragments.reserve(extra_fragments_n);
-
- uint8_t* data_begin = (uint8_t*)(p_buf + 1) + p_buf->offset;
- uint8_t* data_end = (uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len;
- while (extra_fragments_n-- > 0) {
- data_begin += p_scb->stream_mtu;
- size_t fragment_len = data_end - data_begin;
- if (fragment_len > p_scb->stream_mtu) fragment_len = p_scb->stream_mtu;
-
- BT_HDR* p_buf2 = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
- p_buf2->offset = p_buf->offset;
- p_buf2->len = 0;
- p_buf2->layer_specific = 0;
- uint8_t* packet2 =
- (uint8_t*)(p_buf2 + 1) + p_buf2->offset + p_buf2->len;
- memcpy(packet2, data_begin, fragment_len);
- p_buf2->len += fragment_len;
- extra_fragments.push_back(p_buf2);
- p_buf->len -= fragment_len;
- }
-
- if (!extra_fragments.empty()) {
- // Reset the RTP Marker bit for all fragments except the last one
- m_pt &= ~AVDT_MARKER_SET;
- }
- AVDT_WriteReqOpt(p_scb->avdt_handle, p_buf, timestamp, m_pt, opt);
- for (size_t i = 0; i < extra_fragments.size(); i++) {
- if (i + 1 == extra_fragments.size()) {
- // Set the RTP Marker bit for the last fragment
- m_pt |= AVDT_MARKER_SET;
- }
- BT_HDR* p_buf2 = extra_fragments[i];
- AVDT_WriteReqOpt(p_scb->avdt_handle, p_buf2, timestamp, m_pt, opt);
- }
- p_scb->cong = true;
- } else {
- /* there's a buffer, but L2CAP does not seem to be moving data */
- if (new_buf) {
- /* just got this buffer from co_data,
- * put it in queue */
- list_append(p_scb->a2dp_list, p_buf);
- } else {
- /* just dequeue it from the a2dp_list */
- if (list_length(p_scb->a2dp_list) < 3) {
- /* put it back to the queue */
- list_prepend(p_scb->a2dp_list, p_buf);
- } else {
- /* too many buffers in a2dp_list, drop it. */
- bta_av_co_audio_drop(p_scb->hndl, p_scb->PeerAddress());
- osi_free(p_buf);
- }
- }
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_start_ok
- *
- * Description Stream started.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_start_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- bool initiator = false;
- bool suspend = false;
- uint8_t new_role = p_scb->role;
- BT_HDR_RIGID hdr;
- tHCI_ROLE cur_role;
- uint8_t local_tsep = p_scb->seps[p_scb->sep_idx].tsep;
-
- LOG_INFO("%s: peer %s bta_handle:0x%x wait:0x%x role:0x%x local_tsep:%d",
- __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->hndl,
- p_scb->wait, p_scb->role, local_tsep);
-
- p_scb->started = true;
-
- if (local_tsep == AVDT_TSEP_SRC) {
- // The RTP Header marker bit for the A2DP Source encoder
- A2dpCodecConfig* codec_config =
- bta_av_get_a2dp_peer_current_codec(p_scb->PeerAddress());
- CHECK(codec_config != nullptr);
- p_scb->use_rtp_header_marker_bit = codec_config->useRtpHeaderMarkerBit();
- }
-
- if (p_scb->sco_suspend) {
- p_scb->sco_suspend = false;
- }
-
- if (new_role & BTA_AV_ROLE_START_INT) initiator = true;
-
- /* for A2DP SINK we do not send get_caps */
- if ((p_scb->avdt_handle == p_scb->seps[p_scb->sep_idx].av_handle) &&
- (local_tsep == AVDT_TSEP_SNK)) {
- p_scb->wait &= ~(BTA_AV_WAIT_ACP_CAPS_ON);
- APPL_TRACE_DEBUG("%s: local SEP type is SNK new wait is 0x%x", __func__,
- p_scb->wait);
- }
- if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_FAILED) {
- /* role switch has failed */
- APPL_TRACE_ERROR(
- "%s: peer %s role switch failed: bta_handle:0x%x wait:0x%x, role:0x%x",
- __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->hndl,
- p_scb->wait, p_scb->role);
- p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_FAILED;
- p_data = (tBTA_AV_DATA*)&hdr;
- hdr.offset = BTA_AV_RS_FAIL;
- }
- APPL_TRACE_DEBUG("%s: peer %s wait:0x%x use_rtp_header_marker_bit:%s",
- __func__, p_scb->PeerAddress().ToString().c_str(),
- p_scb->wait,
- (p_scb->use_rtp_header_marker_bit) ? "true" : "false");
-
- if (p_data && (p_data->hdr.offset != BTA_AV_RS_NONE)) {
- p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
- if (p_data->hdr.offset == BTA_AV_RS_FAIL) {
- bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->PeerAddress());
- tBTA_AV_START start;
- start.chnl = p_scb->chnl;
- start.status = BTA_AV_FAIL_ROLE;
- start.hndl = p_scb->hndl;
- start.initiator = initiator;
- tBTA_AV bta_av_data;
- bta_av_data.start = start;
- (*bta_av_cb.p_cback)(BTA_AV_START_EVT, &bta_av_data);
- return;
- }
- }
-
- if (!bta_av_link_role_ok(p_scb, A2DP_SET_ONE_BIT))
- p_scb->q_tag = BTA_AV_Q_TAG_START;
- else {
- /* The wait flag may be set here while we are already central on the link */
- /* this could happen if a role switch complete event occurred during
- * reconfig */
- /* if we are now central on the link, there is no need to wait for the role
- * switch, */
- /* complete anymore so we can clear the wait for role switch flag */
- p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
- }
-
- if (p_scb->wait &
- (BTA_AV_WAIT_ROLE_SW_RES_OPEN | BTA_AV_WAIT_ROLE_SW_RES_START)) {
- p_scb->wait |= BTA_AV_WAIT_ROLE_SW_STARTED;
- p_scb->q_tag = BTA_AV_Q_TAG_START;
- }
-
- if (p_scb->wait) {
- APPL_TRACE_ERROR("%s: peer %s wait:0x%x q_tag:%d not started", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->wait,
- p_scb->q_tag);
- /* Clear first bit of p_scb->wait and not to return from this point else
- * HAL layer gets blocked. And if there is delay in Get Capability response
- * as
- * first bit of p_scb->wait is cleared hence it ensures bt_av_start_ok is
- * not called
- * again from bta_av_save_caps.
- */
- p_scb->wait &= ~BTA_AV_WAIT_ACP_CAPS_ON;
- }
-
- /* tell role manager to check M/S role */
- bta_sys_conn_open(BTA_ID_AV, p_scb->app_id, p_scb->PeerAddress());
-
- bta_sys_busy(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->PeerAddress());
-
- if (p_scb->media_type == AVDT_MEDIA_TYPE_AUDIO) {
- /* in normal logic, conns should be bta_av_cb.audio_count - 1,
- * However, bta_av_stream_chg is not called to increase
- * bta_av_cb.audio_count yet.
- * If the code were to be re-arranged for some reasons, this number may need
- * to be changed
- */
- p_scb->co_started = bta_av_cb.audio_open_cnt;
- }
-
- /* clear the congestion flag */
- p_scb->cong = false;
-
- if (new_role & BTA_AV_ROLE_START_INT) {
- new_role &= ~BTA_AV_ROLE_START_INT;
- } else if ((new_role & BTA_AV_ROLE_AD_ACP) &&
- (new_role & BTA_AV_ROLE_SUSPEND_OPT)) {
- suspend = true;
- }
-
- if (!suspend) {
- p_scb->q_tag = BTA_AV_Q_TAG_STREAM;
- bta_av_stream_chg(p_scb, true);
- }
-
- {
- /* If sink starts stream, disable sniff mode here */
- if (!initiator) {
- /* If souce is the central role, disable role switch during streaming.
- * Otherwise allow role switch, if source is peripheral.
- * Because it would not hurt source, if the peer device wants source to be
- * central.
- * disable sniff mode unconditionally during streaming */
- if ((BTM_GetRole(p_scb->PeerAddress(), &cur_role) == BTM_SUCCESS) &&
- (cur_role == HCI_ROLE_CENTRAL)) {
- BTM_block_role_switch_and_sniff_mode_for(p_scb->PeerAddress());
- } else {
- BTM_block_sniff_mode_for(p_scb->PeerAddress());
- }
- }
-
- p_scb->role = new_role;
- p_scb->role &= ~BTA_AV_ROLE_AD_ACP;
- p_scb->role &= ~BTA_AV_ROLE_SUSPEND_OPT;
-
- p_scb->no_rtp_header = false;
- p_scb->p_cos->start(p_scb->hndl, p_scb->PeerAddress(),
- p_scb->cfg.codec_info, &p_scb->no_rtp_header);
- p_scb->co_started = true;
-
- APPL_TRACE_DEBUG("%s: peer %s suspending: %d, role:0x%x, init %d", __func__,
- p_scb->PeerAddress().ToString().c_str(), suspend,
- p_scb->role, initiator);
-
- tBTA_AV_START start;
- start.suspending = suspend;
- start.initiator = initiator;
- start.chnl = p_scb->chnl;
- start.status = BTA_AV_SUCCESS;
- start.hndl = p_scb->hndl;
- tBTA_AV bta_av_data;
- bta_av_data.start = start;
- (*bta_av_cb.p_cback)(BTA_AV_START_EVT, &bta_av_data);
-
- if (suspend) {
- tBTA_AV_API_STOP stop;
- p_scb->role |= BTA_AV_ROLE_SUSPEND;
- p_scb->cong = true; /* do not allow the media data to go through */
- /* do not duplicate the media packets to this channel */
- p_scb->p_cos->stop(p_scb->hndl, p_scb->PeerAddress());
- p_scb->co_started = false;
- stop.flush = false;
- stop.suspend = true;
- stop.reconfig_stop = false;
- bta_av_ssm_execute(p_scb, BTA_AV_AP_STOP_EVT, (tBTA_AV_DATA*)&stop);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_start_failed
- *
- * Description Stream start failed.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_start_failed(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- APPL_TRACE_ERROR(
- "%s: peer %s bta_handle:0x%x audio_open_cnt:%d started:%s co_started:%d",
- __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->hndl,
- bta_av_cb.audio_open_cnt, logbool(p_scb->started).c_str(),
- p_scb->co_started);
-
- if (!p_scb->started && !p_scb->co_started) {
- bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->PeerAddress());
- notify_start_failed(p_scb);
- }
-
- BTM_unblock_role_switch_and_sniff_mode_for(p_scb->PeerAddress());
- p_scb->sco_suspend = false;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_str_closed
- *
- * Description Stream closed.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_str_closed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- tBTA_AV data;
- tBTA_AV_EVT event;
-
- APPL_TRACE_WARNING(
- "%s: peer %s bta_handle:0x%x open_status:%d chnl:%d co_started:%d",
- __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->hndl,
- p_scb->open_status, p_scb->chnl, p_scb->co_started);
-
- BTM_unblock_role_switch_and_sniff_mode_for(p_scb->PeerAddress());
- if (bta_av_cb.audio_open_cnt <= 1) {
- BTM_default_unblock_role_switch();
- }
-
- if (p_scb->open_status != BTA_AV_SUCCESS) {
- /* must be failure when opening the stream */
- data.open.bd_addr = p_scb->PeerAddress();
- data.open.status = p_scb->open_status;
- data.open.chnl = p_scb->chnl;
- data.open.hndl = p_scb->hndl;
-
- if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC)
- data.open.sep = AVDT_TSEP_SNK;
- else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK)
- data.open.sep = AVDT_TSEP_SRC;
-
- event = BTA_AV_OPEN_EVT;
- p_scb->open_status = BTA_AV_SUCCESS;
-
- bta_sys_conn_close(BTA_ID_AV, p_scb->app_id, p_scb->PeerAddress());
- bta_av_cleanup(p_scb, p_data);
- (*bta_av_cb.p_cback)(event, &data);
- } else {
- /* do stop if we were started */
- if (p_scb->co_started) {
- bta_av_str_stopped(p_scb, NULL);
- }
-
- {
- p_scb->p_cos->close(p_scb->hndl, p_scb->PeerAddress());
- data.close.chnl = p_scb->chnl;
- data.close.hndl = p_scb->hndl;
- event = BTA_AV_CLOSE_EVT;
-
- bta_sys_conn_close(BTA_ID_AV, p_scb->app_id, p_scb->PeerAddress());
- bta_av_cleanup(p_scb, p_data);
- (*bta_av_cb.p_cback)(event, &data);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_clr_cong
- *
- * Description Clear stream congestion flag.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_clr_cong(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- APPL_TRACE_DEBUG("%s", __func__);
- if (p_scb->co_started) {
- p_scb->cong = false;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_suspend_cfm
- *
- * Description process the suspend response
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_suspend_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- tBTA_AV_SUSPEND suspend_rsp;
- uint8_t err_code = p_data->str_msg.msg.hdr.err_code;
-
- APPL_TRACE_DEBUG("%s: peer %s bta_handle:0x%x audio_open_cnt:%d err_code:%d",
- __func__, p_scb->PeerAddress().ToString().c_str(),
- p_scb->hndl, bta_av_cb.audio_open_cnt, err_code);
-
- if (!p_scb->started) {
- /* handle the condition where there is a collision of SUSPEND req from
- *either side
- ** Second SUSPEND req could be rejected. Do not treat this as a failure
- */
- APPL_TRACE_WARNING("%s: already suspended, ignore, err_code %d", __func__,
- err_code);
- return;
- }
-
- suspend_rsp.status = BTA_AV_SUCCESS;
- if (err_code && (err_code != AVDT_ERR_BAD_STATE)) {
- suspend_rsp.status = BTA_AV_FAIL;
-
- APPL_TRACE_ERROR("%s: suspend failed, closing connection", __func__);
-
- /* SUSPEND failed. Close connection. */
- bta_av_ssm_execute(p_scb, BTA_AV_API_CLOSE_EVT, NULL);
- } else {
- /* only set started to false when suspend is successful */
- p_scb->started = false;
- }
-
- if (p_scb->role & BTA_AV_ROLE_SUSPEND) {
- p_scb->role &= ~BTA_AV_ROLE_SUSPEND;
- p_scb->cong = false;
- }
-
- bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->PeerAddress());
- BTM_unblock_role_switch_and_sniff_mode_for(p_scb->PeerAddress());
-
- /* in case that we received suspend_ind, we may need to call co_stop here */
- if (p_scb->co_started) {
- uint16_t handle = get_btm_client_interface().lifecycle.BTM_GetHCIConnHandle(
- p_scb->PeerAddress(), BT_TRANSPORT_BR_EDR);
- if (bta_av_cb.offload_started_acl_hdl == handle) {
- bta_av_vendor_offload_stop();
- bta_av_cb.offload_started_acl_hdl = HCI_INVALID_HANDLE;
- } else if (bta_av_cb.offload_start_pending_acl_hdl == handle) {
- APPL_TRACE_WARNING("%s: Stop pending offload start command", __func__);
- bta_av_vendor_offload_stop();
- bta_av_cb.offload_start_pending_acl_hdl = HCI_INVALID_HANDLE;
- }
- bta_av_stream_chg(p_scb, false);
-
- {
- p_scb->co_started = false;
- p_scb->p_cos->stop(p_scb->hndl, p_scb->PeerAddress());
- }
- }
-
- {
- suspend_rsp.chnl = p_scb->chnl;
- suspend_rsp.hndl = p_scb->hndl;
- suspend_rsp.initiator = p_data->str_msg.initiator;
- tBTA_AV bta_av_data;
- bta_av_data.suspend = suspend_rsp;
- (*bta_av_cb.p_cback)(BTA_AV_SUSPEND_EVT, &bta_av_data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rcfg_str_ok
- *
- * Description report reconfigure successful
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rcfg_str_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- p_scb->l2c_cid = AVDT_GetL2CapChannel(p_scb->avdt_handle);
- APPL_TRACE_DEBUG("%s: peer %s bta_handle:0x%x l2c_cid:%d", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->hndl,
- p_scb->l2c_cid);
-
- if (p_data != NULL) {
- // p_data could be NULL if the reconfig was triggered by the local device
- p_scb->stream_mtu =
- p_data->str_msg.msg.open_ind.peer_mtu - AVDT_MEDIA_HDR_SIZE;
- APPL_TRACE_DEBUG("%s: l2c_cid: 0x%x stream_mtu: %d", __func__,
- p_scb->l2c_cid, p_scb->stream_mtu);
- p_scb->p_cos->update_mtu(p_scb->hndl, p_scb->PeerAddress(),
- p_scb->stream_mtu);
- }
-
- /* rc listen */
- bta_av_st_rc_timer(p_scb, NULL);
-
- /* No need to keep the role bits once reconfig is done. */
- p_scb->role &= ~BTA_AV_ROLE_AD_ACP;
- p_scb->role &= ~BTA_AV_ROLE_SUSPEND_OPT;
- p_scb->role &= ~BTA_AV_ROLE_START_INT;
-
- {
- /* reconfigure success */
- tBTA_AV_RECONFIG reconfig;
- reconfig.status = BTA_AV_SUCCESS;
- reconfig.chnl = p_scb->chnl;
- reconfig.hndl = p_scb->hndl;
- tBTA_AV bta_av_data;
- bta_av_data.reconfig = reconfig;
- (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, &bta_av_data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rcfg_failed
- *
- * Description process reconfigure failed
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rcfg_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- APPL_TRACE_ERROR("%s: num_recfg=%d conn_lcb=0x%x peer_addr=%s", __func__,
- p_scb->num_recfg, bta_av_cb.conn_lcb,
- p_scb->PeerAddress().ToString().c_str());
-
- if (p_scb->num_recfg > BTA_AV_RECONFIG_RETRY) {
- bta_av_cco_close(p_scb, p_data);
- /* report failure */
- tBTA_AV_RECONFIG reconfig;
- reconfig.status = BTA_AV_FAIL_STREAM;
- reconfig.chnl = p_scb->chnl;
- reconfig.hndl = p_scb->hndl;
- tBTA_AV bta_av_data;
- bta_av_data.reconfig = reconfig;
- (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, &bta_av_data);
- /* go to closing state */
- bta_av_ssm_execute(p_scb, BTA_AV_API_CLOSE_EVT, NULL);
- } else {
- /* open failed. try again */
- p_scb->num_recfg++;
- // conn_lcb is the index bitmask of all used LCBs, and since LCB and SCB use
- // the same index, it should be safe to use SCB index here.
- if ((bta_av_cb.conn_lcb & (1 << p_scb->hdi)) != 0) {
- AVDT_DisconnectReq(p_scb->PeerAddress(), &bta_av_proc_stream_evt);
- } else {
- APPL_TRACE_WARNING("%s: conn_lcb=0x%x bta_handle=0x%x (hdi=%u) no link",
- __func__, bta_av_cb.conn_lcb, p_scb->hndl, p_scb->hdi);
- bta_av_connect_req(p_scb, NULL);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rcfg_connect
- *
- * Description stream closed. reconnect the stream
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rcfg_connect(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- APPL_TRACE_DEBUG("%s", __func__);
-
- p_scb->cong = false;
- p_scb->num_recfg++;
- APPL_TRACE_DEBUG("%s: num_recfg: %d", __func__, p_scb->num_recfg);
- if (p_scb->num_recfg > BTA_AV_RECONFIG_RETRY) {
- /* let bta_av_rcfg_failed report fail */
- bta_av_rcfg_failed(p_scb, NULL);
- } else {
- AVDT_ConnectReq(p_scb->PeerAddress(), p_scb->hdi, &bta_av_proc_stream_evt);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rcfg_discntd
- *
- * Description AVDT disconnected. reconnect the stream
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rcfg_discntd(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- APPL_TRACE_ERROR("%s: num_recfg=%d conn_lcb=0x%x peer_addr=%s", __func__,
- p_scb->num_recfg, bta_av_cb.conn_lcb,
- p_scb->PeerAddress().ToString().c_str());
-
- p_scb->num_recfg++;
- if (p_scb->num_recfg > BTA_AV_RECONFIG_RETRY) {
- /* report failure */
- tBTA_AV_RECONFIG reconfig;
- reconfig.status = BTA_AV_FAIL_STREAM;
- reconfig.chnl = p_scb->chnl;
- reconfig.hndl = p_scb->hndl;
- tBTA_AV bta_av_data;
- bta_av_data.reconfig = reconfig;
- (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, &bta_av_data);
- /* report close event & go to init state */
- bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, NULL);
- } else {
- AVDT_ConnectReq(p_scb->PeerAddress(), p_scb->hdi, &bta_av_proc_stream_evt);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_suspend_cont
- *
- * Description received the suspend response.
- * continue to reconfigure the stream
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_suspend_cont(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- uint8_t err_code = p_data->str_msg.msg.hdr.err_code;
-
- APPL_TRACE_DEBUG("%s: err_code=%d", __func__, err_code);
-
- p_scb->started = false;
- p_scb->cong = false;
- if (err_code) {
- if (AVDT_ERR_CONNECT == err_code) {
- /* report failure */
- tBTA_AV_RECONFIG reconfig;
- reconfig.status = BTA_AV_FAIL;
- tBTA_AV bta_av_data;
- bta_av_data.reconfig = reconfig;
- (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, &bta_av_data);
- APPL_TRACE_ERROR("%s: BTA_AV_STR_DISC_FAIL_EVT: peer_addr=%s", __func__,
- p_scb->PeerAddress().ToString().c_str());
- bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, NULL);
- } else {
- APPL_TRACE_ERROR("%s: suspend rejected, try close", __func__);
- /* drop the buffers queued in L2CAP */
- L2CA_FlushChannel(p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL);
-
- AVDT_CloseReq(p_scb->avdt_handle);
- }
- } else {
- APPL_TRACE_DEBUG("%s: calling AVDT_ReconfigReq", __func__);
- /* reconfig the stream */
-
- APPL_TRACE_DEBUG("%s: codec: %s", __func__,
- A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str());
- AVDT_ReconfigReq(p_scb->avdt_handle, &p_scb->cfg);
- p_scb->cfg.psc_mask = p_scb->cur_psc_mask;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rcfg_cfm
- *
- * Description if reconfigure is successful, report the event
- * otherwise, close the stream.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rcfg_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- uint8_t err_code = p_data->str_msg.msg.hdr.err_code;
-
- APPL_TRACE_DEBUG("%s: err_code = %d", __func__, err_code);
-
- // Disable AVDTP RECONFIGURE for rejectlisted devices
- bool disable_avdtp_reconfigure = false;
- {
- char remote_name[BTM_MAX_REM_BD_NAME_LEN] = "";
- if (btif_storage_get_stored_remote_name(p_scb->PeerAddress(),
- remote_name)) {
- if (interop_match_name(INTEROP_DISABLE_AVDTP_RECONFIGURE, remote_name) ||
- interop_match_addr(INTEROP_DISABLE_AVDTP_RECONFIGURE,
- (const RawAddress*)&p_scb->PeerAddress())) {
- LOG_INFO(
- "%s: disable AVDTP RECONFIGURE: interop matched "
- "name %s address %s",
- __func__, remote_name, p_scb->PeerAddress().ToString().c_str());
- disable_avdtp_reconfigure = true;
- }
- }
- }
-
- if ((err_code != 0) || disable_avdtp_reconfigure) {
- APPL_TRACE_ERROR("%s: reconfig rejected, try close", __func__);
- /* Disable reconfiguration feature only with explicit rejection(not with
- * timeout) */
- if ((err_code != AVDT_ERR_TIMEOUT) || disable_avdtp_reconfigure) {
- p_scb->recfg_sup = false;
- }
- /* started flag is false when reconfigure command is sent */
- /* drop the buffers queued in L2CAP */
- L2CA_FlushChannel(p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL);
- AVDT_CloseReq(p_scb->avdt_handle);
- } else {
- /* update the codec info after rcfg cfm */
- APPL_TRACE_DEBUG(
- "%s: updating from codec %s to codec %s", __func__,
- A2DP_CodecName(p_scb->cfg.codec_info),
- A2DP_CodecName(p_data->str_msg.msg.reconfig_cfm.p_cfg->codec_info));
- memcpy(p_scb->cfg.codec_info,
- p_data->str_msg.msg.reconfig_cfm.p_cfg->codec_info, AVDT_CODEC_SIZE);
- /* take the SSM back to OPEN state */
- bta_av_ssm_execute(p_scb, BTA_AV_STR_OPEN_OK_EVT, NULL);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rcfg_open
- *
- * Description AVDT is connected. open the stream with the new
- * configuration
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rcfg_open(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- APPL_TRACE_DEBUG("%s: peer %s bta_handle:0x%x num_disc_snks:%d", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->hndl,
- p_scb->num_disc_snks);
-
- if (p_scb->num_disc_snks == 0) {
- /* Need to update call-out module so that it will be ready for discover */
- p_scb->p_cos->stop(p_scb->hndl, p_scb->PeerAddress());
-
- /* send avdtp discover request */
- AVDT_DiscoverReq(p_scb->PeerAddress(), p_scb->hdi, p_scb->sep_info,
- BTA_AV_NUM_SEPS, &bta_av_proc_stream_evt);
- } else {
- APPL_TRACE_DEBUG("%s: calling AVDT_OpenReq()", __func__);
- APPL_TRACE_DEBUG("%s: codec: %s", __func__,
- A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str());
-
- /* we may choose to use a different SEP at reconfig.
- * adjust the sep_idx now */
- bta_av_adjust_seps_idx(p_scb, bta_av_get_scb_handle(p_scb, AVDT_TSEP_SRC));
- LOG_INFO("%s: sep_idx=%d avdt_handle=%d bta_handle=0x%x", __func__,
- p_scb->sep_idx, p_scb->avdt_handle, p_scb->hndl);
-
- /* open the stream with the new config */
- p_scb->sep_info_idx = p_scb->rcfg_idx;
- AVDT_OpenReq(p_scb->avdt_handle, p_scb->PeerAddress(), p_scb->hdi,
- p_scb->sep_info[p_scb->sep_info_idx].seid, &p_scb->cfg);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_security_rej
- *
- * Description Send an AVDTP security reject.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_security_rej(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- AVDT_SecurityRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_BAD_STATE,
- NULL, 0);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_chk_2nd_start
- *
- * Description check if this is 2nd stream and if it needs to be started.
- * This function needs to be kept very similar to
- * bta_av_chk_start
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_chk_2nd_start(tBTA_AV_SCB* p_scb,
- UNUSED_ATTR tBTA_AV_DATA* p_data) {
- LOG_INFO(
- "%s: peer %s channel:%d bta_av_cb.audio_open_cnt:%d role:0x%x "
- "features:0x%x",
- __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->chnl,
- bta_av_cb.audio_open_cnt, p_scb->role, bta_av_cb.features);
-
- if ((p_scb->chnl == BTA_AV_CHNL_AUDIO) && (bta_av_cb.audio_open_cnt >= 2) &&
- (((p_scb->role & BTA_AV_ROLE_AD_ACP) == 0) || // Outgoing connection or
- (bta_av_cb.features & BTA_AV_FEAT_ACP_START))) { // Auto-starting option
- // More than one audio channel is connected.
- if (!(p_scb->role & BTA_AV_ROLE_SUSPEND_OPT)) {
- // This channel does not need to be reconfigured.
- // If there is other channel streaming, start the stream now.
- bool new_started = false;
- for (int i = 0; i < BTA_AV_NUM_STRS; i++) {
- tBTA_AV_SCB* p_scbi = bta_av_cb.p_scb[i];
- if (p_scb == p_scbi) {
- continue;
- }
- if (p_scbi && p_scbi->chnl == BTA_AV_CHNL_AUDIO && p_scbi->co_started) {
- if (!new_started) {
- // Start the new stream
- new_started = true;
- LOG_INFO(
- "%s: starting new stream for peer %s because peer %s "
- "already started",
- __func__, p_scb->PeerAddress().ToString().c_str(),
- p_scbi->PeerAddress().ToString().c_str());
- bta_av_ssm_execute(p_scb, BTA_AV_AP_START_EVT, NULL);
- }
- // May need to update the flush timeout of this already started stream
- if (p_scbi->co_started != bta_av_cb.audio_open_cnt) {
- p_scbi->co_started = bta_av_cb.audio_open_cnt;
- }
- }
- }
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_open_rc
- *
- * Description Send a message to main SM to open RC channel.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_open_rc(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- APPL_TRACE_DEBUG("%s: use_rc: %d, wait: 0x%x role: 0x%x", __func__,
- p_scb->use_rc, p_scb->wait, p_scb->role);
- if ((p_scb->wait & BTA_AV_WAIT_ROLE_SW_BITS) &&
- (p_scb->q_tag == BTA_AV_Q_TAG_START)) {
- /* waiting for role switch for some reason & the timer expires */
- if (!bta_av_link_role_ok(p_scb, A2DP_SET_ONE_BIT)) {
- APPL_TRACE_ERROR(
- "%s: failed to start streaming for role management reasons!!",
- __func__);
- alarm_cancel(p_scb->avrc_ct_timer);
-
- tBTA_AV_START start;
- start.chnl = p_scb->chnl;
- start.status = BTA_AV_FAIL_ROLE;
- start.initiator = true;
- start.hndl = p_scb->hndl;
- p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
- bta_av_cb.rs_idx = 0;
- tBTA_AV bta_av_data;
- bta_av_data.start = start;
- (*bta_av_cb.p_cback)(BTA_AV_START_EVT, &bta_av_data);
- } else {
- /* role switch is done. continue to start streaming */
- bta_av_cb.rs_idx = 0;
- p_data->hdr.offset = BTA_AV_RS_OK;
- bta_av_start_ok(p_scb, p_data);
- }
- return;
- }
-
- if (p_scb->use_rc || (p_scb->role & BTA_AV_ROLE_AD_ACP)) {
- if (bta_av_cb.disc) {
- /* AVRC discover db is in use */
- if (p_scb->rc_handle == BTA_AV_RC_HANDLE_NONE) {
- /* AVRC channel is not connected. delay a little bit */
- if ((p_scb->wait & BTA_AV_WAIT_ROLE_SW_BITS) == 0) {
- bta_sys_start_timer(p_scb->avrc_ct_timer, BTA_AV_RC_DISC_TIME_VAL,
- BTA_AV_AVRC_TIMER_EVT, p_scb->hndl);
- } else {
- p_scb->wait |= BTA_AV_WAIT_CHECK_RC;
- }
- }
- } else {
- /* use main SM for AVRC SDP activities */
- if (is_new_avrcp_enabled()) {
- APPL_TRACE_WARNING("%s: Using the new AVRCP Profile", __func__);
- bluetooth::avrcp::AvrcpService::Get()->ConnectDevice(
- p_scb->PeerAddress());
- } else {
- bta_av_rc_disc((uint8_t)(p_scb->hdi + 1));
- }
- }
- } else {
- if (BTA_AV_RC_HANDLE_NONE != p_scb->rc_handle) {
- /* the open API said that this handle does not want a RC connection.
- * disconnect it now */
- AVRC_Close(p_scb->rc_handle);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_open_at_inc
- *
- * Description This function is called if API open is called by application
- * while state-machine is at incoming state.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_open_at_inc(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- memcpy(&(p_scb->open_api), &(p_data->api_open), sizeof(tBTA_AV_API_OPEN));
-
- APPL_TRACE_DEBUG("%s: peer %s coll_mask=0x%02x", __func__,
- p_scb->PeerAddress().ToString().c_str(), p_scb->coll_mask);
-
- if (p_scb->coll_mask & BTA_AV_COLL_INC_TMR) {
- p_scb->coll_mask |= BTA_AV_COLL_API_CALLED;
-
- /* API open will be handled at timeout if SNK did not start signalling. */
- /* API open will be ignored if SNK starts signalling. */
- } else {
- /* SNK did not start signalling, API was called N seconds timeout. */
- /* We need to switch to INIT state and start opening connection. */
- p_scb->coll_mask = 0;
- bta_av_set_scb_sst_init(p_scb);
-
- tBTA_AV_API_OPEN* p_buf =
- (tBTA_AV_API_OPEN*)osi_malloc(sizeof(tBTA_AV_API_OPEN));
- memcpy(p_buf, &(p_scb->open_api), sizeof(tBTA_AV_API_OPEN));
- bta_sys_sendmsg(p_buf);
- }
-}
-
-void offload_vendor_callback(tBTM_VSC_CMPL* param) {
- tBTA_AV value{0};
- uint8_t sub_opcode = 0;
- if (param->param_len) {
- APPL_TRACE_DEBUG("%s: param_len = %d status = %d", __func__,
- param->param_len, param->p_param_buf[0]);
- value.status = static_cast<tBTA_AV_STATUS>(param->p_param_buf[0]);
- }
- if (value.status == 0) {
- sub_opcode = param->p_param_buf[1];
- APPL_TRACE_DEBUG("%s: subopcode = %d", __func__, sub_opcode);
- switch (sub_opcode) {
- case VS_HCI_A2DP_OFFLOAD_STOP:
- APPL_TRACE_DEBUG("%s: VS_HCI_STOP_A2DP_MEDIA successful", __func__);
- break;
- case VS_HCI_A2DP_OFFLOAD_START:
- if (bta_av_cb.offload_start_pending_acl_hdl != HCI_INVALID_HANDLE) {
- bta_av_cb.offload_started_acl_hdl =
- bta_av_cb.offload_start_pending_acl_hdl;
- bta_av_cb.offload_start_pending_acl_hdl = HCI_INVALID_HANDLE;
- } else {
- LOG_INFO("%s: No pending start command due to AVDTP suspend immediately", __func__);
- }
- (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, &value);
- break;
- default:
- break;
- }
- } else {
- APPL_TRACE_DEBUG("%s: Offload failed for subopcode= %d", __func__,
- sub_opcode);
- if (param->opcode != VS_HCI_A2DP_OFFLOAD_STOP) {
- bta_av_cb.offload_start_pending_acl_hdl = HCI_INVALID_HANDLE;
- (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, &value);
- }
- }
-}
-
-void bta_av_vendor_offload_start(tBTA_AV_SCB* p_scb,
- tBT_A2DP_OFFLOAD* offload_start) {
- uint8_t param[sizeof(tBT_A2DP_OFFLOAD)];
- APPL_TRACE_DEBUG("%s", __func__);
-
- uint8_t* p_param = param;
- *p_param++ = VS_HCI_A2DP_OFFLOAD_START;
-
- UINT32_TO_STREAM(p_param, offload_start->codec_type);
- UINT16_TO_STREAM(p_param, offload_start->max_latency);
- ARRAY_TO_STREAM(p_param, offload_start->scms_t_enable,
- static_cast<int>(offload_start->scms_t_enable.size()));
- UINT32_TO_STREAM(p_param, offload_start->sample_rate);
- UINT8_TO_STREAM(p_param, offload_start->bits_per_sample);
- UINT8_TO_STREAM(p_param, offload_start->ch_mode);
- UINT32_TO_STREAM(p_param, offload_start->encoded_audio_bitrate);
- UINT16_TO_STREAM(p_param, offload_start->acl_hdl);
- UINT16_TO_STREAM(p_param, offload_start->l2c_rcid);
- UINT16_TO_STREAM(p_param, offload_start->mtu);
- ARRAY_TO_STREAM(p_param, offload_start->codec_info,
- (int8_t)sizeof(offload_start->codec_info));
- bta_av_cb.offload_start_pending_acl_hdl = offload_start->acl_hdl;
- LOG_INFO(
- "codec: %#x, sample rate: %#x, bit depth: %#x, channel: %#x, bitrate: "
- "%#x, ACL: %#x, L2CAP: %#x, MTU: %#x",
- offload_start->codec_type, offload_start->sample_rate,
- offload_start->bits_per_sample, offload_start->ch_mode,
- offload_start->encoded_audio_bitrate, offload_start->acl_hdl,
- offload_start->l2c_rcid, offload_start->mtu);
- BTM_VendorSpecificCommand(HCI_CONTROLLER_A2DP, p_param - param,
- param, offload_vendor_callback);
-}
-
-void bta_av_vendor_offload_stop() {
- uint8_t param[sizeof(tBT_A2DP_OFFLOAD)];
- APPL_TRACE_DEBUG("%s", __func__);
- param[0] = VS_HCI_A2DP_OFFLOAD_STOP;
- BTM_VendorSpecificCommand(HCI_CONTROLLER_A2DP, 1, param,
- offload_vendor_callback);
-}
-/*******************************************************************************
- *
- * Function bta_av_offload_req
- *
- * Description This function is called if application requests offload of
- * a2dp audio.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_offload_req(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- tBTA_AV_STATUS status = BTA_AV_FAIL_RESOURCES;
-
- tBT_A2DP_OFFLOAD offload_start;
- APPL_TRACE_DEBUG("%s: stream %s, audio channels open %d", __func__,
- p_scb->started ? "STARTED" : "STOPPED",
- bta_av_cb.audio_open_cnt);
- /* Check if stream has already been started. */
- /* Support offload if only one audio source stream is open. */
- if (p_scb->started != true) {
- status = BTA_AV_FAIL_STREAM;
- } else if (bta_av_cb.offload_start_pending_acl_hdl != HCI_INVALID_HANDLE ||
- bta_av_cb.offload_started_acl_hdl != HCI_INVALID_HANDLE) {
- APPL_TRACE_WARNING("%s: offload already started, ignore request", __func__);
- return;
- } else {
- bta_av_offload_codec_builder(p_scb, &offload_start);
- bta_av_vendor_offload_start(p_scb, &offload_start);
- return;
- }
- if (status != BTA_AV_SUCCESS) {
- tBTA_AV bta_av_data;
- bta_av_data.status = status;
- (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, &bta_av_data);
- }
- /* TODO(eisenbach): RE-IMPLEMENT USING VSC OR HAL EXTENSION
- else if (bta_av_cb.audio_open_cnt == 1 &&
- p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC &&
- p_scb->chnl == BTA_AV_CHNL_AUDIO) {
- bt_vendor_op_a2dp_offload_t a2dp_offload_start;
-
- if (L2CA_GetConnectionConfig(
- p_scb->l2c_cid, &a2dp_offload_start.acl_data_size,
- &a2dp_offload_start.remote_cid, &a2dp_offload_start.lm_handle)) {
- APPL_TRACE_DEBUG("%s: l2cmtu %d lcid 0x%02X rcid 0x%02X lm_handle
- 0x%02X",
- __func__, a2dp_offload_start.acl_data_size,
- p_scb->l2c_cid, a2dp_offload_start.remote_cid,
- a2dp_offload_start.lm_handle);
-
- a2dp_offload_start.bta_av_handle = p_scb->hndl;
- a2dp_offload_start.xmit_quota = BTA_AV_A2DP_OFFLOAD_XMIT_QUOTA;
- a2dp_offload_start.stream_mtu = p_scb->stream_mtu;
- a2dp_offload_start.local_cid = p_scb->l2c_cid;
- a2dp_offload_start.is_flushable = true;
- a2dp_offload_start.stream_source =
- ((uint32_t)(p_scb->cfg.codec_info[1] | p_scb->cfg.codec_info[2]));
-
- memcpy(a2dp_offload_start.codec_info, p_scb->cfg.codec_info,
- sizeof(a2dp_offload_start.codec_info));
-
- if (!vendor_get_interface()->send_command(
- (vendor_opcode_t)BT_VND_OP_A2DP_OFFLOAD_START,
- &a2dp_offload_start)) {
- status = BTA_AV_SUCCESS;
- p_scb->offload_start_pending = true;
- }
- }
- }
- */
-}
-
-/*******************************************************************************
- *
- * Function bta_av_offload_rsp
- *
- * Description This function is called when the vendor lib responds to
- * BT_VND_OP_A2DP_OFFLOAD_START.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_offload_rsp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
- tBTA_AV_STATUS status = p_data->api_status_rsp.status;
-
- APPL_TRACE_DEBUG("%s: stream %s status %s", __func__,
- p_scb->started ? "STARTED" : "STOPPED",
- status ? "FAIL" : "SUCCESS");
-
- /* Check if stream has already been started. */
- if (status == BTA_AV_SUCCESS && p_scb->started != true) {
- status = BTA_AV_FAIL_STREAM;
- }
-
- bta_av_cb.offload_start_pending_acl_hdl = HCI_INVALID_HANDLE;
- tBTA_AV bta_av_data;
- bta_av_data.status = status;
- (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, &bta_av_data);
-}
-
-static void bta_av_offload_codec_builder(tBTA_AV_SCB* p_scb,
- tBT_A2DP_OFFLOAD* p_a2dp_offload) {
- A2dpCodecConfig* CodecConfig = bta_av_get_a2dp_current_codec();
- btav_a2dp_codec_index_t codec_index =
- A2DP_SourceCodecIndex(p_scb->cfg.codec_info);
- uint32_t codec_type = 0;
- uint16_t mtu = p_scb->stream_mtu;
- APPL_TRACE_DEBUG("%s:codec_index = %d", __func__, codec_index);
- switch (codec_index) {
- case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
- codec_type = BTA_AV_CODEC_TYPE_SBC;
- if (A2DP_GetMaxBitpoolSbc(p_scb->cfg.codec_info) <=
- A2DP_SBC_BITPOOL_MIDDLE_QUALITY) {
- APPL_TRACE_WARNING("%s: Restricting streaming MTU size for MQ Bitpool",
- __func__);
- mtu = MAX_2MBPS_AVDTP_MTU;
- }
- break;
- case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
- codec_type = BTA_AV_CODEC_TYPE_AAC;
- break;
- case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
- codec_type = BTA_AV_CODEC_TYPE_APTX;
- break;
- case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
- codec_type = BTA_AV_CODEC_TYPE_APTXHD;
- break;
- case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
- codec_type = BTA_AV_CODEC_TYPE_LDAC;
- break;
- default:
- APPL_TRACE_ERROR("%s: Unknown Codec type ", __func__);
- return;
- }
- if (mtu > MAX_3MBPS_AVDTP_MTU) mtu = MAX_3MBPS_AVDTP_MTU;
- p_a2dp_offload->codec_type = codec_type;
- p_a2dp_offload->max_latency = 0;
- p_a2dp_offload->mtu = mtu;
- p_a2dp_offload->acl_hdl =
- get_btm_client_interface().lifecycle.BTM_GetHCIConnHandle(
- p_scb->PeerAddress(), BT_TRANSPORT_BR_EDR);
- btav_a2dp_scmst_info_t scmst_info =
- p_scb->p_cos->get_scmst_info(p_scb->PeerAddress());
- p_a2dp_offload->scms_t_enable[0] = scmst_info.enable_status;
- p_a2dp_offload->scms_t_enable[1] = scmst_info.cp_header;
- APPL_TRACE_DEBUG(
- "%s: SCMS-T_enable status: %d, "
- "SCMS-T header (if it's enabled): 0x%02x",
- __func__, scmst_info.enable_status, scmst_info.cp_header);
-
- switch (A2DP_GetTrackSampleRate(p_scb->cfg.codec_info)) {
- case 44100:
- p_a2dp_offload->sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
- break;
- case 48000:
- p_a2dp_offload->sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_48000;
- break;
- case 88200:
- p_a2dp_offload->sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_88200;
- break;
- case 96000:
- p_a2dp_offload->sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_96000;
- break;
- }
- if (L2CA_GetRemoteCid(p_scb->l2c_cid, &p_a2dp_offload->l2c_rcid) == false) {
- APPL_TRACE_ERROR("%s: Failed to fetch l2c rcid", __func__);
- return;
- }
- switch (CodecConfig->getAudioBitsPerSample()) {
- case 16:
- p_a2dp_offload->bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;
- break;
- case 24:
- p_a2dp_offload->bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24;
- break;
- case 32:
- p_a2dp_offload->bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32;
- break;
- }
- p_a2dp_offload->ch_mode = A2DP_GetTrackChannelCount(p_scb->cfg.codec_info);
- p_a2dp_offload->encoded_audio_bitrate = CodecConfig->getTrackBitRate();
- if (!CodecConfig->getCodecSpecificConfig(p_a2dp_offload)) {
- APPL_TRACE_ERROR("%s: not a valid codec info", __func__);
- }
-}
diff --git a/bta/av/bta_av_act.cc b/bta/av/bta_av_act.cc
deleted file mode 100644
index baf3f7c..0000000
--- a/bta/av/bta_av_act.cc
+++ /dev/null
@@ -1,2324 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2004-2016 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains action functions for advanced audio/video main state
- * machine.
- *
- ******************************************************************************/
-
-#define LOG_TAG "bt_bta_av"
-
-#include <cstdint>
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bta/av/bta_av_int.h"
-#include "bta/include/bta_ar_api.h"
-#include "bta/include/utl.h"
-#include "btif/avrcp/avrcp_service.h"
-#include "osi/include/allocator.h"
-#include "osi/include/log.h"
-#include "osi/include/osi.h" // UNUSED_ATTR
-#include "osi/include/properties.h"
-#include "stack/include/acl_api.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/l2c_api.h"
-#include "types/raw_address.h"
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-/* the timeout to wait for open req after setconfig for incoming connections */
-#ifndef BTA_AV_SIGNALLING_TIMEOUT_MS
-#define BTA_AV_SIGNALLING_TIMEOUT_MS (8 * 1000) /* 8 seconds */
-#endif
-
-/* Time to wait for signalling from SNK when it is initiated from SNK. */
-/* If not, we will start signalling from SRC. */
-#ifndef BTA_AV_ACCEPT_SIGNALLING_TIMEOUT_MS
-#define BTA_AV_ACCEPT_SIGNALLING_TIMEOUT_MS (2 * 1000) /* 2 seconds */
-#endif
-
-static void bta_av_accept_signalling_timer_cback(void* data);
-
-#ifndef AVRC_MIN_META_CMD_LEN
-#define AVRC_MIN_META_CMD_LEN 20
-#endif
-
-/*******************************************************************************
- *
- * Function bta_av_get_rcb_by_shdl
- *
- * Description find the RCB associated with the given SCB handle.
- *
- * Returns tBTA_AV_RCB
- *
- ******************************************************************************/
-tBTA_AV_RCB* bta_av_get_rcb_by_shdl(uint8_t shdl) {
- tBTA_AV_RCB* p_rcb = NULL;
- int i;
-
- for (i = 0; i < BTA_AV_NUM_RCB; i++) {
- if (bta_av_cb.rcb[i].shdl == shdl &&
- bta_av_cb.rcb[i].handle != BTA_AV_RC_HANDLE_NONE) {
- p_rcb = &bta_av_cb.rcb[i];
- break;
- }
- }
- return p_rcb;
-}
-#define BTA_AV_STS_NO_RSP 0xFF /* a number not used by tAVRC_STS */
-
-/*******************************************************************************
- *
- * Function bta_av_del_rc
- *
- * Description delete the given AVRC handle.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_del_rc(tBTA_AV_RCB* p_rcb) {
- tBTA_AV_SCB* p_scb;
- uint8_t rc_handle; /* connected AVRCP handle */
-
- p_scb = NULL;
- if (p_rcb->handle != BTA_AV_RC_HANDLE_NONE) {
- if (p_rcb->shdl) {
- /* Validate array index*/
- if ((p_rcb->shdl - 1) < BTA_AV_NUM_STRS) {
- p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1];
- }
- if (p_scb) {
- APPL_TRACE_DEBUG("%s: shdl:%d, srch:%d rc_handle:%d", __func__,
- p_rcb->shdl, p_scb->rc_handle, p_rcb->handle);
- if (p_scb->rc_handle == p_rcb->handle)
- p_scb->rc_handle = BTA_AV_RC_HANDLE_NONE;
- /* just in case the RC timer is active
- if (bta_av_cb.features & BTA_AV_FEAT_RCCT && p_scb->chnl ==
- BTA_AV_CHNL_AUDIO) */
- alarm_cancel(p_scb->avrc_ct_timer);
- }
- }
-
- APPL_TRACE_EVENT("%s: handle: %d status=0x%x, rc_acp_handle:%d, idx:%d",
- __func__, p_rcb->handle, p_rcb->status,
- bta_av_cb.rc_acp_handle, bta_av_cb.rc_acp_idx);
- rc_handle = p_rcb->handle;
- if (!(p_rcb->status & BTA_AV_RC_CONN_MASK) ||
- ((p_rcb->status & BTA_AV_RC_ROLE_MASK) == BTA_AV_RC_ROLE_INT)) {
- p_rcb->status = 0;
- p_rcb->handle = BTA_AV_RC_HANDLE_NONE;
- p_rcb->shdl = 0;
- p_rcb->lidx = 0;
- }
- /* else ACP && connected. do not clear the handle yet */
- AVRC_Close(rc_handle);
- if (rc_handle == bta_av_cb.rc_acp_handle)
- bta_av_cb.rc_acp_handle = BTA_AV_RC_HANDLE_NONE;
- APPL_TRACE_EVENT(
- "%s: end del_rc handle: %d status=0x%x, rc_acp_handle:%d, lidx:%d",
- __func__, p_rcb->handle, p_rcb->status, bta_av_cb.rc_acp_handle,
- p_rcb->lidx);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_close_all_rc
- *
- * Description close the all AVRC handle.
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_av_close_all_rc(tBTA_AV_CB* p_cb) {
- int i;
-
- for (i = 0; i < BTA_AV_NUM_RCB; i++) {
- if ((p_cb->disabling) || (bta_av_cb.rcb[i].shdl != 0))
- bta_av_del_rc(&bta_av_cb.rcb[i]);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_del_sdp_rec
- *
- * Description delete the given SDP record handle.
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_av_del_sdp_rec(uint32_t* p_sdp_handle) {
- if (*p_sdp_handle != 0) {
- SDP_DeleteRecord(*p_sdp_handle);
- *p_sdp_handle = 0;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_avrc_sdp_cback
- *
- * Description AVRCP service discovery callback.
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_av_avrc_sdp_cback(UNUSED_ATTR uint16_t status) {
- BT_HDR_RIGID* p_msg = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
-
- p_msg->event = BTA_AV_SDP_AVRC_DISC_EVT;
-
- bta_sys_sendmsg(p_msg);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_ctrl_cback
- *
- * Description AVRCP control callback.
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_av_rc_ctrl_cback(uint8_t handle, uint8_t event,
- UNUSED_ATTR uint16_t result,
- const RawAddress* peer_addr) {
- uint16_t msg_event = 0;
-
- APPL_TRACE_EVENT("%s: handle: %d event=0x%x", __func__, handle, event);
- if (event == AVRC_OPEN_IND_EVT) {
- /* save handle of opened connection
- bta_av_cb.rc_handle = handle;*/
-
- msg_event = BTA_AV_AVRC_OPEN_EVT;
- } else if (event == AVRC_CLOSE_IND_EVT) {
- msg_event = BTA_AV_AVRC_CLOSE_EVT;
- } else if (event == AVRC_BROWSE_OPEN_IND_EVT) {
- msg_event = BTA_AV_AVRC_BROWSE_OPEN_EVT;
- } else if (event == AVRC_BROWSE_CLOSE_IND_EVT) {
- msg_event = BTA_AV_AVRC_BROWSE_CLOSE_EVT;
- }
-
- if (msg_event) {
- tBTA_AV_RC_CONN_CHG* p_msg =
- (tBTA_AV_RC_CONN_CHG*)osi_malloc(sizeof(tBTA_AV_RC_CONN_CHG));
- p_msg->hdr.event = msg_event;
- p_msg->handle = handle;
- if (peer_addr) p_msg->peer_addr = *peer_addr;
- bta_sys_sendmsg(p_msg);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_msg_cback
- *
- * Description AVRCP message callback.
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_av_rc_msg_cback(uint8_t handle, uint8_t label, uint8_t opcode,
- tAVRC_MSG* p_msg) {
- uint8_t* p_data_src = NULL;
- uint16_t data_len = 0;
-
- APPL_TRACE_DEBUG("%s: handle: %u opcode=0x%x", __func__, handle, opcode);
-
- /* Copy avrc packet into BTA message buffer (for sending to BTA state machine)
- */
-
- /* Get size of payload data (for vendor and passthrough messages only; for
- * browsing
- * messages, use zero-copy) */
- if (opcode == AVRC_OP_VENDOR && p_msg->vendor.p_vendor_data != NULL) {
- p_data_src = p_msg->vendor.p_vendor_data;
- data_len = (uint16_t)p_msg->vendor.vendor_len;
- } else if (opcode == AVRC_OP_PASS_THRU && p_msg->pass.p_pass_data != NULL) {
- p_data_src = p_msg->pass.p_pass_data;
- data_len = (uint16_t)p_msg->pass.pass_len;
- }
-
- /* Create a copy of the message */
- tBTA_AV_RC_MSG* p_buf =
- (tBTA_AV_RC_MSG*)osi_malloc(sizeof(tBTA_AV_RC_MSG) + data_len);
-
- p_buf->hdr.event = BTA_AV_AVRC_MSG_EVT;
- p_buf->handle = handle;
- p_buf->label = label;
- p_buf->opcode = opcode;
- memcpy(&p_buf->msg, p_msg, sizeof(tAVRC_MSG));
- /* Copy the data payload, and set the pointer to it */
- if (p_data_src != NULL) {
- uint8_t* p_data_dst = (uint8_t*)(p_buf + 1);
- memcpy(p_data_dst, p_data_src, data_len);
-
- /* Update bta message buffer to point to payload data */
- /* (Note AVRC_OP_BROWSING uses zero-copy: p_buf->msg.browse.p_browse_data
- * already points to original avrc buffer) */
- if (opcode == AVRC_OP_VENDOR)
- p_buf->msg.vendor.p_vendor_data = p_data_dst;
- else if (opcode == AVRC_OP_PASS_THRU)
- p_buf->msg.pass.p_pass_data = p_data_dst;
- }
-
- if (opcode == AVRC_OP_BROWSE) {
- /* set p_pkt to NULL, so avrc would not free the buffer */
- p_msg->browse.p_browse_pkt = NULL;
- }
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_create
- *
- * Description alloc RCB and call AVRC_Open
- *
- * Returns the created rc handle
- *
- ******************************************************************************/
-uint8_t bta_av_rc_create(tBTA_AV_CB* p_cb, uint8_t role, uint8_t shdl,
- uint8_t lidx) {
- if (is_new_avrcp_enabled()) {
- LOG_INFO("Skipping RC creation for the old AVRCP profile");
- return BTA_AV_RC_HANDLE_NONE;
- }
-
- tAVRC_CONN_CB ccb;
- RawAddress bda = RawAddress::kAny;
- uint8_t status = BTA_AV_RC_ROLE_ACP;
- int i;
- uint8_t rc_handle;
- tBTA_AV_RCB* p_rcb;
-
- if (role == AVCT_INT) {
- // Can't grab a stream control block that doesn't have a valid handle
- if (!shdl) {
- APPL_TRACE_ERROR(
- "%s: Can't grab stream control block for shdl = %d -> index = %d",
- __func__, shdl, shdl - 1);
- return BTA_AV_RC_HANDLE_NONE;
- }
- tBTA_AV_SCB* p_scb = p_cb->p_scb[shdl - 1];
- bda = p_scb->PeerAddress();
- status = BTA_AV_RC_ROLE_INT;
- } else {
- p_rcb = bta_av_get_rcb_by_shdl(shdl);
- if (p_rcb != NULL) {
- APPL_TRACE_ERROR("%s: ACP handle exist for shdl:%d", __func__, shdl);
- p_rcb->lidx = lidx;
- return p_rcb->handle;
- }
- }
-
- ccb.ctrl_cback = base::Bind(bta_av_rc_ctrl_cback);
- ccb.msg_cback = base::Bind(bta_av_rc_msg_cback);
- ccb.company_id = p_bta_av_cfg->company_id;
- ccb.conn = role;
- /* note: BTA_AV_FEAT_RCTG = AVRC_CT_TARGET, BTA_AV_FEAT_RCCT = AVRC_CT_CONTROL
- */
- ccb.control = p_cb->features & (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_RCCT |
- BTA_AV_FEAT_METADATA | AVRC_CT_PASSIVE);
-
- if (AVRC_Open(&rc_handle, &ccb, bda) != AVRC_SUCCESS)
- return BTA_AV_RC_HANDLE_NONE;
-
- i = rc_handle;
- p_rcb = &p_cb->rcb[i];
-
- if (p_rcb->handle != BTA_AV_RC_HANDLE_NONE) {
- APPL_TRACE_ERROR("%s: found duplicated handle:%d", __func__, rc_handle);
- }
-
- p_rcb->handle = rc_handle;
- p_rcb->status = status;
- p_rcb->shdl = shdl;
- p_rcb->lidx = lidx;
- p_rcb->peer_features = 0;
- p_rcb->cover_art_psm = 0;
- if (lidx == (BTA_AV_NUM_LINKS + 1)) {
- /* this LIDX is reserved for the AVRCP ACP connection */
- p_cb->rc_acp_handle = p_rcb->handle;
- p_cb->rc_acp_idx = (i + 1);
- APPL_TRACE_DEBUG("%s: rc_acp_handle:%d idx:%d", __func__,
- p_cb->rc_acp_handle, p_cb->rc_acp_idx);
- }
- APPL_TRACE_DEBUG(
- "%s: create %d, role: %d, shdl:%d, rc_handle:%d, lidx:%d, status:0x%x",
- __func__, i, role, shdl, p_rcb->handle, lidx, p_rcb->status);
-
- return rc_handle;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_valid_group_navi_msg
- *
- * Description Check if it is Group Navigation Msg for Metadata
- *
- * Returns AVRC_RSP_ACCEPT or AVRC_RSP_NOT_IMPL
- *
- ******************************************************************************/
-static tBTA_AV_CODE bta_av_group_navi_supported(uint8_t len, uint8_t* p_data,
- bool is_inquiry) {
- tBTA_AV_CODE ret = AVRC_RSP_NOT_IMPL;
- uint8_t* p_ptr = p_data;
- uint16_t u16;
- uint32_t u32;
-
- if (p_bta_av_cfg->avrc_group && len == BTA_GROUP_NAVI_MSG_OP_DATA_LEN) {
- BTA_AV_BE_STREAM_TO_CO_ID(u32, p_ptr);
- BE_STREAM_TO_UINT16(u16, p_ptr);
-
- if (u32 == AVRC_CO_METADATA) {
- if (is_inquiry) {
- if (u16 <= AVRC_PDU_PREV_GROUP) ret = AVRC_RSP_IMPL_STBL;
- } else {
- if (u16 <= AVRC_PDU_PREV_GROUP)
- ret = AVRC_RSP_ACCEPT;
- else
- ret = AVRC_RSP_REJ;
- }
- }
- }
-
- return ret;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_op_supported
- *
- * Description Check if remote control operation is supported.
- *
- * Returns AVRC_RSP_ACCEPT of supported, AVRC_RSP_NOT_IMPL if not.
- *
- ******************************************************************************/
-static tBTA_AV_CODE bta_av_op_supported(tBTA_AV_RC rc_id, bool is_inquiry) {
- tBTA_AV_CODE ret_code = AVRC_RSP_NOT_IMPL;
-
- if (p_bta_av_rc_id) {
- if (is_inquiry) {
- if (p_bta_av_rc_id[rc_id >> 4] & (1 << (rc_id & 0x0F))) {
- ret_code = AVRC_RSP_IMPL_STBL;
- }
- } else {
- if (p_bta_av_rc_id[rc_id >> 4] & (1 << (rc_id & 0x0F))) {
- ret_code = AVRC_RSP_ACCEPT;
- } else if ((p_bta_av_cfg->rc_pass_rsp == AVRC_RSP_INTERIM) &&
- p_bta_av_rc_id_ac) {
- if (p_bta_av_rc_id_ac[rc_id >> 4] & (1 << (rc_id & 0x0F))) {
- ret_code = AVRC_RSP_INTERIM;
- }
- }
- }
- }
- return ret_code;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_find_lcb
- *
- * Description Given BD_addr, find the associated LCB.
- *
- * Returns NULL, if not found.
- *
- ******************************************************************************/
-tBTA_AV_LCB* bta_av_find_lcb(const RawAddress& addr, uint8_t op) {
- tBTA_AV_CB* p_cb = &bta_av_cb;
- int xx;
- uint8_t mask;
- tBTA_AV_LCB* p_lcb = NULL;
-
- APPL_TRACE_DEBUG("%s: address: %s op:%d", __func__, addr.ToString().c_str(),
- op);
- for (xx = 0; xx < BTA_AV_NUM_LINKS; xx++) {
- mask = 1 << xx; /* the used mask for this lcb */
- if ((mask & p_cb->conn_lcb) && p_cb->lcb[xx].addr == addr) {
- p_lcb = &p_cb->lcb[xx];
- if (op == BTA_AV_LCB_FREE) {
- p_cb->conn_lcb &= ~mask; /* clear the connect mask */
- APPL_TRACE_DEBUG("%s: conn_lcb: 0x%x", __func__, p_cb->conn_lcb);
- }
- break;
- }
- }
- return p_lcb;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_opened
- *
- * Description Set AVRCP state to opened.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rc_opened(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) {
- tBTA_AV_RC_OPEN rc_open;
- tBTA_AV_SCB* p_scb;
- int i;
- uint8_t shdl = 0;
- tBTA_AV_LCB* p_lcb;
- tBTA_AV_RCB* p_rcb;
- uint8_t tmp;
- uint8_t disc = 0;
-
- /* find the SCB & stop the timer */
- for (i = 0; i < BTA_AV_NUM_STRS; i++) {
- p_scb = p_cb->p_scb[i];
- if (p_scb && p_scb->PeerAddress() == p_data->rc_conn_chg.peer_addr) {
- p_scb->rc_handle = p_data->rc_conn_chg.handle;
- APPL_TRACE_DEBUG("%s: shdl:%d, srch %d", __func__, i + 1,
- p_scb->rc_handle);
- shdl = i + 1;
- LOG_INFO("%s: allow incoming AVRCP connections:%d", __func__,
- p_scb->use_rc);
- alarm_cancel(p_scb->avrc_ct_timer);
- disc = p_scb->hndl;
- break;
- }
- }
-
- i = p_data->rc_conn_chg.handle;
- if (p_cb->rcb[i].handle == BTA_AV_RC_HANDLE_NONE) {
- APPL_TRACE_ERROR("%s: not a valid handle:%d any more", __func__, i);
- return;
- }
-
- APPL_TRACE_DEBUG("%s: local features %d peer features %d", __func__,
- p_cb->features, p_cb->rcb[i].peer_features);
-
- /* listen to browsing channel when the connection is open,
- * if peer initiated AVRCP connection and local device supports browsing
- * channel */
- AVRC_OpenBrowse(p_data->rc_conn_chg.handle, AVCT_ACP);
-
- if (p_cb->rcb[i].lidx == (BTA_AV_NUM_LINKS + 1) && shdl != 0) {
- /* rc is opened on the RC only ACP channel, but is for a specific
- * SCB -> need to switch RCBs */
- p_rcb = bta_av_get_rcb_by_shdl(shdl);
- if (p_rcb) {
- p_rcb->shdl = p_cb->rcb[i].shdl;
- tmp = p_rcb->lidx;
- p_rcb->lidx = p_cb->rcb[i].lidx;
- p_cb->rcb[i].lidx = tmp;
- p_cb->rc_acp_handle = p_rcb->handle;
- p_cb->rc_acp_idx = (p_rcb - p_cb->rcb) + 1;
- APPL_TRACE_DEBUG("%s: switching RCB rc_acp_handle:%d idx:%d", __func__,
- p_cb->rc_acp_handle, p_cb->rc_acp_idx);
- }
- }
-
- p_cb->rcb[i].shdl = shdl;
- rc_open.rc_handle = i;
- APPL_TRACE_ERROR("%s: rcb[%d] shdl:%d lidx:%d/%d", __func__, i, shdl,
- p_cb->rcb[i].lidx, p_cb->lcb[BTA_AV_NUM_LINKS].lidx);
- p_cb->rcb[i].status |= BTA_AV_RC_CONN_MASK;
-
- if (!shdl && 0 == p_cb->lcb[BTA_AV_NUM_LINKS].lidx) {
- /* no associated SCB -> connected to an RC only device
- * update the index to the extra LCB */
- p_lcb = &p_cb->lcb[BTA_AV_NUM_LINKS];
- p_lcb->addr = p_data->rc_conn_chg.peer_addr;
- p_lcb->lidx = BTA_AV_NUM_LINKS + 1;
- p_cb->rcb[i].lidx = p_lcb->lidx;
- p_lcb->conn_msk = 1;
- APPL_TRACE_ERROR("%s: bd_addr: %s rcb[%d].lidx=%d, lcb.conn_msk=x%x",
- __func__, p_lcb->addr.ToString().c_str(), i,
- p_cb->rcb[i].lidx, p_lcb->conn_msk);
- disc = p_data->rc_conn_chg.handle | BTA_AV_CHNL_MSK;
- }
-
- rc_open.peer_addr = p_data->rc_conn_chg.peer_addr;
- rc_open.peer_features = p_cb->rcb[i].peer_features;
- rc_open.cover_art_psm = p_cb->rcb[i].cover_art_psm;
- rc_open.status = BTA_AV_SUCCESS;
- APPL_TRACE_DEBUG("%s: local features:x%x peer_features:x%x", __func__,
- p_cb->features, rc_open.peer_features);
- APPL_TRACE_DEBUG("%s: cover art psm:x%x", __func__, rc_open.cover_art_psm);
- if (rc_open.peer_features == 0) {
- /* we have not done SDP on peer RC capabilities.
- * peer must have initiated the RC connection */
- if (p_cb->features & BTA_AV_FEAT_RCCT)
- rc_open.peer_features |= BTA_AV_FEAT_RCTG;
- if (p_cb->features & BTA_AV_FEAT_RCTG)
- rc_open.peer_features |= BTA_AV_FEAT_RCCT;
-
- bta_av_rc_disc(disc);
- }
- tBTA_AV bta_av_data;
- bta_av_data.rc_open = rc_open;
- (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, &bta_av_data);
-
- /* if local initiated AVRCP connection and both peer and locals device support
- * browsing channel, open the browsing channel now
- * TODO (sanketa): Some TG would not broadcast browse feature hence check
- * inter-op. */
- if ((p_cb->features & BTA_AV_FEAT_BROWSE) &&
- (rc_open.peer_features & BTA_AV_FEAT_BROWSE) &&
- ((p_cb->rcb[i].status & BTA_AV_RC_ROLE_MASK) == BTA_AV_RC_ROLE_INT)) {
- APPL_TRACE_DEBUG("%s: opening AVRC Browse channel", __func__);
- AVRC_OpenBrowse(p_data->rc_conn_chg.handle, AVCT_INT);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_remote_cmd
- *
- * Description Send an AVRCP remote control command.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rc_remote_cmd(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) {
- tBTA_AV_RCB* p_rcb;
- if (p_cb->features & BTA_AV_FEAT_RCCT) {
- if (p_data->hdr.layer_specific < BTA_AV_NUM_RCB) {
- p_rcb = &p_cb->rcb[p_data->hdr.layer_specific];
- if (p_rcb->status & BTA_AV_RC_CONN_MASK) {
- AVRC_PassCmd(p_rcb->handle, p_data->api_remote_cmd.label,
- &p_data->api_remote_cmd.msg);
- }
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_vendor_cmd
- *
- * Description Send an AVRCP vendor specific command.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rc_vendor_cmd(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) {
- tBTA_AV_RCB* p_rcb;
- if ((p_cb->features & (BTA_AV_FEAT_RCCT | BTA_AV_FEAT_VENDOR)) ==
- (BTA_AV_FEAT_RCCT | BTA_AV_FEAT_VENDOR)) {
- if (p_data->hdr.layer_specific < BTA_AV_NUM_RCB) {
- p_rcb = &p_cb->rcb[p_data->hdr.layer_specific];
- AVRC_VendorCmd(p_rcb->handle, p_data->api_vendor.label,
- &p_data->api_vendor.msg);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_vendor_rsp
- *
- * Description Send an AVRCP vendor specific response.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rc_vendor_rsp(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) {
- tBTA_AV_RCB* p_rcb;
- if ((p_cb->features & (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_VENDOR)) ==
- (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_VENDOR)) {
- if (p_data->hdr.layer_specific < BTA_AV_NUM_RCB) {
- p_rcb = &p_cb->rcb[p_data->hdr.layer_specific];
- AVRC_VendorRsp(p_rcb->handle, p_data->api_vendor.label,
- &p_data->api_vendor.msg);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_meta_rsp
- *
- * Description Send an AVRCP metadata/advanced control command/response.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rc_meta_rsp(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) {
- tBTA_AV_RCB* p_rcb;
- bool do_free = true;
-
- if ((p_cb->features & BTA_AV_FEAT_METADATA) &&
- (p_data->hdr.layer_specific < BTA_AV_NUM_RCB)) {
- if ((p_data->api_meta_rsp.is_rsp && (p_cb->features & BTA_AV_FEAT_RCTG)) ||
- (!p_data->api_meta_rsp.is_rsp && (p_cb->features & BTA_AV_FEAT_RCCT))) {
- p_rcb = &p_cb->rcb[p_data->hdr.layer_specific];
- if (p_rcb->handle != BTA_AV_RC_HANDLE_NONE) {
- AVRC_MsgReq(p_rcb->handle, p_data->api_meta_rsp.label,
- p_data->api_meta_rsp.rsp_code, p_data->api_meta_rsp.p_pkt);
- do_free = false;
- }
- }
- }
-
- if (do_free) osi_free_and_reset((void**)&p_data->api_meta_rsp.p_pkt);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_free_rsp
- *
- * Description free an AVRCP metadata command buffer.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rc_free_rsp(UNUSED_ATTR tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) {
- osi_free_and_reset((void**)&p_data->api_meta_rsp.p_pkt);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_free_browse_msg
- *
- * Description free an AVRCP browse message buffer.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rc_free_browse_msg(UNUSED_ATTR tBTA_AV_CB* p_cb,
- tBTA_AV_DATA* p_data) {
- if (p_data->rc_msg.opcode == AVRC_OP_BROWSE) {
- osi_free_and_reset((void**)&p_data->rc_msg.msg.browse.p_browse_pkt);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_chk_notif_evt_id
- *
- * Description make sure the requested player id is valid.
- *
- * Returns BTA_AV_STS_NO_RSP, if no error
- *
- ******************************************************************************/
-static tAVRC_STS bta_av_chk_notif_evt_id(tAVRC_MSG_VENDOR* p_vendor) {
- tAVRC_STS status = BTA_AV_STS_NO_RSP;
- uint8_t xx;
- uint16_t u16;
- uint8_t* p = p_vendor->p_vendor_data + 2;
-
- BE_STREAM_TO_UINT16(u16, p);
- /* double check the fixed length */
- if ((u16 != 5) || (p_vendor->vendor_len != 9)) {
- status = AVRC_STS_INTERNAL_ERR;
- } else {
- /* make sure the player_id is valid */
- for (xx = 0; xx < p_bta_av_cfg->num_evt_ids; xx++) {
- if (*p == p_bta_av_cfg->p_meta_evt_ids[xx]) {
- break;
- }
- }
- if (xx == p_bta_av_cfg->num_evt_ids) {
- status = AVRC_STS_BAD_PARAM;
- }
- }
-
- return status;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_proc_meta_cmd
- *
- * Description Process an AVRCP metadata command from the peer.
- *
- * Returns true to respond immediately
- *
- ******************************************************************************/
-tBTA_AV_EVT bta_av_proc_meta_cmd(tAVRC_RESPONSE* p_rc_rsp,
- tBTA_AV_RC_MSG* p_msg, uint8_t* p_ctype) {
- tBTA_AV_EVT evt = BTA_AV_META_MSG_EVT;
- uint8_t u8, pdu, *p;
- uint16_t u16;
- tAVRC_MSG_VENDOR* p_vendor = &p_msg->msg.vendor;
-
- pdu = *(p_vendor->p_vendor_data);
- p_rc_rsp->pdu = pdu;
- *p_ctype = AVRC_RSP_REJ;
-
- /* Check to ansure a valid minimum meta data length */
- if ((AVRC_MIN_META_CMD_LEN + p_vendor->vendor_len) > AVRC_META_CMD_BUF_SIZE) {
- /* reject it */
- p_rc_rsp->rsp.status = AVRC_STS_BAD_PARAM;
- APPL_TRACE_ERROR("%s: Invalid meta-command length: %d", __func__,
- p_vendor->vendor_len);
- return 0;
- }
-
- /* Metadata messages only use PANEL sub-unit type */
- if (p_vendor->hdr.subunit_type != AVRC_SUB_PANEL) {
- APPL_TRACE_DEBUG("%s: SUBUNIT must be PANEL", __func__);
- /* reject it */
- evt = 0;
- p_vendor->hdr.ctype = AVRC_RSP_NOT_IMPL;
- p_vendor->vendor_len = 0;
- p_rc_rsp->rsp.status = AVRC_STS_BAD_PARAM;
- } else if (!AVRC_IsValidAvcType(pdu, p_vendor->hdr.ctype)) {
- APPL_TRACE_DEBUG("%s: Invalid pdu/ctype: 0x%x, %d", __func__, pdu,
- p_vendor->hdr.ctype);
- /* reject invalid message without reporting to app */
- evt = 0;
- p_rc_rsp->rsp.status = AVRC_STS_BAD_CMD;
- } else {
- switch (pdu) {
- case AVRC_PDU_GET_CAPABILITIES:
- /* process GetCapabilities command without reporting the event to app */
- evt = 0;
- if (p_vendor->vendor_len != 5) {
- android_errorWriteLog(0x534e4554, "111893951");
- p_rc_rsp->get_caps.status = AVRC_STS_INTERNAL_ERR;
- break;
- }
- u8 = *(p_vendor->p_vendor_data + 4);
- p = p_vendor->p_vendor_data + 2;
- p_rc_rsp->get_caps.capability_id = u8;
- BE_STREAM_TO_UINT16(u16, p);
- if (u16 != 1) {
- p_rc_rsp->get_caps.status = AVRC_STS_INTERNAL_ERR;
- } else {
- p_rc_rsp->get_caps.status = AVRC_STS_NO_ERROR;
- if (u8 == AVRC_CAP_COMPANY_ID) {
- *p_ctype = AVRC_RSP_IMPL_STBL;
- p_rc_rsp->get_caps.count = p_bta_av_cfg->num_co_ids;
- memcpy(p_rc_rsp->get_caps.param.company_id,
- p_bta_av_cfg->p_meta_co_ids,
- (p_bta_av_cfg->num_co_ids << 2));
- } else if (u8 == AVRC_CAP_EVENTS_SUPPORTED) {
- *p_ctype = AVRC_RSP_IMPL_STBL;
- p_rc_rsp->get_caps.count = p_bta_av_cfg->num_evt_ids;
- memcpy(p_rc_rsp->get_caps.param.event_id,
- p_bta_av_cfg->p_meta_evt_ids, p_bta_av_cfg->num_evt_ids);
- } else {
- APPL_TRACE_DEBUG("%s: Invalid capability ID: 0x%x", __func__, u8);
- /* reject - unknown capability ID */
- p_rc_rsp->get_caps.status = AVRC_STS_BAD_PARAM;
- }
- }
- break;
-
- case AVRC_PDU_REGISTER_NOTIFICATION:
- /* make sure the event_id is implemented */
- p_rc_rsp->rsp.status = bta_av_chk_notif_evt_id(p_vendor);
- if (p_rc_rsp->rsp.status != BTA_AV_STS_NO_RSP) evt = 0;
- break;
- }
- }
-
- return evt;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_msg
- *
- * Description Process an AVRCP message from the peer.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rc_msg(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) {
- tBTA_AV_EVT evt = 0;
- tBTA_AV av;
- BT_HDR* p_pkt = NULL;
- tAVRC_MSG_VENDOR* p_vendor = &p_data->rc_msg.msg.vendor;
- bool is_inquiry = ((p_data->rc_msg.msg.hdr.ctype == AVRC_CMD_SPEC_INQ) ||
- p_data->rc_msg.msg.hdr.ctype == AVRC_CMD_GEN_INQ);
- uint8_t ctype = 0;
- tAVRC_RESPONSE rc_rsp;
-
- rc_rsp.rsp.status = BTA_AV_STS_NO_RSP;
-
- if (NULL == p_data) {
- APPL_TRACE_ERROR("%s: Message from peer with no data", __func__);
- return;
- }
-
- APPL_TRACE_DEBUG("%s: opcode=%x, ctype=%x", __func__, p_data->rc_msg.opcode,
- p_data->rc_msg.msg.hdr.ctype);
-
- if (p_data->rc_msg.opcode == AVRC_OP_PASS_THRU) {
- /* if this is a pass thru command */
- if ((p_data->rc_msg.msg.hdr.ctype == AVRC_CMD_CTRL) ||
- (p_data->rc_msg.msg.hdr.ctype == AVRC_CMD_SPEC_INQ) ||
- (p_data->rc_msg.msg.hdr.ctype == AVRC_CMD_GEN_INQ)) {
- /* check if operation is supported */
- char avrcp_ct_support[PROPERTY_VALUE_MAX];
- osi_property_get("bluetooth.pts.avrcp_ct.support", avrcp_ct_support,
- "false");
- if (p_data->rc_msg.msg.pass.op_id == AVRC_ID_VENDOR) {
- p_data->rc_msg.msg.hdr.ctype = AVRC_RSP_NOT_IMPL;
- if (p_cb->features & BTA_AV_FEAT_METADATA)
- p_data->rc_msg.msg.hdr.ctype = bta_av_group_navi_supported(
- p_data->rc_msg.msg.pass.pass_len,
- p_data->rc_msg.msg.pass.p_pass_data, is_inquiry);
- } else if (((p_data->rc_msg.msg.pass.op_id == AVRC_ID_VOL_UP) ||
- (p_data->rc_msg.msg.pass.op_id == AVRC_ID_VOL_DOWN)) &&
- !strcmp(avrcp_ct_support, "true")) {
- p_data->rc_msg.msg.hdr.ctype = AVRC_RSP_ACCEPT;
- } else {
- p_data->rc_msg.msg.hdr.ctype =
- bta_av_op_supported(p_data->rc_msg.msg.pass.op_id, is_inquiry);
- }
-
- APPL_TRACE_DEBUG("%s: ctype %d", __func__, p_data->rc_msg.msg.hdr.ctype)
-
- /* send response */
- if (p_data->rc_msg.msg.hdr.ctype != AVRC_RSP_INTERIM)
- AVRC_PassRsp(p_data->rc_msg.handle, p_data->rc_msg.label,
- &p_data->rc_msg.msg.pass);
-
- /* set up for callback if supported */
- if (p_data->rc_msg.msg.hdr.ctype == AVRC_RSP_ACCEPT ||
- p_data->rc_msg.msg.hdr.ctype == AVRC_RSP_INTERIM) {
- evt = BTA_AV_REMOTE_CMD_EVT;
- av.remote_cmd.rc_id = p_data->rc_msg.msg.pass.op_id;
- av.remote_cmd.key_state = p_data->rc_msg.msg.pass.state;
- av.remote_cmd.p_data = p_data->rc_msg.msg.pass.p_pass_data;
- av.remote_cmd.len = p_data->rc_msg.msg.pass.pass_len;
- memcpy(&av.remote_cmd.hdr, &p_data->rc_msg.msg.hdr, sizeof(tAVRC_HDR));
- av.remote_cmd.label = p_data->rc_msg.label;
- }
- }
- /* else if this is a pass thru response */
- /* id response type is not impl, we have to release label */
- else if (p_data->rc_msg.msg.hdr.ctype >= AVRC_RSP_NOT_IMPL) {
- /* set up for callback */
- evt = BTA_AV_REMOTE_RSP_EVT;
- av.remote_rsp.rc_id = p_data->rc_msg.msg.pass.op_id;
- av.remote_rsp.key_state = p_data->rc_msg.msg.pass.state;
- av.remote_rsp.rsp_code = p_data->rc_msg.msg.hdr.ctype;
- av.remote_rsp.label = p_data->rc_msg.label;
-
- /* If this response is for vendor unique command */
- if ((p_data->rc_msg.msg.pass.op_id == AVRC_ID_VENDOR) &&
- (p_data->rc_msg.msg.pass.pass_len > 0)) {
- av.remote_rsp.p_data =
- (uint8_t*)osi_malloc(p_data->rc_msg.msg.pass.pass_len);
- APPL_TRACE_DEBUG("%s: Vendor Unique data len = %d", __func__,
- p_data->rc_msg.msg.pass.pass_len);
- memcpy(av.remote_rsp.p_data, p_data->rc_msg.msg.pass.p_pass_data,
- p_data->rc_msg.msg.pass.pass_len);
- }
- }
- /* must be a bad ctype -> reject*/
- else {
- p_data->rc_msg.msg.hdr.ctype = AVRC_RSP_REJ;
- AVRC_PassRsp(p_data->rc_msg.handle, p_data->rc_msg.label,
- &p_data->rc_msg.msg.pass);
- }
- }
- /* else if this is a vendor specific command or response */
- else if (p_data->rc_msg.opcode == AVRC_OP_VENDOR) {
- /* set up for callback */
- av.vendor_cmd.code = p_data->rc_msg.msg.hdr.ctype;
- av.vendor_cmd.company_id = p_vendor->company_id;
- av.vendor_cmd.label = p_data->rc_msg.label;
- av.vendor_cmd.p_data = p_vendor->p_vendor_data;
- av.vendor_cmd.len = p_vendor->vendor_len;
-
- /* if configured to support vendor specific and it's a command */
- if ((p_cb->features & BTA_AV_FEAT_VENDOR) &&
- p_data->rc_msg.msg.hdr.ctype <= AVRC_CMD_GEN_INQ) {
- if ((p_cb->features & BTA_AV_FEAT_METADATA) &&
- (p_vendor->company_id == AVRC_CO_METADATA)) {
- av.meta_msg.p_msg = &p_data->rc_msg.msg;
- rc_rsp.rsp.status = BTA_AV_STS_NO_RSP;
- evt = bta_av_proc_meta_cmd(&rc_rsp, &p_data->rc_msg, &ctype);
- } else {
- evt = BTA_AV_VENDOR_CMD_EVT;
- }
- } else if ((p_cb->features & BTA_AV_FEAT_VENDOR) &&
- p_data->rc_msg.msg.hdr.ctype >= AVRC_RSP_NOT_IMPL) {
- /* else if configured to support vendor specific and it's a response */
- if ((p_cb->features & BTA_AV_FEAT_METADATA) &&
- (p_vendor->company_id == AVRC_CO_METADATA)) {
- av.meta_msg.p_msg = &p_data->rc_msg.msg;
- evt = BTA_AV_META_MSG_EVT;
- } else {
- evt = BTA_AV_VENDOR_RSP_EVT;
- }
- } else if (!(p_cb->features & BTA_AV_FEAT_VENDOR) &&
- p_data->rc_msg.msg.hdr.ctype <= AVRC_CMD_GEN_INQ) {
- /* else if not configured to support vendor specific and it's a command */
- if (p_data->rc_msg.msg.vendor.p_vendor_data[0] == AVRC_PDU_INVALID) {
- /* reject it */
- p_data->rc_msg.msg.hdr.ctype = AVRC_RSP_REJ;
- p_data->rc_msg.msg.vendor.p_vendor_data[4] = AVRC_STS_BAD_CMD;
- } else {
- p_data->rc_msg.msg.hdr.ctype = AVRC_RSP_NOT_IMPL;
- }
- AVRC_VendorRsp(p_data->rc_msg.handle, p_data->rc_msg.label,
- &p_data->rc_msg.msg.vendor);
- }
- } else if (p_data->rc_msg.opcode == AVRC_OP_BROWSE) {
- /* set up for callback */
- av.meta_msg.rc_handle = p_data->rc_msg.handle;
- av.meta_msg.company_id = p_vendor->company_id;
- av.meta_msg.code = p_data->rc_msg.msg.hdr.ctype;
- av.meta_msg.label = p_data->rc_msg.label;
- av.meta_msg.p_msg = &p_data->rc_msg.msg;
- av.meta_msg.p_data = p_data->rc_msg.msg.browse.p_browse_data;
- av.meta_msg.len = p_data->rc_msg.msg.browse.browse_len;
- evt = BTA_AV_META_MSG_EVT;
- }
-
- if (evt == 0 && rc_rsp.rsp.status != BTA_AV_STS_NO_RSP) {
- if (!p_pkt) {
- rc_rsp.rsp.opcode = p_data->rc_msg.opcode;
- AVRC_BldResponse(0, &rc_rsp, &p_pkt);
- }
- if (p_pkt)
- AVRC_MsgReq(p_data->rc_msg.handle, p_data->rc_msg.label, ctype, p_pkt);
- }
-
- /* call callback */
- if (evt != 0) {
- av.remote_cmd.rc_handle = p_data->rc_msg.handle;
- (*p_cb->p_cback)(evt, &av);
- /* If browsing message, then free the browse message buffer */
- bta_av_rc_free_browse_msg(p_cb, p_data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_close
- *
- * Description close the specified AVRC handle.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rc_close(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) {
- uint16_t handle = p_data->hdr.layer_specific;
- tBTA_AV_SCB* p_scb;
- tBTA_AV_RCB* p_rcb;
-
- if (handle < BTA_AV_NUM_RCB) {
- p_rcb = &p_cb->rcb[handle];
-
- APPL_TRACE_DEBUG("%s: handle: %d, status=0x%x", __func__, p_rcb->handle,
- p_rcb->status);
- if (p_rcb->handle != BTA_AV_RC_HANDLE_NONE) {
- if (p_rcb->shdl) {
- p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1];
- if (p_scb) {
- /* just in case the RC timer is active
- if (bta_av_cb.features & BTA_AV_FEAT_RCCT &&
- p_scb->chnl == BTA_AV_CHNL_AUDIO) */
- alarm_cancel(p_scb->avrc_ct_timer);
- }
- }
-
- AVRC_Close(p_rcb->handle);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_browse_close
- *
- * Description Empty placeholder.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rc_browse_close(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) {
- APPL_TRACE_WARNING("%s: empty placeholder does nothing!", __func__);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_get_shdl
- *
- * Returns The index to p_scb[]
- *
- ******************************************************************************/
-static uint8_t bta_av_get_shdl(tBTA_AV_SCB* p_scb) {
- int i;
- uint8_t shdl = 0;
- /* find the SCB & stop the timer */
- for (i = 0; i < BTA_AV_NUM_STRS; i++) {
- if (p_scb == bta_av_cb.p_scb[i]) {
- shdl = i + 1;
- break;
- }
- }
- return shdl;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_stream_chg
- *
- * Description audio streaming status changed.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_stream_chg(tBTA_AV_SCB* p_scb, bool started) {
- uint8_t started_msk = BTA_AV_HNDL_TO_MSK(p_scb->hdi);
-
- APPL_TRACE_DEBUG("%s: peer %s started:%s started_msk:0x%x", __func__,
- p_scb->PeerAddress().ToString().c_str(),
- logbool(started).c_str(), started_msk);
-
- if (started) {
- /* Let L2CAP know this channel is processed with high priority */
- L2CA_SetAclPriority(p_scb->PeerAddress(), L2CAP_PRIORITY_HIGH);
- } else {
- /* Let L2CAP know this channel is processed with low priority */
- L2CA_SetAclPriority(p_scb->PeerAddress(), L2CAP_PRIORITY_NORMAL);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_conn_chg
- *
- * Description connetion status changed.
- * Open an AVRCP acceptor channel, if new conn.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_conn_chg(tBTA_AV_DATA* p_data) {
- tBTA_AV_CB* p_cb = &bta_av_cb;
- tBTA_AV_SCB* p_scb = NULL;
- tBTA_AV_SCB* p_scbi;
- uint8_t mask;
- uint8_t conn_msk;
- uint8_t old_msk;
- int i;
- int index = (p_data->hdr.layer_specific & BTA_AV_HNDL_MSK) - 1;
- tBTA_AV_LCB* p_lcb;
- tBTA_AV_LCB* p_lcb_rc;
- tBTA_AV_RCB *p_rcb, *p_rcb2;
- bool chk_restore = false;
-
- /* Validate array index*/
- if (index < BTA_AV_NUM_STRS) {
- p_scb = p_cb->p_scb[index];
- }
- mask = BTA_AV_HNDL_TO_MSK(index);
- p_lcb = bta_av_find_lcb(p_data->conn_chg.peer_addr, BTA_AV_LCB_FIND);
- conn_msk = 1 << (index + 1);
- if (p_data->conn_chg.is_up) {
- /* set the conned mask for this channel */
- if (p_scb) {
- if (p_lcb) {
- p_lcb->conn_msk |= conn_msk;
- for (i = 0; i < BTA_AV_NUM_RCB; i++) {
- if (bta_av_cb.rcb[i].lidx == p_lcb->lidx) {
- bta_av_cb.rcb[i].shdl = index + 1;
- APPL_TRACE_DEBUG(
- "%s: conn_chg up[%d]: %d, status=0x%x, shdl:%d, lidx:%d",
- __func__, i, bta_av_cb.rcb[i].handle, bta_av_cb.rcb[i].status,
- bta_av_cb.rcb[i].shdl, bta_av_cb.rcb[i].lidx);
- break;
- }
- }
- }
- old_msk = p_cb->conn_audio;
- p_cb->conn_audio |= mask;
-
- if ((old_msk & mask) == 0) {
- /* increase the audio open count, if not set yet */
- bta_av_cb.audio_open_cnt++;
- }
-
- APPL_TRACE_DEBUG("%s: rc_acp_handle:%d rc_acp_idx:%d", __func__,
- p_cb->rc_acp_handle, p_cb->rc_acp_idx);
- /* check if the AVRCP ACP channel is already connected */
- if (p_lcb && p_cb->rc_acp_handle != BTA_AV_RC_HANDLE_NONE &&
- p_cb->rc_acp_idx) {
- p_lcb_rc = &p_cb->lcb[BTA_AV_NUM_LINKS];
- APPL_TRACE_DEBUG(
- "%s: rc_acp is connected && conn_chg on same addr "
- "p_lcb_rc->conn_msk:x%x",
- __func__, p_lcb_rc->conn_msk);
- /* check if the RC is connected to the scb addr */
- LOG_INFO("%s: p_lcb_rc->addr: %s conn_chg.peer_addr: %s", __func__,
- p_lcb_rc->addr.ToString().c_str(),
- p_data->conn_chg.peer_addr.ToString().c_str());
-
- if (p_lcb_rc->conn_msk &&
- p_lcb_rc->addr == p_data->conn_chg.peer_addr) {
- /* AVRCP is already connected.
- * need to update the association betwen SCB and RCB */
- p_lcb_rc->conn_msk = 0; /* indicate RC ONLY is not connected */
- p_lcb_rc->lidx = 0;
- p_scb->rc_handle = p_cb->rc_acp_handle;
- p_rcb = &p_cb->rcb[p_cb->rc_acp_idx - 1];
- p_rcb->shdl = bta_av_get_shdl(p_scb);
- APPL_TRACE_DEBUG("%s: update rc_acp shdl:%d/%d srch:%d", __func__,
- index + 1, p_rcb->shdl, p_scb->rc_handle);
-
- p_rcb2 = bta_av_get_rcb_by_shdl(p_rcb->shdl);
- if (p_rcb2) {
- /* found the RCB that was created to associated with this SCB */
- p_cb->rc_acp_handle = p_rcb2->handle;
- p_cb->rc_acp_idx = (p_rcb2 - p_cb->rcb) + 1;
- APPL_TRACE_DEBUG("%s: new rc_acp_handle:%d, idx:%d", __func__,
- p_cb->rc_acp_handle, p_cb->rc_acp_idx);
- p_rcb2->lidx = (BTA_AV_NUM_LINKS + 1);
- APPL_TRACE_DEBUG("%s: rc2 handle:%d lidx:%d/%d", __func__,
- p_rcb2->handle, p_rcb2->lidx,
- p_cb->lcb[p_rcb2->lidx - 1].lidx);
- }
- p_rcb->lidx = p_lcb->lidx;
- APPL_TRACE_DEBUG("%s: rc handle:%d lidx:%d/%d", __func__,
- p_rcb->handle, p_rcb->lidx,
- p_cb->lcb[p_rcb->lidx - 1].lidx);
- }
- }
- }
- } else {
- if ((p_cb->conn_audio & mask) && bta_av_cb.audio_open_cnt) {
- /* this channel is still marked as open. decrease the count */
- bta_av_cb.audio_open_cnt--;
- }
-
- /* clear the conned mask for this channel */
- p_cb->conn_audio &= ~mask;
- if (p_scb) {
- // The stream is closed. Clear the state.
- p_scb->OnDisconnected();
- if (p_scb->chnl == BTA_AV_CHNL_AUDIO) {
- if (p_lcb) {
- p_lcb->conn_msk &= ~conn_msk;
- }
- /* audio channel is down. make sure the INT channel is down */
- /* just in case the RC timer is active
- if (p_cb->features & BTA_AV_FEAT_RCCT) */
- { alarm_cancel(p_scb->avrc_ct_timer); }
- /* one audio channel goes down. check if we need to restore high
- * priority */
- chk_restore = true;
- }
- }
-
- APPL_TRACE_DEBUG("%s: shdl:%d", __func__, index + 1);
- for (i = 0; i < BTA_AV_NUM_RCB; i++) {
- APPL_TRACE_DEBUG("%s: conn_chg dn[%d]: %d, status=0x%x, shdl:%d, lidx:%d",
- __func__, i, bta_av_cb.rcb[i].handle,
- bta_av_cb.rcb[i].status, bta_av_cb.rcb[i].shdl,
- bta_av_cb.rcb[i].lidx);
- if (bta_av_cb.rcb[i].shdl == index + 1) {
- bta_av_del_rc(&bta_av_cb.rcb[i]);
- /* since the connection is already down and info was removed, clean
- * reference */
- bta_av_cb.rcb[i].shdl = 0;
- break;
- }
- }
-
- if (p_cb->conn_audio == 0) {
- /* if both channels are not connected,
- * close all RC channels */
- bta_av_close_all_rc(p_cb);
- }
-
- /* if the AVRCP is no longer listening, create the listening channel */
- if (bta_av_cb.rc_acp_handle == BTA_AV_RC_HANDLE_NONE &&
- bta_av_cb.features & BTA_AV_FEAT_RCTG)
- bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1);
- }
-
- APPL_TRACE_DEBUG(
- "%s: audio:%x up:%d conn_msk:0x%x chk_restore:%d "
- "audio_open_cnt:%d",
- __func__, p_cb->conn_audio, p_data->conn_chg.is_up, conn_msk, chk_restore,
- p_cb->audio_open_cnt);
-
- if (chk_restore) {
- if (p_cb->audio_open_cnt == 1) {
- /* one audio channel goes down and there's one audio channel remains open.
- * restore the switch role in default link policy */
- BTM_default_unblock_role_switch();
- bta_av_restore_switch();
- }
- if (p_cb->audio_open_cnt) {
- /* adjust flush timeout settings to longer period */
- for (i = 0; i < BTA_AV_NUM_STRS; i++) {
- p_scbi = bta_av_cb.p_scb[i];
- if (p_scbi && p_scbi->chnl == BTA_AV_CHNL_AUDIO && p_scbi->co_started) {
- /* may need to update the flush timeout of this already started stream
- */
- if (p_scbi->co_started != bta_av_cb.audio_open_cnt) {
- p_scbi->co_started = bta_av_cb.audio_open_cnt;
- }
- }
- }
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_disable
- *
- * Description disable AV.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_disable(tBTA_AV_CB* p_cb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
- BT_HDR_RIGID hdr;
- bool disabling_in_progress = false;
- uint16_t xx;
-
- p_cb->disabling = true;
-
- bta_av_close_all_rc(p_cb);
-
- osi_free_and_reset((void**)&p_cb->p_disc_db);
-
- /* disable audio/video - de-register all channels,
- * expect BTA_AV_DEREG_COMP_EVT when deregister is complete */
- for (xx = 0; xx < BTA_AV_NUM_STRS; xx++) {
- if (p_cb->p_scb[xx] != NULL) {
- // Free signalling timers
- alarm_free(p_cb->p_scb[xx]->link_signalling_timer);
- p_cb->p_scb[xx]->link_signalling_timer = NULL;
- alarm_free(p_cb->p_scb[xx]->accept_signalling_timer);
- p_cb->p_scb[xx]->accept_signalling_timer = NULL;
-
- hdr.layer_specific = xx + 1;
- bta_av_api_deregister((tBTA_AV_DATA*)&hdr);
- disabling_in_progress = true;
- }
- }
- // Since All channels are deregistering by API_DEREGISTER, the DEREG_COMP_EVT
- // would come first before API_DISABLE if there is no connections, and it is
- // no needed to setup this disabling flag.
- p_cb->disabling = disabling_in_progress;
-
-}
-
-/*******************************************************************************
- *
- * Function bta_av_api_disconnect
- *
- * Description .
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_api_disconnect(tBTA_AV_DATA* p_data) {
- tBTA_AV_SCB* p_scb =
- bta_av_hndl_to_scb(p_data->api_discnt.hdr.layer_specific);
- AVDT_DisconnectReq(p_scb->PeerAddress(), bta_av_conn_cback);
- alarm_cancel(p_scb->link_signalling_timer);
-}
-
-/**
- * Find the index for the free LCB entry to use.
- *
- * The selection order is:
- * (1) Find the index if there is already SCB entry for the peer address
- * (2) If there is no SCB entry for the peer address, find the first
- * SCB entry that is not assigned.
- *
- * @param peer_address the peer address to use
- * @return the index for the free LCB entry to use or BTA_AV_NUM_LINKS
- * if no entry is found
- */
-static uint8_t bta_av_find_lcb_index_by_scb_and_address(
- const RawAddress& peer_address) {
- APPL_TRACE_DEBUG("%s: peer_address: %s conn_lcb: 0x%x", __func__,
- peer_address.ToString().c_str(), bta_av_cb.conn_lcb);
-
- // Find the index if there is already SCB entry for the peer address
- for (uint8_t index = 0; index < BTA_AV_NUM_LINKS; index++) {
- uint8_t mask = 1 << index;
- if (mask & bta_av_cb.conn_lcb) {
- continue;
- }
- tBTA_AV_SCB* p_scb = bta_av_cb.p_scb[index];
- if (p_scb == nullptr) {
- continue;
- }
- if (p_scb->PeerAddress() == peer_address) {
- return index;
- }
- }
-
- // Find the first SCB entry that is not assigned.
- for (uint8_t index = 0; index < BTA_AV_NUM_LINKS; index++) {
- uint8_t mask = 1 << index;
- if (mask & bta_av_cb.conn_lcb) {
- continue;
- }
- tBTA_AV_SCB* p_scb = bta_av_cb.p_scb[index];
- if (p_scb == nullptr) {
- continue;
- }
- if (!p_scb->IsAssigned()) {
- return index;
- }
- }
-
- return BTA_AV_NUM_LINKS;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_sig_chg
- *
- * Description process AVDT signal channel up/down.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_sig_chg(tBTA_AV_DATA* p_data) {
- uint16_t event = p_data->str_msg.hdr.layer_specific;
- tBTA_AV_CB* p_cb = &bta_av_cb;
- uint32_t xx;
- uint8_t mask;
- tBTA_AV_LCB* p_lcb = NULL;
-
- APPL_TRACE_DEBUG("%s: event: %d", __func__, event);
- if (event == AVDT_CONNECT_IND_EVT) {
- APPL_TRACE_DEBUG("%s: AVDT_CONNECT_IND_EVT: peer %s", __func__,
- p_data->str_msg.bd_addr.ToString().c_str());
-
- p_lcb = bta_av_find_lcb(p_data->str_msg.bd_addr, BTA_AV_LCB_FIND);
- if (!p_lcb) {
- /* if the address does not have an LCB yet, alloc one */
- xx = bta_av_find_lcb_index_by_scb_and_address(p_data->str_msg.bd_addr);
-
- /* check if we found something */
- if (xx >= BTA_AV_NUM_LINKS) {
- /* We do not have scb for this avdt connection. */
- /* Silently close the connection. */
- APPL_TRACE_ERROR("%s: av scb not available for avdt connection for %s",
- __func__, p_data->str_msg.bd_addr.ToString().c_str());
- AVDT_DisconnectReq(p_data->str_msg.bd_addr, NULL);
- return;
- }
- LOG_INFO("%s: AVDT_CONNECT_IND_EVT: peer %s selected lcb_index %d",
- __func__, p_data->str_msg.bd_addr.ToString().c_str(), xx);
-
- tBTA_AV_SCB* p_scb = p_cb->p_scb[xx];
- mask = 1 << xx;
- p_lcb = &p_cb->lcb[xx];
- p_lcb->lidx = xx + 1;
- p_lcb->addr = p_data->str_msg.bd_addr;
- p_lcb->conn_msk = 0; /* clear the connect mask */
- /* start listening when the signal channel is open */
- if (p_cb->features & BTA_AV_FEAT_RCTG) {
- bta_av_rc_create(p_cb, AVCT_ACP, 0, p_lcb->lidx);
- }
- /* this entry is not used yet. */
- p_cb->conn_lcb |= mask; /* mark it as used */
- APPL_TRACE_DEBUG("%s: start sig timer %d", __func__, p_data->hdr.offset);
- if (p_data->hdr.offset == AVDT_ACP) {
- APPL_TRACE_DEBUG("%s: Incoming L2CAP acquired, set state as incoming",
- __func__);
- p_scb->OnConnected(p_data->str_msg.bd_addr);
- p_scb->use_rc = true; /* allowing RC for incoming connection */
- bta_av_ssm_execute(p_scb, BTA_AV_ACP_CONNECT_EVT, p_data);
-
- /* The Pending Event should be sent as soon as the L2CAP signalling
- * channel
- * is set up, which is NOW. Earlier this was done only after
- * BTA_AV_SIGNALLING_TIMEOUT_MS.
- * The following function shall send the event and start the
- * recurring timer
- */
- if (!p_scb->link_signalling_timer) {
- p_scb->link_signalling_timer = alarm_new("link_signalling_timer");
- }
- BT_HDR hdr;
- hdr.layer_specific = p_scb->hndl;
- bta_av_signalling_timer((tBTA_AV_DATA*)&hdr);
-
- APPL_TRACE_DEBUG("%s: Re-start timer for AVDTP service", __func__);
- bta_sys_conn_open(BTA_ID_AV, p_scb->app_id, p_scb->PeerAddress());
- /* Possible collision : need to avoid outgoing processing while the
- * timer is running */
- p_scb->coll_mask = BTA_AV_COLL_INC_TMR;
- if (!p_scb->accept_signalling_timer) {
- p_scb->accept_signalling_timer = alarm_new("accept_signalling_timer");
- }
- alarm_set_on_mloop(
- p_scb->accept_signalling_timer, BTA_AV_ACCEPT_SIGNALLING_TIMEOUT_MS,
- bta_av_accept_signalling_timer_cback, UINT_TO_PTR(xx));
- }
- }
- }
- else if (event == BTA_AR_AVDT_CONN_EVT) {
- uint8_t scb_index = p_data->str_msg.scb_index;
- alarm_cancel(p_cb->p_scb[scb_index]->link_signalling_timer);
- }
- else {
- /* disconnected. */
- APPL_TRACE_DEBUG("%s: bta_av_cb.conn_lcb=0x%x", __func__,
- bta_av_cb.conn_lcb);
-
- p_lcb = bta_av_find_lcb(p_data->str_msg.bd_addr, BTA_AV_LCB_FREE);
- if (p_lcb && (p_lcb->conn_msk || bta_av_cb.conn_lcb)) {
- APPL_TRACE_DEBUG("%s: conn_msk: 0x%x", __func__, p_lcb->conn_msk);
- /* clean up ssm */
- for (xx = 0; xx < BTA_AV_NUM_STRS; xx++) {
- if (p_cb->p_scb[xx] &&
- p_cb->p_scb[xx]->PeerAddress() == p_data->str_msg.bd_addr) {
- APPL_TRACE_DEBUG("%s: Closing timer for AVDTP service", __func__);
- bta_sys_conn_close(BTA_ID_AV, p_cb->p_scb[xx]->app_id,
- p_cb->p_scb[xx]->PeerAddress());
- }
- mask = 1 << (xx + 1);
- if (((mask & p_lcb->conn_msk) || bta_av_cb.conn_lcb) &&
- p_cb->p_scb[xx] &&
- p_cb->p_scb[xx]->PeerAddress() == p_data->str_msg.bd_addr) {
- APPL_TRACE_WARNING("%s: Sending AVDT_DISCONNECT_EVT peer_addr=%s",
- __func__,
- p_cb->p_scb[xx]->PeerAddress().ToString().c_str());
- bta_av_ssm_execute(p_cb->p_scb[xx], BTA_AV_AVDT_DISCONNECT_EVT, NULL);
- }
- }
- }
- }
- APPL_TRACE_DEBUG("%s: bta_av_cb.conn_lcb=0x%x after sig_chg", __func__,
- p_cb->conn_lcb);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_signalling_timer
- *
- * Description process the signal channel timer. This timer is started
- * when the AVDTP signal channel is connected. If no profile
- * is connected, the timer goes off every
- * BTA_AV_SIGNALLING_TIMEOUT_MS.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_signalling_timer(UNUSED_ATTR tBTA_AV_DATA* p_data) {
- tBTA_AV_HNDL hndl = p_data->hdr.layer_specific;
- tBTA_AV_SCB* p_scb = bta_av_hndl_to_scb(hndl);
-
- tBTA_AV_CB* p_cb = &bta_av_cb;
- int xx;
- uint8_t mask;
- tBTA_AV_LCB* p_lcb = NULL;
-
- APPL_TRACE_DEBUG("%s: conn_lcb=0x%x", __func__, p_cb->conn_lcb);
- for (xx = 0; xx < BTA_AV_NUM_LINKS; xx++) {
- p_lcb = &p_cb->lcb[xx];
- mask = 1 << xx;
- APPL_TRACE_DEBUG(
- "%s: index=%d conn_lcb=0x%x peer=%s conn_mask=0x%x lidx=%d", __func__,
- xx, p_cb->conn_lcb, p_lcb->addr.ToString().c_str(), p_lcb->conn_msk,
- p_lcb->lidx);
- if (mask & p_cb->conn_lcb) {
- /* this entry is used. check if it is connected */
- if (!p_lcb->conn_msk) {
- APPL_TRACE_DEBUG("%s hndl 0x%x", __func__, p_scb->hndl);
- bta_sys_start_timer(p_scb->link_signalling_timer,
- BTA_AV_SIGNALLING_TIMEOUT_MS,
- BTA_AV_SIGNALLING_TIMER_EVT, hndl);
- tBTA_AV_PEND pend;
- pend.bd_addr = p_lcb->addr;
- tBTA_AV bta_av_data;
- bta_av_data.pend = pend;
- APPL_TRACE_DEBUG(
- "%s: BTA_AV_PENDING_EVT for %s index=%d conn_mask=0x%x lidx=%d",
- __func__, pend.bd_addr.ToString().c_str(), xx, p_lcb->conn_msk,
- p_lcb->lidx);
- (*p_cb->p_cback)(BTA_AV_PENDING_EVT, &bta_av_data);
- }
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_accept_signalling_timer_cback
- *
- * Description Process the timeout when SRC is accepting connection
- * and SNK did not start signalling.
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_av_accept_signalling_timer_cback(void* data) {
- uint32_t inx = PTR_TO_UINT(data);
- tBTA_AV_CB* p_cb = &bta_av_cb;
- tBTA_AV_SCB* p_scb = NULL;
- if (inx < BTA_AV_NUM_STRS) {
- p_scb = p_cb->p_scb[inx];
- }
- if (p_scb) {
- APPL_TRACE_DEBUG("%s: coll_mask=0x%02x", __func__, p_scb->coll_mask);
-
- if (p_scb->coll_mask & BTA_AV_COLL_INC_TMR) {
- p_scb->coll_mask &= ~BTA_AV_COLL_INC_TMR;
-
- if (bta_av_is_scb_opening(p_scb)) {
- APPL_TRACE_DEBUG("%s: stream state opening: SDP started = %d", __func__,
- p_scb->sdp_discovery_started);
- if (p_scb->sdp_discovery_started) {
- /* We are still doing SDP. Run the timer again. */
- p_scb->coll_mask |= BTA_AV_COLL_INC_TMR;
-
- alarm_set_on_mloop(p_scb->accept_signalling_timer,
- BTA_AV_ACCEPT_SIGNALLING_TIMEOUT_MS,
- bta_av_accept_signalling_timer_cback,
- UINT_TO_PTR(inx));
- } else {
- /* SNK did not start signalling, resume signalling process. */
- bta_av_discover_req(p_scb, NULL);
- }
- } else if (bta_av_is_scb_incoming(p_scb)) {
- /* Stay in incoming state if SNK does not start signalling */
-
- APPL_TRACE_DEBUG("%s: stream state incoming", __func__);
- /* API open was called right after SNK opened L2C connection. */
- if (p_scb->coll_mask & BTA_AV_COLL_API_CALLED) {
- p_scb->coll_mask &= ~BTA_AV_COLL_API_CALLED;
-
- /* BTA_AV_API_OPEN_EVT */
- tBTA_AV_API_OPEN* p_buf =
- (tBTA_AV_API_OPEN*)osi_malloc(sizeof(tBTA_AV_API_OPEN));
- memcpy(p_buf, &(p_scb->open_api), sizeof(tBTA_AV_API_OPEN));
- bta_sys_sendmsg(p_buf);
- }
- }
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_check_peer_features
- *
- * Description check supported features on the peer device from the SDP
- * record and return the feature mask
- *
- * Returns tBTA_AV_FEAT peer device feature mask
- *
- ******************************************************************************/
-tBTA_AV_FEAT bta_av_check_peer_features(uint16_t service_uuid) {
- tBTA_AV_FEAT peer_features = 0;
- tBTA_AV_CB* p_cb = &bta_av_cb;
- tSDP_DISC_REC* p_rec = NULL;
- tSDP_DISC_ATTR* p_attr;
- uint16_t peer_rc_version = 0;
- uint16_t categories = 0;
-
- APPL_TRACE_DEBUG("%s: service_uuid:x%x", __func__, service_uuid);
- /* loop through all records we found */
- while (true) {
- /* get next record; if none found, we're done */
- p_rec = SDP_FindServiceInDb(p_cb->p_disc_db, service_uuid, p_rec);
- if (p_rec == NULL) {
- break;
- }
-
- if ((SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_CLASS_ID_LIST)) !=
- NULL) {
- /* find peer features */
- if (SDP_FindServiceInDb(p_cb->p_disc_db, UUID_SERVCLASS_AV_REMOTE_CONTROL,
- NULL)) {
- peer_features |= BTA_AV_FEAT_RCCT;
- }
- if (SDP_FindServiceInDb(p_cb->p_disc_db,
- UUID_SERVCLASS_AV_REM_CTRL_TARGET, NULL)) {
- peer_features |= BTA_AV_FEAT_RCTG;
- }
- }
-
- if ((SDP_FindAttributeInRec(p_rec, ATTR_ID_BT_PROFILE_DESC_LIST)) != NULL) {
- /* get profile version (if failure, version parameter is not updated) */
- SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL,
- &peer_rc_version);
- APPL_TRACE_DEBUG("%s: peer_rc_version 0x%x", __func__, peer_rc_version);
-
- if (peer_rc_version >= AVRC_REV_1_3)
- peer_features |= (BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_METADATA);
-
- if (peer_rc_version >= AVRC_REV_1_4) {
- /* get supported categories */
- p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES);
- if (p_attr != NULL) {
- categories = p_attr->attr_value.v.u16;
- if (categories & AVRC_SUPF_CT_CAT2)
- peer_features |= (BTA_AV_FEAT_ADV_CTRL);
- if (categories & AVRC_SUPF_CT_BROWSE)
- peer_features |= (BTA_AV_FEAT_BROWSE);
- }
- }
- }
- }
- APPL_TRACE_DEBUG("%s: peer_features:x%x", __func__, peer_features);
- return peer_features;
-}
-
-/*******************************************************************************
- *
- * Function bta_avk_check_peer_features
- *
- * Description check supported features on the peer device from the SDP
- * record and return the feature mask
- *
- * Returns tBTA_AV_FEAT peer device feature mask
- *
- ******************************************************************************/
-tBTA_AV_FEAT bta_avk_check_peer_features(uint16_t service_uuid) {
- tBTA_AV_FEAT peer_features = 0;
- tBTA_AV_CB* p_cb = &bta_av_cb;
-
- APPL_TRACE_DEBUG("%s: service_uuid:x%x", __func__, service_uuid);
-
- /* loop through all records we found */
- tSDP_DISC_REC* p_rec =
- SDP_FindServiceInDb(p_cb->p_disc_db, service_uuid, NULL);
- while (p_rec) {
- APPL_TRACE_DEBUG("%s: found Service record for x%x", __func__,
- service_uuid);
-
- if ((SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_CLASS_ID_LIST)) !=
- NULL) {
- /* find peer features */
- if (SDP_FindServiceInDb(p_cb->p_disc_db, UUID_SERVCLASS_AV_REMOTE_CONTROL,
- NULL)) {
- peer_features |= BTA_AV_FEAT_RCCT;
- }
- if (SDP_FindServiceInDb(p_cb->p_disc_db,
- UUID_SERVCLASS_AV_REM_CTRL_TARGET, NULL)) {
- peer_features |= BTA_AV_FEAT_RCTG;
- }
- }
-
- if ((SDP_FindAttributeInRec(p_rec, ATTR_ID_BT_PROFILE_DESC_LIST)) != NULL) {
- /* get profile version (if failure, version parameter is not updated) */
- uint16_t peer_rc_version = 0;
- bool val = SDP_FindProfileVersionInRec(
- p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_rc_version);
- APPL_TRACE_DEBUG("%s: peer_rc_version for TG 0x%x, profile_found %d",
- __func__, peer_rc_version, val);
-
- if (peer_rc_version >= AVRC_REV_1_3)
- peer_features |= (BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_METADATA);
-
- /* Get supported features */
- tSDP_DISC_ATTR* p_attr =
- SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES);
- if (p_attr != NULL) {
- uint16_t categories = p_attr->attr_value.v.u16;
- /*
- * Though Absolute Volume came after in 1.4 and above, but there are
- * few devices in market which supports absolute Volume and they are
- * still 1.3. To avoid IOP issuses with those devices, we check for
- * 1.3 as minimum version
- */
- if (peer_rc_version >= AVRC_REV_1_3) {
- if (categories & AVRC_SUPF_TG_CAT2)
- peer_features |= (BTA_AV_FEAT_ADV_CTRL);
- if (categories & AVRC_SUPF_TG_APP_SETTINGS)
- peer_features |= (BTA_AV_FEAT_APP_SETTING);
- if (categories & AVRC_SUPF_TG_BROWSE)
- peer_features |= (BTA_AV_FEAT_BROWSE);
- }
-
- /* AVRCP Cover Artwork over BIP */
- if (peer_rc_version >= AVRC_REV_1_6) {
- if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET &&
- categories & AVRC_SUPF_TG_PLAYER_COVER_ART)
- peer_features |= (BTA_AV_FEAT_COVER_ARTWORK);
- }
- }
- }
- /* get next record; if none found, we're done */
- p_rec = SDP_FindServiceInDb(p_cb->p_disc_db, service_uuid, p_rec);
- }
- APPL_TRACE_DEBUG("%s: peer_features:x%x", __func__, peer_features);
- return peer_features;
-}
-
-/******************************************************************************
- *
- * Function bta_avk_get_cover_art_psm
- *
- * Description Get the PSM associated with the AVRCP Target cover art
- * feature
- *
- * Returns uint16_t PSM value used to get cover artwork, or 0x0000 if
- * one does not exist.
- *
- *****************************************************************************/
-uint16_t bta_avk_get_cover_art_psm() {
- APPL_TRACE_DEBUG("%s: searching for cover art psm", __func__);
- /* Cover Art L2CAP PSM is only available on a target device */
- tBTA_AV_CB* p_cb = &bta_av_cb;
- tSDP_DISC_REC* p_rec =
- SDP_FindServiceInDb(p_cb->p_disc_db, UUID_SERVCLASS_AV_REM_CTRL_TARGET,
- NULL);
- while (p_rec) {
- tSDP_DISC_ATTR* p_attr =
- (SDP_FindAttributeInRec(p_rec, ATTR_ID_ADDITION_PROTO_DESC_LISTS));
- /*
- * If we have the Additional Protocol Description Lists attribute then we
- * specifically want the list that is an L2CAP protocol leading to OBEX.
- * Because the is a case where cover art is supported and browsing isn't
- * we need to check each list for the one we want.
- *
- * This means we need to do drop down into the protocol list and do a
- * "for each protocol, for each protocol element, for each protocol element
- * list parameter, if the parameter is L2CAP then find the PSM associated
- * with it, then make sure we see OBEX in that same protocol"
- */
- if (p_attr != NULL && SDP_DISC_ATTR_TYPE(p_attr->attr_len_type)
- == DATA_ELE_SEQ_DESC_TYPE) {
- // Point to first in List of protocols (i.e [(L2CAP -> AVCTP),
- // (L2CAP -> OBEX)])
- tSDP_DISC_ATTR* p_protocol_list = p_attr->attr_value.v.p_sub_attr;
- while (p_protocol_list != NULL) {
- if (SDP_DISC_ATTR_TYPE(p_protocol_list->attr_len_type)
- == DATA_ELE_SEQ_DESC_TYPE) {
- // Point to fist in list of protocol elements (i.e. [L2CAP, AVCTP])
- tSDP_DISC_ATTR* p_protocol =
- p_protocol_list->attr_value.v.p_sub_attr;
- bool protocol_has_obex = false;
- bool protocol_has_l2cap = false;
- uint16_t psm = 0x0000;
- while (p_protocol) {
- if (SDP_DISC_ATTR_TYPE(p_protocol->attr_len_type)
- == DATA_ELE_SEQ_DESC_TYPE) {
- // Point to first item protocol parameters list (i.e [UUID=L2CAP,
- // PSM=0x1234])
- tSDP_DISC_ATTR* p_protocol_param =
- p_protocol->attr_value.v.p_sub_attr;
- /*
- * Currently there's only ever one UUID and one parameter. L2cap
- * has a single PSM, AVCTP has a version and OBEX has nothing.
- * Change this if that ever changes.
- */
- uint16_t protocol_uuid = 0;
- uint16_t protocol_param = 0;
- while (p_protocol_param) {
- uint16_t param_type =
- SDP_DISC_ATTR_TYPE(p_protocol_param->attr_len_type);
- uint16_t param_len =
- SDP_DISC_ATTR_LEN(p_protocol_param->attr_len_type);
- if (param_type == UUID_DESC_TYPE) {
- protocol_uuid = p_protocol_param->attr_value.v.u16;
- } else if (param_type == UINT_DESC_TYPE) {
- protocol_param = (param_len == 2)
- ? p_protocol_param->attr_value.v.u16
- : p_protocol_param->attr_value.v.u8;
- } /* else dont care */
- p_protocol_param = p_protocol_param->p_next_attr; // next
- }
- // If we've found L2CAP then the parameter is a PSM
- if (protocol_uuid == UUID_PROTOCOL_L2CAP) {
- protocol_has_l2cap = true;
- psm = protocol_param;
- } else if (protocol_uuid == UUID_PROTOCOL_OBEX) {
- protocol_has_obex = true;
- }
- }
- // If this protocol has l2cap and obex then we're found the BIP PSM
- if (protocol_has_l2cap && protocol_has_obex) {
- APPL_TRACE_DEBUG("%s: found psm 0x%x", __func__, psm);
- return psm;
- }
- p_protocol = p_protocol->p_next_attr; // next protocol element
- }
- }
- p_protocol_list = p_protocol_list->p_next_attr; // next protocol
- }
- }
- /* get next record; if none found, we're done */
- p_rec = SDP_FindServiceInDb(p_cb->p_disc_db,
- UUID_SERVCLASS_AV_REM_CTRL_TARGET, p_rec);
- }
- /* L2CAP PSM range is 0x1000-0xFFFF so 0x0000 is safe default invalid */
- APPL_TRACE_DEBUG("%s: could not find a BIP psm", __func__);
- return 0x0000;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_disc_done
- *
- * Description Handle AVRCP service discovery results. If matching
- * service found, open AVRCP connection.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rc_disc_done(UNUSED_ATTR tBTA_AV_DATA* p_data) {
- tBTA_AV_CB* p_cb = &bta_av_cb;
- tBTA_AV_SCB* p_scb = NULL;
- tBTA_AV_LCB* p_lcb;
- uint8_t rc_handle;
- tBTA_AV_FEAT peer_features = 0; /* peer features mask */
- uint16_t cover_art_psm = 0x0000;
-
- APPL_TRACE_DEBUG("%s: bta_av_rc_disc_done disc:x%x", __func__, p_cb->disc);
- if (!p_cb->disc) {
- return;
- }
-
- if ((p_cb->disc & BTA_AV_CHNL_MSK) == BTA_AV_CHNL_MSK) {
- /* this is the rc handle/index to tBTA_AV_RCB */
- rc_handle = p_cb->disc & (~BTA_AV_CHNL_MSK);
- } else {
- /* Validate array index*/
- if (((p_cb->disc & BTA_AV_HNDL_MSK) - 1) < BTA_AV_NUM_STRS) {
- p_scb = p_cb->p_scb[(p_cb->disc & BTA_AV_HNDL_MSK) - 1];
- }
- if (p_scb) {
- rc_handle = p_scb->rc_handle;
- } else {
- p_cb->disc = 0;
- return;
- }
- }
-
- APPL_TRACE_DEBUG("%s: rc_handle %d", __func__, rc_handle);
- if (p_cb->sdp_a2dp_snk_handle) {
- /* This is Sink + CT + TG(Abs Vol) */
- peer_features =
- bta_avk_check_peer_features(UUID_SERVCLASS_AV_REM_CTRL_TARGET);
- APPL_TRACE_DEBUG("%s: populating rem ctrl target features %d", __func__,
- peer_features);
- if (BTA_AV_FEAT_ADV_CTRL &
- bta_avk_check_peer_features(UUID_SERVCLASS_AV_REMOTE_CONTROL))
- peer_features |= (BTA_AV_FEAT_ADV_CTRL | BTA_AV_FEAT_RCCT);
-
- if (peer_features & BTA_AV_FEAT_COVER_ARTWORK)
- cover_art_psm = bta_avk_get_cover_art_psm();
-
- APPL_TRACE_DEBUG("%s: populating rem ctrl target bip psm 0x%x", __func__,
- cover_art_psm);
- } else if (p_cb->sdp_a2dp_handle) {
- /* check peer version and whether support CT and TG role */
- peer_features =
- bta_av_check_peer_features(UUID_SERVCLASS_AV_REMOTE_CONTROL);
- if ((p_cb->features & BTA_AV_FEAT_ADV_CTRL) &&
- ((peer_features & BTA_AV_FEAT_ADV_CTRL) == 0)) {
- /* if we support advance control and peer does not, check their support on
- * TG role
- * some implementation uses 1.3 on CT ans 1.4 on TG */
- peer_features |=
- bta_av_check_peer_features(UUID_SERVCLASS_AV_REM_CTRL_TARGET);
- }
-
- /* Change our features if the remote AVRCP version is 1.3 or less */
- tSDP_DISC_REC* p_rec = nullptr;
- p_rec = SDP_FindServiceInDb(p_cb->p_disc_db,
- UUID_SERVCLASS_AV_REMOTE_CONTROL, p_rec);
- if (p_rec != NULL &&
- SDP_FindAttributeInRec(p_rec, ATTR_ID_BT_PROFILE_DESC_LIST) != NULL) {
- /* get profile version (if failure, version parameter is not updated) */
- uint16_t peer_rc_version = 0xFFFF; // Don't change the AVRCP version
- SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL,
- &peer_rc_version);
- if (peer_rc_version <= AVRC_REV_1_3) {
- APPL_TRACE_DEBUG("%s: Using AVRCP 1.3 Capabilities with remote device",
- __func__);
- p_bta_av_cfg = &bta_av_cfg_compatibility;
- }
- }
- }
-
- p_cb->disc = 0;
- osi_free_and_reset((void**)&p_cb->p_disc_db);
-
- APPL_TRACE_DEBUG("%s: peer_features 0x%x, features 0x%x", __func__,
- peer_features, p_cb->features);
-
- /* if we have no rc connection */
- if (rc_handle == BTA_AV_RC_HANDLE_NONE) {
- if (p_scb) {
- /* if peer remote control service matches ours and USE_RC is true */
- if ((((p_cb->features & BTA_AV_FEAT_RCCT) &&
- (peer_features & BTA_AV_FEAT_RCTG)) ||
- ((p_cb->features & BTA_AV_FEAT_RCTG) &&
- (peer_features & BTA_AV_FEAT_RCCT)))) {
- p_lcb = bta_av_find_lcb(p_scb->PeerAddress(), BTA_AV_LCB_FIND);
- if (p_lcb) {
- rc_handle = bta_av_rc_create(p_cb, AVCT_INT,
- (uint8_t)(p_scb->hdi + 1), p_lcb->lidx);
- p_cb->rcb[rc_handle].peer_features = peer_features;
- p_cb->rcb[rc_handle].cover_art_psm = cover_art_psm;
- } else {
- APPL_TRACE_ERROR("%s: can not find LCB!!", __func__);
- }
- } else if (p_scb->use_rc) {
- /* can not find AVRC on peer device. report failure */
- p_scb->use_rc = false;
- tBTA_AV_RC_OPEN rc_open;
- rc_open.peer_addr = p_scb->PeerAddress();
- rc_open.peer_features = 0;
- rc_open.cover_art_psm = 0;
- rc_open.status = BTA_AV_FAIL_SDP;
- tBTA_AV bta_av_data;
- bta_av_data.rc_open = rc_open;
- (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, &bta_av_data);
- }
- }
- } else {
- tBTA_AV_RC_FEAT rc_feat;
- p_cb->rcb[rc_handle].peer_features = peer_features;
- rc_feat.rc_handle = rc_handle;
- rc_feat.peer_features = peer_features;
- if (p_scb == NULL) {
- /*
- * In case scb is not created by the time we are done with SDP
- * we still need to send RC feature event. So we need to get BD
- * from Message. Note that lidx is 1 based not 0 based
- */
- rc_feat.peer_addr = p_cb->lcb[p_cb->rcb[rc_handle].lidx - 1].addr;
- } else {
- rc_feat.peer_addr = p_scb->PeerAddress();
- }
-
- tBTA_AV bta_av_feat;
- bta_av_feat.rc_feat = rc_feat;
- (*p_cb->p_cback)(BTA_AV_RC_FEAT_EVT, &bta_av_feat);
-
- // Send PSM data
- APPL_TRACE_DEBUG("%s: Send PSM data", __func__);
- tBTA_AV_RC_PSM rc_psm;
- p_cb->rcb[rc_handle].cover_art_psm = cover_art_psm;
- rc_psm.rc_handle = rc_handle;
- rc_psm.cover_art_psm = cover_art_psm;
- if (p_scb == NULL) {
- rc_psm.peer_addr = p_cb->lcb[p_cb->rcb[rc_handle].lidx - 1].addr;
- } else {
- rc_psm.peer_addr = p_scb->PeerAddress();
- }
-
- APPL_TRACE_DEBUG("%s: rc_psm = 0x%x", __func__, rc_psm.cover_art_psm);
-
- tBTA_AV bta_av_psm;
- bta_av_psm.rc_cover_art_psm = rc_psm;
- (*p_cb->p_cback)(BTA_AV_RC_PSM_EVT, &bta_av_psm);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_closed
- *
- * Description Set AVRCP state to closed.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rc_closed(tBTA_AV_DATA* p_data) {
- tBTA_AV_CB* p_cb = &bta_av_cb;
- tBTA_AV_RC_CLOSE rc_close;
- tBTA_AV_RC_CONN_CHG* p_msg = (tBTA_AV_RC_CONN_CHG*)p_data;
- tBTA_AV_RCB* p_rcb;
- tBTA_AV_SCB* p_scb;
- int i;
- bool conn = false;
- tBTA_AV_LCB* p_lcb;
-
- rc_close.rc_handle = BTA_AV_RC_HANDLE_NONE;
- p_scb = NULL;
- APPL_TRACE_DEBUG("%s: rc_handle:%d", __func__, p_msg->handle);
- for (i = 0; i < BTA_AV_NUM_RCB; i++) {
- p_rcb = &p_cb->rcb[i];
- APPL_TRACE_DEBUG("%s: rcb[%d] rc_handle:%d, status=0x%x", __func__, i,
- p_rcb->handle, p_rcb->status);
- if (p_rcb->handle == p_msg->handle) {
- rc_close.rc_handle = i;
- p_rcb->status &= ~BTA_AV_RC_CONN_MASK;
- p_rcb->peer_features = 0;
- p_rcb->cover_art_psm = 0;
- APPL_TRACE_DEBUG("%s: shdl:%d, lidx:%d", __func__, p_rcb->shdl,
- p_rcb->lidx);
- if (p_rcb->shdl) {
- if ((p_rcb->shdl - 1) < BTA_AV_NUM_STRS) {
- p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1];
- }
- if (p_scb) {
- rc_close.peer_addr = p_scb->PeerAddress();
- if (p_scb->rc_handle == p_rcb->handle)
- p_scb->rc_handle = BTA_AV_RC_HANDLE_NONE;
- APPL_TRACE_DEBUG("%s: shdl:%d, srch:%d", __func__, p_rcb->shdl,
- p_scb->rc_handle);
- }
- p_rcb->shdl = 0;
- } else if (p_rcb->lidx == (BTA_AV_NUM_LINKS + 1)) {
- /* if the RCB uses the extra LCB, use the addr for event and clean it */
- p_lcb = &p_cb->lcb[BTA_AV_NUM_LINKS];
- rc_close.peer_addr = p_msg->peer_addr;
- LOG_INFO("%s: rc_only closed bd_addr: %s", __func__,
- p_msg->peer_addr.ToString().c_str());
- p_lcb->conn_msk = 0;
- p_lcb->lidx = 0;
- }
- p_rcb->lidx = 0;
-
- if ((p_rcb->status & BTA_AV_RC_ROLE_MASK) == BTA_AV_RC_ROLE_INT) {
- /* AVCT CCB is deallocated */
- p_rcb->handle = BTA_AV_RC_HANDLE_NONE;
- p_rcb->status = 0;
- } else {
- /* AVCT CCB is still there. dealloc */
- bta_av_del_rc(p_rcb);
- }
- } else if ((p_rcb->handle != BTA_AV_RC_HANDLE_NONE) &&
- (p_rcb->status & BTA_AV_RC_CONN_MASK)) {
- /* at least one channel is still connected */
- conn = true;
- }
- }
-
- if (!conn) {
- /* no AVRC channels are connected, go back to INIT state */
- bta_av_sm_execute(p_cb, BTA_AV_AVRC_NONE_EVT, NULL);
- }
-
- if (rc_close.rc_handle == BTA_AV_RC_HANDLE_NONE) {
- rc_close.rc_handle = p_msg->handle;
- rc_close.peer_addr = p_msg->peer_addr;
- }
- tBTA_AV bta_av_data;
- bta_av_data.rc_close = rc_close;
- (*p_cb->p_cback)(BTA_AV_RC_CLOSE_EVT, &bta_av_data);
- if (bta_av_cb.rc_acp_handle == BTA_AV_RC_HANDLE_NONE
- && bta_av_cb.features & BTA_AV_FEAT_RCTG)
- bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_browse_opened
- *
- * Description AVRC browsing channel is opened
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rc_browse_opened(tBTA_AV_DATA* p_data) {
- tBTA_AV_CB* p_cb = &bta_av_cb;
- tBTA_AV_RC_CONN_CHG* p_msg = (tBTA_AV_RC_CONN_CHG*)p_data;
- tBTA_AV_RC_BROWSE_OPEN rc_browse_open;
-
- LOG_INFO("%s: peer_addr: %s rc_handle:%d", __func__,
- p_msg->peer_addr.ToString().c_str(), p_msg->handle);
-
- rc_browse_open.status = BTA_AV_SUCCESS;
- rc_browse_open.rc_handle = p_msg->handle;
- rc_browse_open.peer_addr = p_msg->peer_addr;
-
- tBTA_AV bta_av_data;
- bta_av_data.rc_browse_open = rc_browse_open;
- (*p_cb->p_cback)(BTA_AV_RC_BROWSE_OPEN_EVT, &bta_av_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_browse_closed
- *
- * Description AVRC browsing channel is closed
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rc_browse_closed(tBTA_AV_DATA* p_data) {
- tBTA_AV_CB* p_cb = &bta_av_cb;
- tBTA_AV_RC_CONN_CHG* p_msg = (tBTA_AV_RC_CONN_CHG*)p_data;
- tBTA_AV_RC_BROWSE_CLOSE rc_browse_close;
-
- LOG_INFO("%s: peer_addr: %s rc_handle:%d", __func__,
- p_msg->peer_addr.ToString().c_str(), p_msg->handle);
-
- rc_browse_close.rc_handle = p_msg->handle;
- rc_browse_close.peer_addr = p_msg->peer_addr;
-
- tBTA_AV bta_av_data;
- bta_av_data.rc_browse_close = rc_browse_close;
- (*p_cb->p_cback)(BTA_AV_RC_BROWSE_CLOSE_EVT, &bta_av_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rc_disc
- *
- * Description start AVRC SDP discovery.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_rc_disc(uint8_t disc) {
- tBTA_AV_CB* p_cb = &bta_av_cb;
- tAVRC_SDP_DB_PARAMS db_params;
- uint16_t attr_list[] = {ATTR_ID_SERVICE_CLASS_ID_LIST,
- ATTR_ID_BT_PROFILE_DESC_LIST,
- ATTR_ID_SUPPORTED_FEATURES,
- ATTR_ID_ADDITION_PROTO_DESC_LISTS};
- uint8_t hdi;
- tBTA_AV_SCB* p_scb;
- RawAddress peer_addr = RawAddress::kEmpty;
- uint8_t rc_handle;
-
- APPL_TRACE_DEBUG("%s: disc: 0x%x, bta_av_cb.disc: 0x%x", __func__, disc,
- bta_av_cb.disc);
- if ((bta_av_cb.disc != 0) || (disc == 0)) return;
-
- if ((disc & BTA_AV_CHNL_MSK) == BTA_AV_CHNL_MSK) {
- /* this is the rc handle/index to tBTA_AV_RCB */
- rc_handle = disc & (~BTA_AV_CHNL_MSK);
- if (p_cb->rcb[rc_handle].lidx) {
- peer_addr = p_cb->lcb[p_cb->rcb[rc_handle].lidx - 1].addr;
- }
- } else {
- hdi = (disc & BTA_AV_HNDL_MSK) - 1;
- p_scb = p_cb->p_scb[hdi];
-
- if (p_scb) {
- APPL_TRACE_DEBUG("%s: rc_handle %d", __func__, p_scb->rc_handle);
- peer_addr = p_scb->PeerAddress();
- }
- }
-
- if (!peer_addr.IsEmpty()) {
- /* allocate discovery database */
- if (p_cb->p_disc_db == NULL)
- p_cb->p_disc_db = (tSDP_DISCOVERY_DB*)osi_malloc(BTA_AV_DISC_BUF_SIZE);
-
- /* set up parameters */
- db_params.db_len = BTA_AV_DISC_BUF_SIZE;
- db_params.num_attr = sizeof(attr_list) / sizeof(uint16_t);
- db_params.p_db = p_cb->p_disc_db;
- db_params.p_attrs = attr_list;
-
- /* searching for UUID_SERVCLASS_AV_REMOTE_CONTROL gets both TG and CT */
- if (AVRC_FindService(UUID_SERVCLASS_AV_REMOTE_CONTROL, peer_addr,
- &db_params,
- base::Bind(bta_av_avrc_sdp_cback)) == AVRC_SUCCESS) {
- p_cb->disc = disc;
- APPL_TRACE_DEBUG("%s: disc 0x%x", __func__, p_cb->disc);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_dereg_comp
- *
- * Description deregister complete. free the stream control block.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_dereg_comp(tBTA_AV_DATA* p_data) {
- tBTA_AV_CB* p_cb = &bta_av_cb;
- tBTA_AV_SCB* p_scb;
- tBTA_UTL_COD cod;
- uint8_t mask;
- BT_HDR* p_buf;
-
- /* find the stream control block */
- p_scb = bta_av_hndl_to_scb(p_data->hdr.layer_specific);
-
- if (p_scb) {
- APPL_TRACE_DEBUG("%s: deregistered %d(h%d)", __func__, p_scb->chnl,
- p_scb->hndl);
- mask = BTA_AV_HNDL_TO_MSK(p_scb->hdi);
- p_cb->reg_audio &= ~mask;
- if ((p_cb->conn_audio & mask) && p_cb->audio_open_cnt) {
- /* this channel is still marked as open. decrease the count */
- p_cb->audio_open_cnt--;
- }
- p_cb->conn_audio &= ~mask;
-
- if (p_scb->q_tag == BTA_AV_Q_TAG_STREAM && p_scb->a2dp_list) {
- /* make sure no buffers are in a2dp_list */
- while (!list_is_empty(p_scb->a2dp_list)) {
- p_buf = (BT_HDR*)list_front(p_scb->a2dp_list);
- list_remove(p_scb->a2dp_list, p_buf);
- osi_free(p_buf);
- }
- }
-
- /* remove the A2DP SDP record, if no more audio stream is left */
- if (!p_cb->reg_audio) {
-
- /* Only remove the SDP record if we're the ones that created it */
- if (is_new_avrcp_enabled()) {
- APPL_TRACE_DEBUG("%s: newavrcp is the owner of the AVRCP Target SDP "
- "record. Don't dereg the SDP record", __func__);
- } else {
- APPL_TRACE_DEBUG("%s: newavrcp is not enabled. Remove SDP record",
- __func__);
- bta_ar_dereg_avrc(UUID_SERVCLASS_AV_REMOTE_CONTROL);
- }
-
- if (p_cb->sdp_a2dp_handle) {
- bta_av_del_sdp_rec(&p_cb->sdp_a2dp_handle);
- p_cb->sdp_a2dp_handle = 0;
- bta_sys_remove_uuid(UUID_SERVCLASS_AUDIO_SOURCE);
- }
-
- if (p_cb->sdp_a2dp_snk_handle) {
- bta_av_del_sdp_rec(&p_cb->sdp_a2dp_snk_handle);
- p_cb->sdp_a2dp_snk_handle = 0;
- bta_sys_remove_uuid(UUID_SERVCLASS_AUDIO_SINK);
- }
- }
-
- bta_av_free_scb(p_scb);
- }
-
- APPL_TRACE_DEBUG("%s: audio 0x%x, disable:%d", __func__, p_cb->reg_audio,
- p_cb->disabling);
- /* if no stream control block is active */
- if (p_cb->reg_audio == 0) {
- /* deregister from AVDT */
- bta_ar_dereg_avdt();
-
- /* deregister from AVCT */
- bta_ar_dereg_avrc(UUID_SERVCLASS_AV_REM_CTRL_TARGET);
- bta_ar_dereg_avct();
-
- if (p_cb->disabling) {
- p_cb->disabling = false;
- // reset enabling parameters
- p_cb->features = 0;
- p_cb->sec_mask = 0;
- }
-
- /* Clear the Capturing service class bit */
- cod.service = BTM_COD_SERVICE_CAPTURING;
- utl_set_device_class(&cod, BTA_UTL_CLR_COD_SERVICE_CLASS);
- }
-}
diff --git a/bta/av/bta_av_api.cc b/bta/av/bta_av_api.cc
deleted file mode 100644
index 9a8ccfd..0000000
--- a/bta/av/bta_av_api.cc
+++ /dev/null
@@ -1,615 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2011-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the implementation of the API for the advanced audio/video (AV)
- * subsystem of BTA, Broadcom's Bluetooth application layer for mobile
- * phones.
- *
- ******************************************************************************/
-
-#define LOG_TAG "bt_bta_av"
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bta/av/bta_av_int.h"
-#include "osi/include/allocator.h"
-#include "osi/include/compat.h"
-#include "osi/include/log.h"
-#include "stack/include/bt_hdr.h"
-#include "types/raw_address.h"
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-
-static const tBTA_SYS_REG bta_av_reg = {bta_av_hdl_event, BTA_AvDisable};
-
-/*******************************************************************************
- *
- * Function BTA_AvEnable
- *
- * Description Enable the advanced audio/video service. When the enable
- * operation is complete the callback function will be
- * called with a BTA_AV_ENABLE_EVT. This function must
- * be called before other function in the AV API are
- * called.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvEnable(tBTA_AV_FEAT features, tBTA_AV_CBACK* p_cback) {
- tBTA_AV_API_ENABLE* p_buf =
- (tBTA_AV_API_ENABLE*)osi_malloc(sizeof(tBTA_AV_API_ENABLE));
-
- /* register with BTA system manager */
- bta_sys_register(BTA_ID_AV, &bta_av_reg);
-
- p_buf->hdr.event = BTA_AV_API_ENABLE_EVT;
- p_buf->p_cback = p_cback;
- p_buf->features = features;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvDisable
- *
- * Description Disable the advanced audio/video service.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvDisable(void) {
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
-
- bta_sys_deregister(BTA_ID_AV);
- p_buf->event = BTA_AV_API_DISABLE_EVT;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvRegister
- *
- * Description Register the audio or video service to stack. When the
- * operation is complete the callback function will be
- * called with a BTA_AV_REGISTER_EVT. This function must
- * be called before AVDT stream is open.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvRegister(tBTA_AV_CHNL chnl, const char* p_service_name,
- uint8_t app_id, tBTA_AV_SINK_DATA_CBACK* p_sink_data_cback,
- uint16_t service_uuid) {
- tBTA_AV_API_REG* p_buf =
- (tBTA_AV_API_REG*)osi_malloc(sizeof(tBTA_AV_API_REG));
-
- p_buf->hdr.layer_specific = chnl;
- p_buf->hdr.event = BTA_AV_API_REGISTER_EVT;
- if (p_service_name)
- strlcpy(p_buf->p_service_name, p_service_name, BTA_SERVICE_NAME_LEN);
- else
- p_buf->p_service_name[0] = 0;
- p_buf->app_id = app_id;
- p_buf->p_app_sink_data_cback = p_sink_data_cback;
- p_buf->service_uuid = service_uuid;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvDeregister
- *
- * Description Deregister the audio or video service
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvDeregister(tBTA_AV_HNDL hndl) {
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
-
- p_buf->layer_specific = hndl;
- p_buf->event = BTA_AV_API_DEREGISTER_EVT;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvOpen
- *
- * Description Opens an advanced audio/video connection to a peer device.
- * When connection is open callback function is called
- * with a BTA_AV_OPEN_EVT.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvOpen(const RawAddress& bd_addr, tBTA_AV_HNDL handle, bool use_rc,
- uint16_t uuid) {
- LOG_INFO("%s: peer %s bta_handle:0x%x use_rc=%s uuid=0x%x", __func__,
- bd_addr.ToString().c_str(), handle, (use_rc) ? "true" : "false",
- uuid);
-
- tBTA_AV_API_OPEN* p_buf =
- (tBTA_AV_API_OPEN*)osi_malloc(sizeof(tBTA_AV_API_OPEN));
-
- p_buf->hdr.event = BTA_AV_API_OPEN_EVT;
- p_buf->hdr.layer_specific = handle;
- p_buf->bd_addr = bd_addr;
- p_buf->use_rc = use_rc;
- p_buf->switch_res = BTA_AV_RS_NONE;
- p_buf->uuid = uuid;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvClose
- *
- * Description Close the current streams.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvClose(tBTA_AV_HNDL handle) {
- LOG_INFO("%s: bta_handle:0x%x", __func__, handle);
-
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
-
- p_buf->event = BTA_AV_API_CLOSE_EVT;
- p_buf->layer_specific = handle;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvDisconnect
- *
- * Description Close the connection to the address.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvDisconnect(tBTA_AV_HNDL handle) {
- LOG_INFO("%s: bta_handle=0x%x", __func__, handle);
-
- tBTA_AV_API_DISCNT* p_buf =
- (tBTA_AV_API_DISCNT*)osi_malloc(sizeof(tBTA_AV_API_DISCNT));
-
- p_buf->hdr.event = BTA_AV_API_DISCONNECT_EVT;
- p_buf->hdr.layer_specific = handle;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvStart
- *
- * Description Start audio/video stream data transfer.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvStart(tBTA_AV_HNDL handle) {
- LOG_INFO("Starting audio/video stream data transfer bta_handle:%hhu", handle);
-
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
-
- p_buf->event = BTA_AV_API_START_EVT;
- p_buf->layer_specific = handle;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvOffloadStart
- *
- * Description Start a2dp audio offloading.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvOffloadStart(tBTA_AV_HNDL hndl) {
- LOG_INFO("%s: bta_handle=0x%x", __func__, hndl);
-
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
-
- p_buf->event = BTA_AV_API_OFFLOAD_START_EVT;
- p_buf->layer_specific = hndl;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvOffloadStartRsp
- *
- * Description Response from vendor lib for A2DP Offload Start request.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvOffloadStartRsp(tBTA_AV_HNDL hndl, tBTA_AV_STATUS status) {
- tBTA_AV_API_STATUS_RSP* p_buf =
- (tBTA_AV_API_STATUS_RSP*)osi_malloc(sizeof(tBTA_AV_API_STATUS_RSP));
-
- p_buf->hdr.event = BTA_AV_API_OFFLOAD_START_RSP_EVT;
- p_buf->hdr.layer_specific = hndl;
- p_buf->status = status;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvStop
- *
- * Description Stop audio/video stream data transfer.
- * If suspend is true, this function sends AVDT suspend signal
- * to the connected peer(s).
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvStop(tBTA_AV_HNDL handle, bool suspend) {
- LOG_INFO("%s: bta_handle=0x%x suspend=%s", __func__, handle,
- logbool(suspend).c_str());
-
- tBTA_AV_API_STOP* p_buf =
- (tBTA_AV_API_STOP*)osi_malloc(sizeof(tBTA_AV_API_STOP));
-
- p_buf->hdr.event = BTA_AV_API_STOP_EVT;
- p_buf->hdr.layer_specific = handle;
- p_buf->flush = true;
- p_buf->suspend = suspend;
- p_buf->reconfig_stop = false;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvReconfig
- *
- * Description Reconfigure the audio/video stream.
- * If suspend is true, this function tries the
- * suspend/reconfigure procedure first.
- * If suspend is false or when suspend/reconfigure fails,
- * this function closes and re-opens the AVDT connection.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvReconfig(tBTA_AV_HNDL hndl, bool suspend, uint8_t sep_info_idx,
- uint8_t* p_codec_info, uint8_t num_protect,
- const uint8_t* p_protect_info) {
- LOG_INFO("%s: bta_handle=0x%x suspend=%s sep_info_idx=%d", __func__, hndl,
- logbool(suspend).c_str(), sep_info_idx);
-
- tBTA_AV_API_RCFG* p_buf =
- (tBTA_AV_API_RCFG*)osi_malloc(sizeof(tBTA_AV_API_RCFG) + num_protect);
-
- p_buf->hdr.layer_specific = hndl;
- p_buf->hdr.event = BTA_AV_API_RECONFIG_EVT;
- p_buf->num_protect = num_protect;
- p_buf->suspend = suspend;
- p_buf->sep_info_idx = sep_info_idx;
- p_buf->p_protect_info = (uint8_t*)(p_buf + 1);
- memcpy(p_buf->codec_info, p_codec_info, AVDT_CODEC_SIZE);
- memcpy(p_buf->p_protect_info, p_protect_info, num_protect);
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvProtectReq
- *
- * Description Send a content protection request. This function can only
- * be used if AV is enabled with feature BTA_AV_FEAT_PROTECT.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvProtectReq(tBTA_AV_HNDL hndl, uint8_t* p_data, uint16_t len) {
- tBTA_AV_API_PROTECT_REQ* p_buf = (tBTA_AV_API_PROTECT_REQ*)osi_malloc(
- sizeof(tBTA_AV_API_PROTECT_REQ) + len);
-
- p_buf->hdr.layer_specific = hndl;
- p_buf->hdr.event = BTA_AV_API_PROTECT_REQ_EVT;
- p_buf->len = len;
- if (p_data == NULL) {
- p_buf->p_data = NULL;
- } else {
- p_buf->p_data = (uint8_t*)(p_buf + 1);
- memcpy(p_buf->p_data, p_data, len);
- }
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvProtectRsp
- *
- * Description Send a content protection response. This function must
- * be called if a BTA_AV_PROTECT_REQ_EVT is received.
- * This function can only be used if AV is enabled with
- * feature BTA_AV_FEAT_PROTECT.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvProtectRsp(tBTA_AV_HNDL hndl, uint8_t error_code, uint8_t* p_data,
- uint16_t len) {
- tBTA_AV_API_PROTECT_RSP* p_buf = (tBTA_AV_API_PROTECT_RSP*)osi_malloc(
- sizeof(tBTA_AV_API_PROTECT_RSP) + len);
-
- p_buf->hdr.layer_specific = hndl;
- p_buf->hdr.event = BTA_AV_API_PROTECT_RSP_EVT;
- p_buf->len = len;
- p_buf->error_code = error_code;
- if (p_data == NULL) {
- p_buf->p_data = NULL;
- } else {
- p_buf->p_data = (uint8_t*)(p_buf + 1);
- memcpy(p_buf->p_data, p_data, len);
- }
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvRemoteCmd
- *
- * Description Send a remote control command. This function can only
- * be used if AV is enabled with feature BTA_AV_FEAT_RCCT.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvRemoteCmd(uint8_t rc_handle, uint8_t label, tBTA_AV_RC rc_id,
- tBTA_AV_STATE key_state) {
- tBTA_AV_API_REMOTE_CMD* p_buf =
- (tBTA_AV_API_REMOTE_CMD*)osi_malloc(sizeof(tBTA_AV_API_REMOTE_CMD));
-
- p_buf->hdr.event = BTA_AV_API_REMOTE_CMD_EVT;
- p_buf->hdr.layer_specific = rc_handle;
- p_buf->msg.op_id = rc_id;
- p_buf->msg.state = key_state;
- p_buf->msg.p_pass_data = NULL;
- p_buf->msg.pass_len = 0;
- p_buf->label = label;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvRemoteVendorUniqueCmd
- *
- * Description Send a remote control command with Vendor Unique rc_id.
- * This function can only be used if AV is enabled with
- * feature BTA_AV_FEAT_RCCT.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvRemoteVendorUniqueCmd(uint8_t rc_handle, uint8_t label,
- tBTA_AV_STATE key_state, uint8_t* p_msg,
- uint8_t buf_len) {
- tBTA_AV_API_REMOTE_CMD* p_buf = (tBTA_AV_API_REMOTE_CMD*)osi_malloc(
- sizeof(tBTA_AV_API_REMOTE_CMD) + buf_len);
-
- p_buf->label = label;
- p_buf->hdr.event = BTA_AV_API_REMOTE_CMD_EVT;
- p_buf->hdr.layer_specific = rc_handle;
- p_buf->msg.op_id = AVRC_ID_VENDOR;
- p_buf->msg.state = key_state;
- p_buf->msg.pass_len = buf_len;
- if (p_msg == NULL) {
- p_buf->msg.p_pass_data = NULL;
- } else {
- p_buf->msg.p_pass_data = (uint8_t*)(p_buf + 1);
- memcpy(p_buf->msg.p_pass_data, p_msg, buf_len);
- }
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvVendorCmd
- *
- * Description Send a vendor dependent remote control command. This
- * function can only be used if AV is enabled with feature
- * BTA_AV_FEAT_VENDOR.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvVendorCmd(uint8_t rc_handle, uint8_t label, tBTA_AV_CODE cmd_code,
- uint8_t* p_data, uint16_t len) {
- tBTA_AV_API_VENDOR* p_buf =
- (tBTA_AV_API_VENDOR*)osi_malloc(sizeof(tBTA_AV_API_VENDOR) + len);
-
- p_buf->hdr.event = BTA_AV_API_VENDOR_CMD_EVT;
- p_buf->hdr.layer_specific = rc_handle;
- p_buf->msg.hdr.ctype = cmd_code;
- p_buf->msg.hdr.subunit_type = AVRC_SUB_PANEL;
- p_buf->msg.hdr.subunit_id = 0;
- p_buf->msg.company_id = p_bta_av_cfg->company_id;
- p_buf->label = label;
- p_buf->msg.vendor_len = len;
- if (p_data == NULL) {
- p_buf->msg.p_vendor_data = NULL;
- } else {
- p_buf->msg.p_vendor_data = (uint8_t*)(p_buf + 1);
- memcpy(p_buf->msg.p_vendor_data, p_data, len);
- }
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvVendorRsp
- *
- * Description Send a vendor dependent remote control response.
- * This function must be called if a BTA_AV_VENDOR_CMD_EVT
- * is received. This function can only be used if AV is
- * enabled with feature BTA_AV_FEAT_VENDOR.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvVendorRsp(uint8_t rc_handle, uint8_t label, tBTA_AV_CODE rsp_code,
- uint8_t* p_data, uint16_t len, uint32_t company_id) {
- tBTA_AV_API_VENDOR* p_buf =
- (tBTA_AV_API_VENDOR*)osi_malloc(sizeof(tBTA_AV_API_VENDOR) + len);
-
- p_buf->hdr.event = BTA_AV_API_VENDOR_RSP_EVT;
- p_buf->hdr.layer_specific = rc_handle;
- p_buf->msg.hdr.ctype = rsp_code;
- p_buf->msg.hdr.subunit_type = AVRC_SUB_PANEL;
- p_buf->msg.hdr.subunit_id = 0;
- if (company_id)
- p_buf->msg.company_id = company_id;
- else
- p_buf->msg.company_id = p_bta_av_cfg->company_id;
- p_buf->label = label;
- p_buf->msg.vendor_len = len;
- if (p_data == NULL) {
- p_buf->msg.p_vendor_data = NULL;
- } else {
- p_buf->msg.p_vendor_data = (uint8_t*)(p_buf + 1);
- memcpy(p_buf->msg.p_vendor_data, p_data, len);
- }
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvOpenRc
- *
- * Description Open an AVRCP connection toward the device with the
- * specified handle
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvOpenRc(tBTA_AV_HNDL handle) {
- tBTA_AV_API_OPEN_RC* p_buf =
- (tBTA_AV_API_OPEN_RC*)osi_malloc(sizeof(tBTA_AV_API_OPEN_RC));
-
- p_buf->hdr.event = BTA_AV_API_RC_OPEN_EVT;
- p_buf->hdr.layer_specific = handle;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvCloseRc
- *
- * Description Close an AVRCP connection
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvCloseRc(uint8_t rc_handle) {
- tBTA_AV_API_CLOSE_RC* p_buf =
- (tBTA_AV_API_CLOSE_RC*)osi_malloc(sizeof(tBTA_AV_API_CLOSE_RC));
-
- p_buf->hdr.event = BTA_AV_API_RC_CLOSE_EVT;
- p_buf->hdr.layer_specific = rc_handle;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvMetaRsp
- *
- * Description Send a Metadata/Advanced Control response. The message
- * contained in p_pkt can be composed with AVRC utility
- * functions.
- * This function can only be used if AV is enabled with feature
- * BTA_AV_FEAT_METADATA.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvMetaRsp(uint8_t rc_handle, uint8_t label, tBTA_AV_CODE rsp_code,
- BT_HDR* p_pkt) {
- tBTA_AV_API_META_RSP* p_buf =
- (tBTA_AV_API_META_RSP*)osi_malloc(sizeof(tBTA_AV_API_META_RSP));
-
- p_buf->hdr.event = BTA_AV_API_META_RSP_EVT;
- p_buf->hdr.layer_specific = rc_handle;
- p_buf->rsp_code = rsp_code;
- p_buf->p_pkt = p_pkt;
- p_buf->is_rsp = true;
- p_buf->label = label;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_AvMetaCmd
- *
- * Description Send a Metadata/Advanced Control command. The message
-*contained
- * in p_pkt can be composed with AVRC utility functions.
- * This function can only be used if AV is enabled with feature
- * BTA_AV_FEAT_METADATA.
- * This message is sent only when the peer supports the TG
-*role.
-*8 The only command makes sense right now is the absolute
-*volume command.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_AvMetaCmd(uint8_t rc_handle, uint8_t label, tBTA_AV_CMD cmd_code,
- BT_HDR* p_pkt) {
- tBTA_AV_API_META_RSP* p_buf =
- (tBTA_AV_API_META_RSP*)osi_malloc(sizeof(tBTA_AV_API_META_RSP));
-
- p_buf->hdr.event = BTA_AV_API_META_RSP_EVT;
- p_buf->hdr.layer_specific = rc_handle;
- p_buf->p_pkt = p_pkt;
- p_buf->rsp_code = cmd_code;
- p_buf->is_rsp = false;
- p_buf->label = label;
-
- bta_sys_sendmsg(p_buf);
-}
diff --git a/bta/av/bta_av_cfg.cc b/bta/av/bta_av_cfg.cc
deleted file mode 100644
index d2a7d8a..0000000
--- a/bta/av/bta_av_cfg.cc
+++ /dev/null
@@ -1,265 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2005-2016 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains compile-time configurable constants for advanced
- * audio/video
- *
- ******************************************************************************/
-
-#include <cstdint>
-
-#include "bt_target.h" // Must be first to define build configuration
-
-#include "bta/include/bta_av_api.h"
-#include "stack/include/avrc_api.h"
-
-#ifndef BTA_AV_RC_COMP_ID
-#define BTA_AV_RC_COMP_ID AVRC_CO_GOOGLE
-#endif
-
-#ifndef BTA_AV_RC_PASS_RSP_CODE
-#define BTA_AV_RC_PASS_RSP_CODE AVRC_RSP_NOT_IMPL
-#endif
-
-const uint32_t bta_av_meta_caps_co_ids[] = {AVRC_CO_METADATA, AVRC_CO_BROADCOM};
-
-/* AVRCP supported categories */
-#define BTA_AV_RC_SUPF_CT (AVRC_SUPF_CT_CAT2)
-#define BTA_AVK_RC_SUPF_CT (AVRC_SUPF_CT_CAT1 | \
- AVRC_SUPF_CT_BROWSE | \
- AVRC_SUPF_CT_COVER_ART_GET_IMAGE_PROP | \
- AVRC_SUPF_CT_COVER_ART_GET_IMAGE)
-#define BTA_AVK_RC_SUPF_TG (AVRC_SUPF_TG_CAT2)
-
-/* AVRCP Controller and Targer default name */
-#ifndef BTA_AV_RC_CT_NAME
-#define BTA_AV_RC_CT_NAME "AVRC Controller"
-#endif
-
-#ifndef BTA_AV_RC_TG_NAME
-#define BTA_AV_RC_TG_NAME "AVRC Target"
-#endif
-
-/* Added to modify
- * 1. flush timeout
- * 2. Remove Group navigation support in SupportedFeatures
- * 3. GetCapabilities supported event_ids list
- * 4. GetCapabilities supported event_ids count
-*/
-
-/* Note: Android doesnt support AVRC_SUPF_TG_GROUP_NAVI */
-/* Note: if AVRC_SUPF_TG_GROUP_NAVI is set, bta_av_cfg.avrc_group should be true
- */
-#ifndef BTA_AV_RC_SUPF_TG
-#define BTA_AV_RC_SUPF_TG \
- (AVRC_SUPF_TG_CAT1 | AVRC_SUPF_TG_MULTI_PLAYER | \
- AVRC_SUPF_TG_BROWSE) /* TODO: | AVRC_SUPF_TG_APP_SETTINGS) */
-#endif
-
-/*
- * If the number of event IDs is changed in this array, BTA_AV_NUM_RC_EVT_IDS
- * also needs to be changed.
- */
-const uint8_t bta_av_meta_caps_evt_ids[] = {
- AVRC_EVT_PLAY_STATUS_CHANGE, AVRC_EVT_TRACK_CHANGE,
- AVRC_EVT_PLAY_POS_CHANGED, AVRC_EVT_AVAL_PLAYERS_CHANGE,
- AVRC_EVT_ADDR_PLAYER_CHANGE, AVRC_EVT_UIDS_CHANGE,
- AVRC_EVT_NOW_PLAYING_CHANGE,
- /* TODO: Add support for these events
- AVRC_EVT_APP_SETTING_CHANGE,
- */
-};
-
-#ifndef BTA_AV_NUM_RC_EVT_IDS
-#define BTA_AV_NUM_RC_EVT_IDS \
- (sizeof(bta_av_meta_caps_evt_ids) / sizeof(bta_av_meta_caps_evt_ids[0]))
-#endif /* BTA_AV_NUM_RC_EVT_IDS */
-
-const uint8_t bta_avk_meta_caps_evt_ids[] = {
-#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
- AVRC_EVT_VOLUME_CHANGE,
-#endif
-};
-
-#ifndef BTA_AVK_NUM_RC_EVT_IDS
-#define BTA_AVK_NUM_RC_EVT_IDS \
- (sizeof(bta_avk_meta_caps_evt_ids) / sizeof(bta_avk_meta_caps_evt_ids[0]))
-#endif /* BTA_AVK_NUM_RC_EVT_IDS */
-
-// These are the only events used with AVRCP1.3
-const uint8_t bta_av_meta_caps_evt_ids_avrcp13[] = {
- AVRC_EVT_PLAY_STATUS_CHANGE, AVRC_EVT_TRACK_CHANGE,
- AVRC_EVT_PLAY_POS_CHANGED,
-};
-
-#ifndef BTA_AV_NUM_RC_EVT_IDS_AVRCP13
-#define BTA_AV_NUM_RC_EVT_IDS_AVRCP13 \
- (sizeof(bta_av_meta_caps_evt_ids_avrcp13) / \
- sizeof(bta_av_meta_caps_evt_ids_avrcp13[0]))
-#endif /* BTA_AVK_NUM_RC_EVT_IDS_AVRCP13 */
-
-/* This configuration to be used when we are Src + TG + CT( only for abs vol) */
-extern const tBTA_AV_CFG bta_av_cfg = {
- BTA_AV_RC_COMP_ID, /* AVRCP Company ID */
- BTA_AV_RC_SUPF_CT, /* AVRCP controller categories */
- BTA_AV_RC_SUPF_TG, /* AVRCP target categories */
- 6, /* AVDTP audio channel max data queue size */
- false, /* true, to accept AVRC 1.3 group nevigation command */
- 2, /* company id count in p_meta_co_ids */
- BTA_AV_NUM_RC_EVT_IDS, /* event id count in p_meta_evt_ids */
- BTA_AV_RC_PASS_RSP_CODE, /* the default response code for pass
- through commands */
- bta_av_meta_caps_co_ids, /* the metadata Get Capabilities response
- for company id */
- bta_av_meta_caps_evt_ids, /* the the metadata Get Capabilities
- response for event id */
- BTA_AV_RC_CT_NAME, /* Default AVRCP controller name */
- BTA_AV_RC_TG_NAME /* Default AVRCP target name */
-};
-
-/* This configuration to be used when we are Sink + CT + TG( only for abs vol)
- */
-extern const tBTA_AV_CFG bta_avk_cfg = {
- AVRC_CO_METADATA, /* AVRCP Company ID */
- BTA_AVK_RC_SUPF_CT, /* AVRCP controller categories */
- BTA_AVK_RC_SUPF_TG, /* AVRCP target categories */
- 6, /* AVDTP audio channel max data queue size */
- false, /* true, to accept AVRC 1.3 group nevigation command */
- 2, /* company id count in p_meta_co_ids */
- BTA_AVK_NUM_RC_EVT_IDS, /* event id count in p_meta_evt_ids */
- BTA_AV_RC_PASS_RSP_CODE, /* the default response code for pass
- through commands */
- bta_av_meta_caps_co_ids, /* the metadata Get Capabilities response
- for company id */
- bta_avk_meta_caps_evt_ids, /* the the metadata Get Capabilities
- response for event id */
- {0}, /* Default AVRCP controller name */
- {0}, /* Default AVRCP target name */
-};
-
-/* This configuration to be used when we are using AVRCP1.3 */
-extern const tBTA_AV_CFG bta_av_cfg_compatibility = {
- BTA_AV_RC_COMP_ID, /* AVRCP Company ID */
- BTA_AV_RC_SUPF_CT, /* AVRCP controller categories */
- AVRC_SUPF_TG_CAT1, /* Only support CAT1 for AVRCP1.3 */
- 6, /* AVDTP audio channel max data queue size */
- false, /* true, to accept AVRC 1.3 group nevigation command */
- 2, /* company id count in p_meta_co_ids */
- BTA_AV_NUM_RC_EVT_IDS_AVRCP13, /* event id count for AVRCP1.3 */
- BTA_AV_RC_PASS_RSP_CODE, /* the default response code for pass
- through commands */
- bta_av_meta_caps_co_ids, /* the metadata Get Capabilities response
- for company id */
- bta_av_meta_caps_evt_ids_avrcp13, /* the the metadata Get Capabilities
- response for event id, compatible
- with AVRCP1.3 */
- BTA_AV_RC_CT_NAME, /* Default AVRCP controller name */
- BTA_AV_RC_TG_NAME /* Default AVRCP target name */
-};
-
-const tBTA_AV_CFG* p_bta_av_cfg = NULL;
-
-const uint16_t bta_av_rc_id[] = {
- 0x0000, /* bit mask: 0=SELECT, 1=UP, 2=DOWN, 3=LEFT,
- 4=RIGHT, 5=RIGHT_UP, 6=RIGHT_DOWN, 7=LEFT_UP,
- 8=LEFT_DOWN, 9=ROOT_MENU, 10=SETUP_MENU, 11=CONT_MENU,
- 12=FAV_MENU, 13=EXIT */
-
- 0, /* not used */
-
- 0x0000, /* bit mask: 0=0, 1=1, 2=2, 3=3,
- 4=4, 5=5, 6=6, 7=7,
- 8=8, 9=9, 10=DOT, 11=ENTER,
- 12=CLEAR */
-
- 0x0000, /* bit mask: 0=CHAN_UP, 1=CHAN_DOWN, 2=PREV_CHAN, 3=SOUND_SEL,
- 4=INPUT_SEL, 5=DISP_INFO, 6=HELP, 7=PAGE_UP,
- 8=PAGE_DOWN */
-
-/* btui_app provides an example of how to leave the decision of rejecting a
- command or not
- * based on which media player is currently addressed (this is only applicable
- for AVRCP 1.4 or later)
- * If the decision is per player for a particular rc_id, the related bit is
- clear (not set)
- * bit mask: 0=POWER, 1=VOL_UP, 2=VOL_DOWN, 3=MUTE, 4=PLAY, 5=STOP,
- 6=PAUSE, 7=RECORD, 8=REWIND, 9=FAST_FOR, 10=EJECT, 11=FORWARD,
- 12=BACKWARD */
-#if (BTA_AV_RC_PASS_RSP_CODE == AVRC_RSP_INTERIM)
- 0x0070, /* PLAY | STOP | PAUSE */
-#else /* BTA_AV_RC_PASS_RSP_CODE != AVRC_RSP_INTERIM */
- 0x1b7E, /* PLAY | STOP | PAUSE | FF | RW | VOL_UP | VOL_DOWN | MUTE | FW |
- BACK */
-#endif /* BTA_AV_RC_PASS_RSP_CODE */
-
- 0x0000, /* bit mask: 0=ANGLE, 1=SUBPICT */
-
- 0, /* not used */
-
- 0x0000 /* bit mask: 0=not used, 1=F1, 2=F2, 3=F3,
- 4=F4, 5=F5 */
-};
-
-#if (BTA_AV_RC_PASS_RSP_CODE == AVRC_RSP_INTERIM)
-const uint16_t bta_av_rc_id_ac[] = {
- 0x0000, /* bit mask: 0=SELECT, 1=UP, 2=DOWN, 3=LEFT,
- 4=RIGHT, 5=RIGHT_UP, 6=RIGHT_DOWN,
- 7=LEFT_UP,
- 8=LEFT_DOWN, 9=ROOT_MENU, 10=SETUP_MENU,
- 11=CONT_MENU,
- 12=FAV_MENU, 13=EXIT */
-
- 0, /* not used */
-
- 0x0000, /* bit mask: 0=0, 1=1, 2=2, 3=3,
- 4=4, 5=5, 6=6, 7=7,
- 8=8, 9=9, 10=DOT, 11=ENTER,
- 12=CLEAR */
-
- 0x0000, /* bit mask: 0=CHAN_UP, 1=CHAN_DOWN, 2=PREV_CHAN,
- 3=SOUND_SEL,
- 4=INPUT_SEL, 5=DISP_INFO, 6=HELP,
- 7=PAGE_UP,
- 8=PAGE_DOWN */
-
- /* btui_app provides an example of how to leave the decision of
- * rejecting a command or not
- * based on which media player is currently addressed (this is
- * only applicable for AVRCP 1.4 or later)
- * If the decision is per player for a particular rc_id, the
- * related bit is set */
- 0x1800, /* bit mask: 0=POWER, 1=VOL_UP, 2=VOL_DOWN, 3=MUTE,
- 4=PLAY, 5=STOP, 6=PAUSE, 7=RECORD,
- 8=REWIND, 9=FAST_FOR, 10=EJECT, 11=FORWARD,
- 12=BACKWARD */
-
- 0x0000, /* bit mask: 0=ANGLE, 1=SUBPICT */
-
- 0, /* not used */
-
- 0x0000 /* bit mask: 0=not used, 1=F1, 2=F2, 3=F3,
- 4=F4, 5=F5 */
-};
-uint16_t* p_bta_av_rc_id_ac = (uint16_t*)bta_av_rc_id_ac;
-#else
-uint16_t* p_bta_av_rc_id_ac = NULL;
-#endif
-
-uint16_t* p_bta_av_rc_id = (uint16_t*)bta_av_rc_id;
diff --git a/bta/av/bta_av_ci.cc b/bta/av/bta_av_ci.cc
deleted file mode 100644
index bfa4574..0000000
--- a/bta/av/bta_av_ci.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2005-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the implementation file for advanced audio/video call-in
- * functions.
- *
- ******************************************************************************/
-
-#define LOG_TAG "bt_bta_av"
-
-#include "bta/av/bta_av_int.h"
-#include "osi/include/allocator.h"
-#include "osi/include/log.h"
-#include "stack/include/bt_hdr.h"
-
-/*******************************************************************************
- *
- * Function bta_av_ci_src_data_ready
- *
- * Description This function sends an event to the AV indicating that
- * the phone has audio stream data ready to send and AV
- * should call bta_av_co_audio_source_data_path().
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_ci_src_data_ready(tBTA_AV_CHNL chnl) {
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
-
- p_buf->layer_specific = chnl;
- p_buf->event = BTA_AV_CI_SRC_DATA_READY_EVT;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_ci_setconfig
- *
- * Description This function must be called in response to function
- * bta_av_co_audio_setconfig().
- * Parameter err_code is set to an AVDTP status value;
- * AVDT_SUCCESS if the codec configuration is ok,
- * otherwise error.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_ci_setconfig(tBTA_AV_HNDL bta_av_handle, uint8_t err_code,
- uint8_t category, uint8_t num_seid, uint8_t* p_seid,
- bool recfg_needed, uint8_t avdt_handle) {
- LOG_INFO(
- "%s: bta_av_handle=0x%x err_code=%d category=%d "
- "num_seid=%d recfg_needed=%s avdt_handle=%d",
- __func__, bta_av_handle, err_code, category, num_seid,
- recfg_needed ? "true" : "false", avdt_handle);
-
- tBTA_AV_CI_SETCONFIG* p_buf =
- (tBTA_AV_CI_SETCONFIG*)osi_malloc(sizeof(tBTA_AV_CI_SETCONFIG));
-
- p_buf->hdr.layer_specific = bta_av_handle;
- p_buf->hdr.event = (err_code == A2DP_SUCCESS) ? BTA_AV_CI_SETCONFIG_OK_EVT
- : BTA_AV_CI_SETCONFIG_FAIL_EVT;
- p_buf->err_code = err_code;
- p_buf->category = category;
- p_buf->recfg_needed = recfg_needed;
- p_buf->num_seid = num_seid;
- p_buf->avdt_handle = avdt_handle;
- if (p_seid && num_seid) {
- p_buf->p_seid = (uint8_t*)(p_buf + 1);
- memcpy(p_buf->p_seid, p_seid, num_seid);
- } else {
- p_buf->p_seid = NULL;
- p_buf->num_seid = 0;
- }
-
- bta_sys_sendmsg(p_buf);
-}
diff --git a/bta/av/bta_av_int.h b/bta/av/bta_av_int.h
deleted file mode 100644
index 9a65ec5..0000000
--- a/bta/av/bta_av_int.h
+++ /dev/null
@@ -1,811 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2004-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the private interface file for the BTA advanced audio/video.
- *
- ******************************************************************************/
-#ifndef BTA_AV_INT_H
-#define BTA_AV_INT_H
-
-#include <cstdint>
-#include <string>
-
-#include "bta/av/bta_av_int.h"
-#include "bta/include/bta_av_api.h"
-#include "bta/include/bta_av_co.h"
-#include "bta/sys/bta_sys.h"
-#include "osi/include/list.h"
-#include "stack/include/avdt_api.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/bt_types.h"
-#include "types/raw_address.h"
-
-#define CASE_RETURN_TEXT(code) \
- case code: \
- return #code
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-
-enum {
- /* these events are handled by the AV main state machine */
- BTA_AV_API_DISABLE_EVT = BTA_SYS_EVT_START(BTA_ID_AV),
- BTA_AV_API_REMOTE_CMD_EVT,
- BTA_AV_API_VENDOR_CMD_EVT,
- BTA_AV_API_VENDOR_RSP_EVT,
- BTA_AV_API_META_RSP_EVT,
- BTA_AV_API_RC_CLOSE_EVT,
- BTA_AV_AVRC_OPEN_EVT,
- BTA_AV_AVRC_MSG_EVT,
- BTA_AV_AVRC_NONE_EVT,
-
- /* these events are handled by the AV stream state machine */
- BTA_AV_API_OPEN_EVT,
- BTA_AV_API_CLOSE_EVT,
- BTA_AV_AP_START_EVT, /* the following 2 events must be in the same order as
- the *API_*EVT */
- BTA_AV_AP_STOP_EVT,
- BTA_AV_API_RECONFIG_EVT,
- BTA_AV_API_PROTECT_REQ_EVT,
- BTA_AV_API_PROTECT_RSP_EVT,
- BTA_AV_API_RC_OPEN_EVT,
- BTA_AV_SRC_DATA_READY_EVT,
- BTA_AV_CI_SETCONFIG_OK_EVT,
- BTA_AV_CI_SETCONFIG_FAIL_EVT,
- BTA_AV_SDP_DISC_OK_EVT,
- BTA_AV_SDP_DISC_FAIL_EVT,
- BTA_AV_STR_DISC_OK_EVT,
- BTA_AV_STR_DISC_FAIL_EVT,
- BTA_AV_STR_GETCAP_OK_EVT,
- BTA_AV_STR_GETCAP_FAIL_EVT,
- BTA_AV_STR_OPEN_OK_EVT,
- BTA_AV_STR_OPEN_FAIL_EVT,
- BTA_AV_STR_START_OK_EVT,
- BTA_AV_STR_START_FAIL_EVT,
- BTA_AV_STR_CLOSE_EVT,
- BTA_AV_STR_CONFIG_IND_EVT,
- BTA_AV_STR_SECURITY_IND_EVT,
- BTA_AV_STR_SECURITY_CFM_EVT,
- BTA_AV_STR_WRITE_CFM_EVT,
- BTA_AV_STR_SUSPEND_CFM_EVT,
- BTA_AV_STR_RECONFIG_CFM_EVT,
- BTA_AV_AVRC_TIMER_EVT,
- BTA_AV_AVDT_CONNECT_EVT,
- BTA_AV_AVDT_DISCONNECT_EVT,
- BTA_AV_ROLE_CHANGE_EVT,
- BTA_AV_AVDT_DELAY_RPT_EVT,
- BTA_AV_AVDT_DELAY_RPT_CFM_EVT,
- BTA_AV_ACP_CONNECT_EVT,
- BTA_AV_API_OFFLOAD_START_EVT,
- BTA_AV_API_OFFLOAD_START_RSP_EVT,
-
- /* these events are handled outside of the state machine */
- BTA_AV_API_ENABLE_EVT,
- BTA_AV_API_REGISTER_EVT,
- BTA_AV_API_DEREGISTER_EVT,
- BTA_AV_API_DISCONNECT_EVT,
- BTA_AV_CI_SRC_DATA_READY_EVT,
- BTA_AV_SIG_CHG_EVT,
- BTA_AV_SIGNALLING_TIMER_EVT,
- BTA_AV_SDP_AVRC_DISC_EVT,
- BTA_AV_AVRC_CLOSE_EVT,
- BTA_AV_AVRC_BROWSE_OPEN_EVT,
- BTA_AV_AVRC_BROWSE_CLOSE_EVT,
- BTA_AV_CONN_CHG_EVT,
- BTA_AV_DEREG_COMP_EVT,
- BTA_AV_AVDT_RPT_CONN_EVT,
- BTA_AV_API_START_EVT, /* the following 2 events must be in the same order as
- the *AP_*EVT */
- BTA_AV_API_STOP_EVT
-};
-
-/* events for AV control block state machine */
-#define BTA_AV_FIRST_SM_EVT BTA_AV_API_DISABLE_EVT
-#define BTA_AV_LAST_SM_EVT BTA_AV_AVRC_NONE_EVT
-
-/* events for AV stream control block state machine */
-#define BTA_AV_FIRST_SSM_EVT BTA_AV_API_OPEN_EVT
-
-/* events that do not go through state machine */
-#define BTA_AV_FIRST_NSM_EVT BTA_AV_API_ENABLE_EVT
-#define BTA_AV_LAST_NSM_EVT BTA_AV_API_STOP_EVT
-
-/* API events passed to both SSMs (by bta_av_api_to_ssm) */
-#define BTA_AV_FIRST_A2S_API_EVT BTA_AV_API_START_EVT
-#define BTA_AV_FIRST_A2S_SSM_EVT BTA_AV_AP_START_EVT
-
-#define BTA_AV_LAST_EVT BTA_AV_API_STOP_EVT
-
-/* maximum number of SEPS in stream discovery results */
-#define BTA_AV_NUM_SEPS 32
-
-/* initialization value for AVRC handle */
-#define BTA_AV_RC_HANDLE_NONE 0xFF
-
-/* size of database for service discovery */
-#define BTA_AV_DISC_BUF_SIZE 2000
-
-/* maximum length of AVDTP security data */
-#define BTA_AV_SECURITY_MAX_LEN 400
-
-/* check number of buffers queued at L2CAP when this amount of buffers are
- * queued to L2CAP */
-#define BTA_AV_QUEUE_DATA_CHK_NUM L2CAP_HIGH_PRI_MIN_XMIT_QUOTA
-
-/* the number of ACL links with AVDT */
-#define BTA_AV_NUM_LINKS AVDT_NUM_LINKS
-
-#define BTA_AV_BE_STREAM_TO_CO_ID(u32, p) \
- { \
- (u32) = (((uint32_t)(*((p) + 2))) + (((uint32_t)(*((p) + 1))) << 8) + \
- (((uint32_t)(*(p))) << 16)); \
- (p) += 3; \
- }
-
-/*****************************************************************************
- * Data types
- ****************************************************************************/
-
-/* function types for call-out functions */
-typedef bool (*tBTA_AV_CO_INIT)(btav_a2dp_codec_index_t codec_index,
- AvdtpSepConfig* p_cfg);
-typedef void (*tBTA_AV_CO_DISC_RES)(tBTA_AV_HNDL bta_av_handle,
- const RawAddress& peer_addr,
- uint8_t num_seps, uint8_t num_snk,
- uint8_t num_src, uint16_t uuid_local);
-typedef tA2DP_STATUS (*tBTA_AV_CO_GETCFG)(tBTA_AV_HNDL bta_av_handle,
- const RawAddress& peer_addr,
- uint8_t* p_codec_info,
- uint8_t* p_sep_info_idx, uint8_t seid,
- uint8_t* p_num_protect,
- uint8_t* p_protect_info);
-typedef void (*tBTA_AV_CO_SETCFG)(tBTA_AV_HNDL bta_av_handle,
- const RawAddress& peer_addr,
- const uint8_t* p_codec_info, uint8_t seid,
- uint8_t num_protect,
- const uint8_t* p_protect_info,
- uint8_t t_local_sep, uint8_t avdt_handle);
-typedef void (*tBTA_AV_CO_OPEN)(tBTA_AV_HNDL bta_av_handle,
- const RawAddress& peer_addr, uint16_t mtu);
-typedef void (*tBTA_AV_CO_CLOSE)(tBTA_AV_HNDL bta_av_handle,
- const RawAddress& peer_addr);
-typedef void (*tBTA_AV_CO_START)(tBTA_AV_HNDL bta_av_handle,
- const RawAddress& peer_addr,
- const uint8_t* p_codec_info,
- bool* p_no_rtp_header);
-typedef void (*tBTA_AV_CO_STOP)(tBTA_AV_HNDL bta_av_handle,
- const RawAddress& peer_addr);
-typedef BT_HDR* (*tBTA_AV_CO_DATAPATH)(const uint8_t* p_codec_info,
- uint32_t* p_timestamp);
-typedef void (*tBTA_AV_CO_DELAY)(tBTA_AV_HNDL bta_av_handle,
- const RawAddress& peer_addr, uint16_t delay);
-typedef void (*tBTA_AV_CO_UPDATE_MTU)(tBTA_AV_HNDL bta_av_handle,
- const RawAddress& peer_addr,
- uint16_t mtu);
-
-typedef btav_a2dp_scmst_info_t (*tBTA_AV_CO_GET_SCMST_INFO)(
- const RawAddress& peer_addr);
-
-/* the call-out functions for one stream */
-typedef struct {
- tBTA_AV_CO_INIT init;
- tBTA_AV_CO_DISC_RES disc_res;
- tBTA_AV_CO_GETCFG getcfg;
- tBTA_AV_CO_SETCFG setcfg;
- tBTA_AV_CO_OPEN open;
- tBTA_AV_CO_CLOSE close;
- tBTA_AV_CO_START start;
- tBTA_AV_CO_STOP stop;
- tBTA_AV_CO_DATAPATH data;
- tBTA_AV_CO_DELAY delay;
- tBTA_AV_CO_UPDATE_MTU update_mtu;
- tBTA_AV_CO_GET_SCMST_INFO get_scmst_info;
-} tBTA_AV_CO_FUNCTS;
-
-/* data type for BTA_AV_API_ENABLE_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- tBTA_AV_CBACK* p_cback;
- tBTA_AV_FEAT features;
-} tBTA_AV_API_ENABLE;
-
-/* data type for BTA_AV_API_REGISTER_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- char p_service_name[BTA_SERVICE_NAME_LEN + 1];
- uint8_t app_id;
- tBTA_AV_SINK_DATA_CBACK* p_app_sink_data_cback;
- uint16_t service_uuid;
-} tBTA_AV_API_REG;
-
-typedef enum : uint8_t {
- BTA_AV_RS_NONE, /* straight API call */
- BTA_AV_RS_OK, /* the role switch result - successful */
- BTA_AV_RS_FAIL, /* the role switch result - failed */
- BTA_AV_RS_DONE /* the role switch is done - continue */
-} tBTA_AV_RS_RES;
-
-inline std::string bta_av_role_switch_result_text(
- const tBTA_AV_RS_RES& result) {
- switch (result) {
- CASE_RETURN_TEXT(BTA_AV_RS_NONE);
- CASE_RETURN_TEXT(BTA_AV_RS_OK);
- CASE_RETURN_TEXT(BTA_AV_RS_FAIL);
- CASE_RETURN_TEXT(BTA_AV_RS_DONE);
- default:
- return std::string("UNKNOWN");
- }
-}
-
-/* data type for BTA_AV_API_OPEN_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- RawAddress bd_addr;
- bool use_rc;
- tBTA_AV_RS_RES switch_res;
- uint16_t uuid; /* uuid of initiator */
-} tBTA_AV_API_OPEN;
-
-/* data type for BTA_AV_API_STOP_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- bool suspend;
- bool flush;
- bool reconfig_stop; // True if the stream is stopped for reconfiguration
-} tBTA_AV_API_STOP;
-
-/* data type for BTA_AV_API_DISCONNECT_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
-} tBTA_AV_API_DISCNT;
-
-/* data type for BTA_AV_API_PROTECT_REQ_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- uint8_t* p_data;
- uint16_t len;
-} tBTA_AV_API_PROTECT_REQ;
-
-/* data type for BTA_AV_API_PROTECT_RSP_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- uint8_t* p_data;
- uint16_t len;
- uint8_t error_code;
-} tBTA_AV_API_PROTECT_RSP;
-
-/* data type for BTA_AV_API_REMOTE_CMD_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- tAVRC_MSG_PASS msg;
- uint8_t label;
-} tBTA_AV_API_REMOTE_CMD;
-
-/* data type for BTA_AV_API_VENDOR_CMD_EVT and RSP */
-typedef struct {
- BT_HDR_RIGID hdr;
- tAVRC_MSG_VENDOR msg;
- uint8_t label;
-} tBTA_AV_API_VENDOR;
-
-/* data type for BTA_AV_API_RC_OPEN_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
-} tBTA_AV_API_OPEN_RC;
-
-/* data type for BTA_AV_API_RC_CLOSE_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
-} tBTA_AV_API_CLOSE_RC;
-
-/* data type for BTA_AV_API_META_RSP_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- bool is_rsp;
- uint8_t label;
- tBTA_AV_CODE rsp_code;
- BT_HDR* p_pkt;
-} tBTA_AV_API_META_RSP;
-
-/* data type for BTA_AV_API_RECONFIG_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- uint8_t codec_info[AVDT_CODEC_SIZE]; /* codec configuration */
- uint8_t* p_protect_info;
- uint8_t num_protect;
- bool suspend;
- uint8_t sep_info_idx;
-} tBTA_AV_API_RCFG;
-
-/* data type for BTA_AV_CI_SETCONFIG_OK_EVT and BTA_AV_CI_SETCONFIG_FAIL_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- tBTA_AV_HNDL hndl;
- uint8_t err_code;
- uint8_t category;
- uint8_t num_seid;
- uint8_t* p_seid;
- bool recfg_needed;
- uint8_t avdt_handle; /* local sep type for which this stream will be set up */
-} tBTA_AV_CI_SETCONFIG;
-
-/* data type for all stream events from AVDTP */
-typedef struct {
- BT_HDR_RIGID hdr;
- AvdtpSepConfig cfg; /* configuration/capabilities parameters */
- tAVDT_CTRL msg; /* AVDTP callback message parameters */
- RawAddress bd_addr; /* bd address */
- uint8_t scb_index;
- uint8_t handle;
- uint8_t avdt_event;
- bool initiator; /* true, if local device initiates the SUSPEND */
-} tBTA_AV_STR_MSG;
-
-/* data type for BTA_AV_AVRC_MSG_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- tAVRC_MSG msg;
- uint8_t handle;
- uint8_t label;
- uint8_t opcode;
-} tBTA_AV_RC_MSG;
-
-/* data type for BTA_AV_AVRC_OPEN_EVT, BTA_AV_AVRC_CLOSE_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- RawAddress peer_addr;
- uint8_t handle;
-} tBTA_AV_RC_CONN_CHG;
-
-/* data type for BTA_AV_CONN_CHG_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- RawAddress peer_addr;
- bool is_up;
-} tBTA_AV_CONN_CHG;
-
-/* data type for BTA_AV_ROLE_CHANGE_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- uint8_t new_role;
- uint8_t hci_status;
-} tBTA_AV_ROLE_RES;
-
-/* data type for BTA_AV_SDP_DISC_OK_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
-} tBTA_AV_SDP_RES;
-
-/* data type for BTA_AV_API_OFFLOAD_RSP_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- tBTA_AV_STATUS status;
-} tBTA_AV_API_STATUS_RSP;
-
-/* type for SEP control block */
-typedef struct {
- uint8_t av_handle; /* AVDTP handle */
- uint8_t tsep; /* SEP type of local SEP */
- uint8_t codec_info[AVDT_CODEC_SIZE]; /* Codec info */
- tBTA_AV_SINK_DATA_CBACK*
- p_app_sink_data_cback; /* Sink application callback for media packets */
-} tBTA_AV_SEP;
-
-enum : uint8_t {
- /* initiator/acceptor role for adaption */
- BTA_AV_ROLE_AD_INT = 0x00, /* initiator */
- BTA_AV_ROLE_AD_ACP = 0x01, /* acceptor */
-
- /* initiator/acceptor signaling roles */
- BTA_AV_ROLE_START_ACP = 0x00,
- BTA_AV_ROLE_START_INT = 0x10, /* do not change this value */
-
- BTA_AV_ROLE_SUSPEND = 0x20, /* suspending on start */
- BTA_AV_ROLE_SUSPEND_OPT = 0x40, /* Suspend on Start option is set */
-};
-typedef uint8_t tBTA_AV_ROLE;
-
-/* union of all event datatypes */
-union tBTA_AV_DATA {
- BT_HDR_RIGID hdr;
- tBTA_AV_API_ENABLE api_enable;
- tBTA_AV_API_REG api_reg;
- tBTA_AV_API_OPEN api_open;
- tBTA_AV_API_STOP api_stop;
- tBTA_AV_API_DISCNT api_discnt;
- tBTA_AV_API_PROTECT_REQ api_protect_req;
- tBTA_AV_API_PROTECT_RSP api_protect_rsp;
- tBTA_AV_API_REMOTE_CMD api_remote_cmd;
- tBTA_AV_API_VENDOR api_vendor;
- tBTA_AV_API_RCFG api_reconfig;
- tBTA_AV_CI_SETCONFIG ci_setconfig;
- tBTA_AV_STR_MSG str_msg;
- tBTA_AV_RC_MSG rc_msg;
- tBTA_AV_RC_CONN_CHG rc_conn_chg;
- tBTA_AV_CONN_CHG conn_chg;
- tBTA_AV_ROLE_RES role_res;
- tBTA_AV_SDP_RES sdp_res;
- tBTA_AV_API_META_RSP api_meta_rsp;
- tBTA_AV_API_STATUS_RSP api_status_rsp;
-};
-
-typedef union {
- tBTA_AV_API_OPEN open; /* used only before open and role switch
- is needed on another AV channel */
-} tBTA_AV_Q_INFO;
-
-#define BTA_AV_Q_TAG_OPEN 0x01 /* after API_OPEN, before STR_OPENED */
-#define BTA_AV_Q_TAG_START 0x02 /* before start sending media packets */
-#define BTA_AV_Q_TAG_STREAM 0x03 /* during streaming */
-
-#define BTA_AV_WAIT_ACP_CAPS_ON 0x01 /* retriving the peer capabilities */
-#define BTA_AV_WAIT_ACP_CAPS_STARTED \
- 0x02 /* started while retriving peer capabilities */
-#define BTA_AV_WAIT_ROLE_SW_RES_OPEN \
- 0x04 /* waiting for role switch result after API_OPEN, before STR_OPENED */
-#define BTA_AV_WAIT_ROLE_SW_RES_START \
- 0x08 /* waiting for role switch result before streaming */
-#define BTA_AV_WAIT_ROLE_SW_STARTED \
- 0x10 /* started while waiting for role switch result */
-#define BTA_AV_WAIT_ROLE_SW_RETRY 0x20 /* set when retry on timeout */
-#define BTA_AV_WAIT_CHECK_RC \
- 0x40 /* set when the timer is used by role switch */
-#define BTA_AV_WAIT_ROLE_SW_FAILED 0x80 /* role switch failed */
-
-#define BTA_AV_WAIT_ROLE_SW_BITS \
- (BTA_AV_WAIT_ROLE_SW_RES_OPEN | BTA_AV_WAIT_ROLE_SW_RES_START | \
- BTA_AV_WAIT_ROLE_SW_STARTED | BTA_AV_WAIT_ROLE_SW_RETRY)
-
-/* Bitmap for collision, coll_mask */
-#define BTA_AV_COLL_INC_TMR \
- 0x01 /* Timer is running for incoming L2C connection */
-#define BTA_AV_COLL_API_CALLED \
- 0x02 /* API open was called while incoming timer is running */
-
-/* type for AV stream control block */
-// TODO: This should be renamed and changed to a proper class
-struct tBTA_AV_SCB final {
- public:
- const tBTA_AV_CO_FUNCTS* p_cos; /* the associated callout functions */
- bool sdp_discovery_started; /* variable to determine whether SDP is started */
- tBTA_AV_SEP seps[BTAV_A2DP_CODEC_INDEX_MAX];
- AvdtpSepConfig peer_cap; /* buffer used for get capabilities */
- list_t* a2dp_list; /* used for audio channels only */
- tBTA_AV_Q_INFO q_info;
- tAVDT_SEP_INFO sep_info[BTA_AV_NUM_SEPS]; /* stream discovery results */
- AvdtpSepConfig cfg; /* local SEP configuration */
- alarm_t* avrc_ct_timer; /* delay timer for AVRC CT */
- alarm_t* link_signalling_timer;
- alarm_t*
- accept_signalling_timer; /* timer to monitor signalling when accepting */
- uint16_t l2c_cid; /* L2CAP channel ID */
- uint16_t stream_mtu; /* MTU of stream */
- uint8_t media_type; /* Media type: AVDT_MEDIA_TYPE_* */
- bool cong; /* true if AVDTP congested */
- tBTA_AV_STATUS open_status; /* open failure status */
- tBTA_AV_CHNL chnl; /* the channel: audio/video */
- tBTA_AV_HNDL hndl; /* the handle: ((hdi + 1)|chnl) */
- uint16_t cur_psc_mask; /* Protocol service capabilities mask for current
- connection */
- uint8_t avdt_handle; /* AVDTP handle */
- uint8_t hdi; /* the index to SCB[] */
- uint8_t num_seps; /* number of seps returned by stream discovery */
- uint8_t num_disc_snks; /* number of discovered snks */
- uint8_t num_disc_srcs; /* number of discovered srcs */
- uint8_t sep_info_idx; /* current index into sep_info */
- uint8_t sep_idx; /* current index into local seps[] */
- uint8_t rcfg_idx; /* reconfig requested index into sep_info */
- uint8_t state; /* state machine state */
- uint8_t avdt_label; /* AVDTP label */
- uint8_t app_id; /* application id */
- uint8_t num_recfg; /* number of reconfigure sent */
- uint8_t role;
- uint8_t l2c_bufs; /* the number of buffers queued to L2CAP */
- uint8_t rc_handle; /* connected AVRCP handle */
- bool use_rc; /* true if AVRCP is allowed */
- bool started; /* true if stream started */
- bool use_rtp_header_marker_bit; /* true if the encoded data packets have RTP
- * headers, and the Marker bit in the header
- * is set according to RFC 6416 */
- uint8_t
- co_started; /* non-zero, if stream started from call-out perspective */
- bool recfg_sup; /* true if the first attempt to reconfigure the stream was
- successfull, else False if command fails */
- bool suspend_sup; /* true if Suspend stream is supported, else false if
- suspend command fails */
- bool deregistering; /* true if deregistering */
- bool sco_suspend; /* true if SUSPEND is issued automatically for SCO */
- uint8_t coll_mask; /* Mask to check incoming and outgoing collision */
- tBTA_AV_API_OPEN open_api; /* Saved OPEN api message */
- uint8_t wait; /* set 0x1, when getting Caps as ACP, set 0x2, when started */
- uint8_t q_tag; /* identify the associated q_info union member */
- bool no_rtp_header; /* true if add no RTP header */
- uint16_t uuid_int; /*intended UUID of Initiator to connect to */
-
- /**
- * Called to setup the state when connected to a peer.
- *
- * @param peer_address the peer address
- */
- void OnConnected(const RawAddress& peer_address);
-
- /**
- * Called to clear the state when disconnected from a peer.
- *
- */
- void OnDisconnected();
-
- /**
- * Get the peer address.
- */
- const RawAddress& PeerAddress() const { return peer_address_; }
-
- /**
- * Get the AVDTP version of the peer device.
- */
- uint16_t AvdtpVersion() const { return avdtp_version_; }
-
- /**
- * Set the AVDTP version of the peer device.
- *
- * @param avdtp_version the AVDTP version to use
- */
- void SetAvdtpVersion(uint16_t avdtp_version);
-
- /**
- * Check whether the entry is assigned and currenty used.
- *
- * @return true if the entry is assigned and currently used
- */
- bool IsAssigned() const { return !peer_address_.IsEmpty(); }
-
- private:
- RawAddress peer_address_; // Peer address
- uint16_t avdtp_version_; // The AVDTP version of the peer device
-};
-
-#define BTA_AV_RC_ROLE_MASK 0x10
-#define BTA_AV_RC_ROLE_INT 0x00
-#define BTA_AV_RC_ROLE_ACP 0x10
-
-#define BTA_AV_RC_CONN_MASK 0x20
-
-/* type for AV RCP control block */
-/* index to this control block is the rc handle */
-typedef struct {
- uint8_t status;
- uint8_t handle;
- uint8_t shdl; /* stream handle (hdi + 1) */
- uint8_t lidx; /* (index+1) to LCB */
- tBTA_AV_FEAT peer_features; /* peer features mask */
- uint16_t cover_art_psm; /* BIP PSM for cover art feature */
-} tBTA_AV_RCB;
-#define BTA_AV_NUM_RCB (BTA_AV_NUM_STRS + 2)
-
-enum { BTA_AV_LCB_FREE, BTA_AV_LCB_FIND };
-
-/* type for AV ACL Link control block */
-typedef struct {
- RawAddress addr; /* peer BD address */
- uint8_t conn_msk; /* handle mask of connected stream handle */
- uint8_t lidx; /* index + 1 */
-} tBTA_AV_LCB;
-
-/* type for stream state machine action functions */
-typedef void (*tBTA_AV_SACT)(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-
-/* type for AV control block */
-typedef struct {
- tBTA_AV_SCB* p_scb[BTA_AV_NUM_STRS]; /* stream control block */
- tSDP_DISCOVERY_DB* p_disc_db; /* pointer to discovery database */
- tBTA_AV_CBACK* p_cback; /* application callback function */
- tBTA_AV_RCB rcb[BTA_AV_NUM_RCB]; /* RCB control block */
- tBTA_AV_LCB lcb[BTA_AV_NUM_LINKS + 1]; /* link control block */
- uint32_t sdp_a2dp_handle; /* SDP record handle for audio src */
- uint32_t sdp_a2dp_snk_handle; /* SDP record handle for audio snk */
- tBTA_AV_FEAT features; /* features mask */
- tBTA_SEC sec_mask; /* security mask */
- tBTA_AV_HNDL handle; /* the handle for SDP activity */
- bool disabling; /* true if api disabled called */
- uint8_t enabling_attempts; // counter to wait for previous disabling
- uint8_t
- disc; /* (hdi+1) or (rc_handle|BTA_AV_CHNL_MSK) if p_disc_db is in use */
- uint8_t state; /* state machine state */
- uint8_t conn_audio; /* handle mask of connected audio channels */
- uint8_t conn_lcb; /* index mask of used LCBs */
- uint8_t audio_open_cnt; /* number of connected audio channels */
- uint8_t reg_audio; /* handle mask of registered audio channels */
- uint8_t rc_acp_handle;
- uint8_t rc_acp_idx; /* (index + 1) to RCB */
- uint8_t rs_idx; /* (index + 1) to SCB for the one waiting for RS on open */
- bool sco_occupied; /* true if SCO is being used or call is in progress */
- uint16_t offload_start_pending_acl_hdl;
- uint16_t offload_started_acl_hdl;
-} tBTA_AV_CB;
-
-// total attempts are half seconds
-constexpr uint32_t kEnablingAttemptsIntervalMs = 100;
-constexpr uint8_t kEnablingAttemptsCountMaximum = 5;
-
-// A2DP offload VSC parameters
-class tBT_A2DP_OFFLOAD {
- public:
- uint32_t codec_type; /* codec types ex: SBC/AAC/LDAC/APTx */
- uint16_t max_latency; /* maximum latency */
- std::array<uint8_t, 2> scms_t_enable; /* SCMS-T enable */
- uint32_t sample_rate; /* Sample rates ex: 44.1/48/88.2/96 Khz */
- uint8_t bits_per_sample; /* bits per sample ex: 16/24/32 */
- uint8_t ch_mode; /* None:0 Left:1 Right:2 */
- uint32_t encoded_audio_bitrate; /* encoder audio bitrates */
- uint16_t acl_hdl; /* connection handle */
- uint16_t l2c_rcid; /* l2cap channel id */
- uint16_t mtu; /* MTU size */
- uint8_t codec_info[32]; /* Codec specific information */
-};
-
-/* Vendor OFFLOAD VSC */
-#define HCI_VSQC_CONTROLLER_A2DP_OPCODE 0x000A
-
-#define VS_HCI_A2DP_OFFLOAD_START 0x01
-#define VS_HCI_A2DP_OFFLOAD_STOP 0x02
-/*****************************************************************************
- * Global data
- ****************************************************************************/
-
-/* control block declaration */
-extern tBTA_AV_CB bta_av_cb;
-
-/* config struct */
-extern const tBTA_AV_CFG* p_bta_av_cfg;
-extern const tBTA_AV_CFG bta_avk_cfg;
-extern const tBTA_AV_CFG bta_av_cfg;
-extern const tBTA_AV_CFG bta_av_cfg_compatibility;
-
-/* rc id config struct */
-extern uint16_t* p_bta_av_rc_id;
-extern uint16_t* p_bta_av_rc_id_ac;
-
-extern const tBTA_AV_CO_FUNCTS bta_av_a2dp_cos;
-extern void bta_av_sink_data_cback(uint8_t handle, BT_HDR* p_pkt,
- uint32_t time_stamp, uint8_t m_pt);
-
-/*****************************************************************************
- * Function prototypes
- ****************************************************************************/
-/* utility functions */
-extern tBTA_AV_SCB* bta_av_hndl_to_scb(uint16_t handle);
-tBTA_AV_SCB* bta_av_addr_to_scb(const RawAddress& bd_addr);
-extern bool bta_av_chk_start(tBTA_AV_SCB* p_scb);
-extern void bta_av_restore_switch(void);
-extern void bta_av_conn_cback(uint8_t handle, const RawAddress& bd_addr,
- uint8_t event, tAVDT_CTRL* p_data,
- uint8_t scb_index);
-extern uint8_t bta_av_rc_create(tBTA_AV_CB* p_cb, uint8_t role, uint8_t shdl,
- uint8_t lidx);
-extern void bta_av_stream_chg(tBTA_AV_SCB* p_scb, bool started);
-extern bool bta_av_is_scb_opening(tBTA_AV_SCB* p_scb);
-extern bool bta_av_is_scb_incoming(tBTA_AV_SCB* p_scb);
-extern void bta_av_set_scb_sst_init(tBTA_AV_SCB* p_scb);
-extern bool bta_av_is_scb_init(tBTA_AV_SCB* p_scb);
-extern void bta_av_set_scb_sst_incoming(tBTA_AV_SCB* p_scb);
-extern tBTA_AV_LCB* bta_av_find_lcb(const RawAddress& addr, uint8_t op);
-extern const char* bta_av_sst_code(uint8_t state);
-extern void bta_av_free_scb(tBTA_AV_SCB* p_scb);
-
-/* main functions */
-extern void bta_av_api_deregister(tBTA_AV_DATA* p_data);
-extern void bta_av_dup_audio_buf(tBTA_AV_SCB* p_scb, BT_HDR* p_buf);
-extern void bta_av_sm_execute(tBTA_AV_CB* p_cb, uint16_t event,
- tBTA_AV_DATA* p_data);
-extern void bta_av_ssm_execute(tBTA_AV_SCB* p_scb, uint16_t event,
- tBTA_AV_DATA* p_data);
-extern bool bta_av_hdl_event(BT_HDR_RIGID* p_msg);
-extern const char* bta_av_evt_code(uint16_t evt_code);
-extern bool bta_av_switch_if_needed(tBTA_AV_SCB* p_scb);
-extern bool bta_av_link_role_ok(tBTA_AV_SCB* p_scb, uint8_t bits);
-
-/* nsm action functions */
-extern void bta_av_api_disconnect(tBTA_AV_DATA* p_data);
-extern void bta_av_sig_chg(tBTA_AV_DATA* p_data);
-extern void bta_av_signalling_timer(tBTA_AV_DATA* p_data);
-extern void bta_av_rc_disc_done(tBTA_AV_DATA* p_data);
-extern void bta_av_rc_closed(tBTA_AV_DATA* p_data);
-extern void bta_av_rc_browse_opened(tBTA_AV_DATA* p_data);
-extern void bta_av_rc_browse_closed(tBTA_AV_DATA* p_data);
-extern void bta_av_rc_disc(uint8_t disc);
-extern void bta_av_conn_chg(tBTA_AV_DATA* p_data);
-extern void bta_av_dereg_comp(tBTA_AV_DATA* p_data);
-
-/* sm action functions */
-extern void bta_av_disable(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data);
-extern void bta_av_rc_opened(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data);
-extern void bta_av_rc_remote_cmd(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data);
-extern void bta_av_rc_vendor_cmd(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data);
-extern void bta_av_rc_vendor_rsp(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data);
-extern void bta_av_rc_msg(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data);
-extern void bta_av_rc_close(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data);
-extern void bta_av_rc_meta_rsp(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data);
-extern void bta_av_rc_free_rsp(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data);
-extern void bta_av_rc_free_browse_msg(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data);
-
-extern tBTA_AV_RCB* bta_av_get_rcb_by_shdl(uint8_t shdl);
-extern void bta_av_del_rc(tBTA_AV_RCB* p_rcb);
-
-extern void bta_av_proc_stream_evt(uint8_t handle, const RawAddress& bd_addr,
- uint8_t event, tAVDT_CTRL* p_data,
- uint8_t scb_index);
-
-/* ssm action functions */
-extern void bta_av_do_disc_a2dp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_cleanup(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_free_sdb(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_config_ind(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_disconnect_req(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_security_req(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_security_rsp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_setconfig_rsp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_str_opened(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_security_ind(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_security_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_do_close(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_connect_req(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_sdp_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_disc_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_disc_res_as_acp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_open_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_getcap_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_setconfig_rej(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_discover_req(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_conn_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_do_start(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_str_stopped(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_reconfig(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_data_path(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_start_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_start_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_str_closed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_clr_cong(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_suspend_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_rcfg_str_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_rcfg_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_rcfg_connect(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_rcfg_discntd(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_suspend_cont(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_rcfg_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_rcfg_open(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_security_rej(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_open_rc(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_chk_2nd_start(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_save_caps(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_rej_conn(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_rej_conn(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_set_use_rc(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_cco_close(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_switch_role(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_role_res(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_delay_co(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_open_at_inc(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_offload_req(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_offload_rsp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-extern void bta_av_vendor_offload_stop(void);
-extern void bta_av_st_rc_timer(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data);
-
-#endif /* BTA_AV_INT_H */
diff --git a/bta/av/bta_av_main.cc b/bta/av/bta_av_main.cc
deleted file mode 100644
index 257770c..0000000
--- a/bta/av/bta_av_main.cc
+++ /dev/null
@@ -1,1518 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2004-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the main implementation file for the BTA advanced audio/video.
- *
- ******************************************************************************/
-
-#define LOG_TAG "bt_bta_av"
-
-#include <cstdint>
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bta/av/bta_av_int.h"
-#include "bta/include/bta_ar_api.h"
-#include "bta/include/utl.h"
-#include "btif/avrcp/avrcp_service.h"
-#include "btif/include/btif_av_co.h"
-#include "btif/include/btif_config.h"
-#include "main/shim/dumpsys.h"
-#include "osi/include/allocator.h"
-#include "osi/include/log.h"
-#include "osi/include/osi.h" // UNUSED_ATTR
-#include "osi/include/properties.h"
-#include "stack/include/acl_api.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/btm_api.h"
-#include "types/hci_role.h"
-#include "types/raw_address.h"
-
-#include <base/logging.h>
-
-/*****************************************************************************
- * Constants and types
- ****************************************************************************/
-
-#ifndef BTA_AV_RET_TOUT
-#define BTA_AV_RET_TOUT 4
-#endif
-
-#ifndef BTA_AV_SIG_TOUT
-#define BTA_AV_SIG_TOUT 4
-#endif
-
-#ifndef BTA_AV_IDLE_TOUT
-#define BTA_AV_IDLE_TOUT 10
-#endif
-
-/* the delay time in milliseconds to retry role switch */
-#ifndef BTA_AV_RS_TIME_VAL
-#define BTA_AV_RS_TIME_VAL 1000
-#endif
-
-#ifndef AVRCP_VERSION_PROPERTY
-#define AVRCP_VERSION_PROPERTY "persist.bluetooth.avrcpversion"
-#endif
-
-#ifndef AVRCP_1_6_STRING
-#define AVRCP_1_6_STRING "avrcp16"
-#endif
-
-#ifndef AVRCP_1_5_STRING
-#define AVRCP_1_5_STRING "avrcp15"
-#endif
-
-#ifndef AVRCP_1_4_STRING
-#define AVRCP_1_4_STRING "avrcp14"
-#endif
-
-#ifndef AVRCP_1_3_STRING
-#define AVRCP_1_3_STRING "avrcp13"
-#endif
-
-#ifndef AVRCP_DEFAULT_VERSION
-#define AVRCP_DEFAULT_VERSION AVRCP_1_5_STRING
-#endif
-
-/* state machine states */
-enum { BTA_AV_INIT_ST, BTA_AV_OPEN_ST };
-
-typedef void (*tBTA_AV_NSM_ACT)(tBTA_AV_DATA* p_data);
-static void bta_av_api_enable(tBTA_AV_DATA* p_data);
-static void bta_av_api_register(tBTA_AV_DATA* p_data);
-static void bta_av_ci_data(tBTA_AV_DATA* p_data);
-static void bta_av_rpc_conn(tBTA_AV_DATA* p_data);
-static void bta_av_api_to_ssm(tBTA_AV_DATA* p_data);
-
-static void bta_av_sco_chg_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
- uint8_t app_id, const RawAddress& peer_addr);
-static void bta_av_sys_rs_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
- uint8_t app_id, const RawAddress& peer_addr);
-
-/*****************************************************************************
- * Global data
- ****************************************************************************/
-
-/* AV control block */
-tBTA_AV_CB bta_av_cb = {};
-
-static const char* bta_av_st_code(uint8_t state);
-
-/*******************************************************************************
- *
- * Function bta_av_api_enable
- *
- * Description Handle an API enable event.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_av_api_enable(tBTA_AV_DATA* p_data) {
- if (bta_av_cb.disabling) {
- APPL_TRACE_WARNING(
- "%s: previous (reg_audio=%#x) is still disabling (attempts=%d)",
- __func__, bta_av_cb.reg_audio, bta_av_cb.enabling_attempts);
- if (++bta_av_cb.enabling_attempts <= kEnablingAttemptsCountMaximum) {
- tBTA_AV_API_ENABLE* p_buf =
- (tBTA_AV_API_ENABLE*)osi_malloc(sizeof(tBTA_AV_API_ENABLE));
- memcpy(p_buf, &p_data->api_enable, sizeof(tBTA_AV_API_ENABLE));
- bta_sys_sendmsg_delayed(p_buf, base::TimeDelta::FromMilliseconds(
- kEnablingAttemptsIntervalMs));
- return;
- }
- if (bta_av_cb.sdp_a2dp_handle) {
- SDP_DeleteRecord(bta_av_cb.sdp_a2dp_handle);
- bta_sys_remove_uuid(UUID_SERVCLASS_AUDIO_SOURCE);
- }
- if (bta_av_cb.sdp_a2dp_snk_handle) {
- SDP_DeleteRecord(bta_av_cb.sdp_a2dp_snk_handle);
- bta_sys_remove_uuid(UUID_SERVCLASS_AUDIO_SINK);
- }
- // deregister from AVDT
- bta_ar_dereg_avdt();
-
- // deregister from AVCT
- bta_ar_dereg_avrc(UUID_SERVCLASS_AV_REMOTE_CONTROL);
- bta_ar_dereg_avrc(UUID_SERVCLASS_AV_REM_CTRL_TARGET);
- bta_ar_dereg_avct();
- }
-
- /* initialize control block */
- memset(&bta_av_cb, 0, sizeof(tBTA_AV_CB));
-
- for (int i = 0; i < BTA_AV_NUM_RCB; i++)
- bta_av_cb.rcb[i].handle = BTA_AV_RC_HANDLE_NONE;
-
- bta_av_cb.rc_acp_handle = BTA_AV_RC_HANDLE_NONE;
-
- /* store parameters */
- bta_av_cb.p_cback = p_data->api_enable.p_cback;
- bta_av_cb.features = p_data->api_enable.features;
- bta_av_cb.offload_start_pending_acl_hdl = HCI_INVALID_HANDLE;
- bta_av_cb.offload_started_acl_hdl = HCI_INVALID_HANDLE;
-
- tBTA_AV_ENABLE enable;
- enable.features = bta_av_cb.features;
-
- /* Register for SCO change event */
- bta_sys_sco_register(bta_av_sco_chg_cback);
-
- /* call callback with enable event */
- tBTA_AV bta_av_data;
- bta_av_data.enable = enable;
- (*bta_av_cb.p_cback)(BTA_AV_ENABLE_EVT, &bta_av_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_addr_to_scb
- *
- * Description find the stream control block by the peer addr
- *
- * Returns void
- *
- ******************************************************************************/
-tBTA_AV_SCB* bta_av_addr_to_scb(const RawAddress& bd_addr) {
- tBTA_AV_SCB* p_scb = NULL;
- int xx;
-
- for (xx = 0; xx < BTA_AV_NUM_STRS; xx++) {
- if (bta_av_cb.p_scb[xx]) {
- if (bd_addr == bta_av_cb.p_scb[xx]->PeerAddress()) {
- p_scb = bta_av_cb.p_scb[xx];
- break;
- }
- }
- }
- return p_scb;
-}
-
-int BTA_AvObtainPeerChannelIndex(const RawAddress& peer_address) {
- // Find the entry for the peer (if exists)
- tBTA_AV_SCB* p_scb = bta_av_addr_to_scb(peer_address);
- if (p_scb != nullptr) {
- return p_scb->hdi;
- }
-
- // Find the index for an entry that is not used
- for (int index = 0; index < BTA_AV_NUM_STRS; index++) {
- tBTA_AV_SCB* p_scb = bta_av_cb.p_scb[index];
- if (p_scb == nullptr) {
- continue;
- }
- if (p_scb->PeerAddress().IsEmpty()) {
- return p_scb->hdi;
- }
- }
-
- return -1;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_hndl_to_scb
- *
- * Description find the stream control block by the handle
- *
- * Returns void
- *
- ******************************************************************************/
-tBTA_AV_SCB* bta_av_hndl_to_scb(uint16_t handle) {
- tBTA_AV_HNDL hndl = (tBTA_AV_HNDL)handle;
- tBTA_AV_SCB* p_scb = NULL;
- uint8_t idx = (hndl & BTA_AV_HNDL_MSK);
-
- if (idx && (idx <= BTA_AV_NUM_STRS)) {
- p_scb = bta_av_cb.p_scb[idx - 1];
- }
- return p_scb;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_alloc_scb
- *
- * Description allocate stream control block,
- * register the service to stack
- * create SDP record
- *
- * Returns void
- *
- ******************************************************************************/
-static tBTA_AV_SCB* bta_av_alloc_scb(tBTA_AV_CHNL chnl) {
- if (chnl != BTA_AV_CHNL_AUDIO) {
- APPL_TRACE_ERROR("%s: bad channel: %d", __func__, chnl);
- return nullptr;
- }
-
- for (int xx = 0; xx < BTA_AV_NUM_STRS; xx++) {
- if (bta_av_cb.p_scb[xx] != nullptr) continue;
- // Found an empty spot
- // TODO: After tBTA_AV_SCB is changed to a proper class, the entry
- // here should be allocated by C++ 'new' statement.
- tBTA_AV_SCB* p_ret = (tBTA_AV_SCB*)osi_calloc(sizeof(tBTA_AV_SCB));
- p_ret->rc_handle = BTA_AV_RC_HANDLE_NONE;
- p_ret->chnl = chnl;
- p_ret->hndl = (tBTA_AV_HNDL)((xx + 1) | chnl);
- p_ret->hdi = xx;
- p_ret->a2dp_list = list_new(nullptr);
- p_ret->avrc_ct_timer = alarm_new("bta_av.avrc_ct_timer");
- bta_av_cb.p_scb[xx] = p_ret;
- return p_ret;
- }
-
- return nullptr;
-}
-
-void bta_av_free_scb(tBTA_AV_SCB* p_scb) {
- if (p_scb == nullptr) return;
- uint8_t scb_index = p_scb->hdi;
- CHECK(scb_index < BTA_AV_NUM_STRS);
-
- CHECK(p_scb == bta_av_cb.p_scb[scb_index]);
- bta_av_cb.p_scb[scb_index] = nullptr;
- alarm_free(p_scb->avrc_ct_timer);
- // TODO: After tBTA_AV_SCB is changed to a proper class, the entry
- // here should be de-allocated by C++ 'delete' statement.
- osi_free(p_scb);
-}
-
-void tBTA_AV_SCB::OnConnected(const RawAddress& peer_address) {
- peer_address_ = peer_address;
-
- if (peer_address.IsEmpty()) {
- LOG_ERROR("%s: Invalid peer address: %s", __func__,
- peer_address.ToString().c_str());
- return;
- }
-
- // Read and restore the AVDTP version from local storage
- uint16_t avdtp_version = 0;
- size_t version_value_size = sizeof(avdtp_version);
- if (!btif_config_get_bin(peer_address_.ToString(), AVDTP_VERSION_CONFIG_KEY,
- (uint8_t*)&avdtp_version, &version_value_size)) {
- LOG_WARN("%s: Failed to read cached peer AVDTP version for %s", __func__,
- peer_address_.ToString().c_str());
- } else {
- SetAvdtpVersion(avdtp_version);
- }
-}
-
-void tBTA_AV_SCB::OnDisconnected() {
- peer_address_ = RawAddress::kEmpty;
- SetAvdtpVersion(0);
-}
-
-void tBTA_AV_SCB::SetAvdtpVersion(uint16_t avdtp_version) {
- avdtp_version_ = avdtp_version;
- LOG_INFO("%s: AVDTP version for %s set to 0x%x", __func__,
- peer_address_.ToString().c_str(), avdtp_version_);
-}
-
-/*******************************************************************************
- ******************************************************************************/
-void bta_av_conn_cback(UNUSED_ATTR uint8_t handle, const RawAddress& bd_addr,
- uint8_t event, tAVDT_CTRL* p_data, uint8_t scb_index) {
- uint16_t evt = 0;
- tBTA_AV_SCB* p_scb = NULL;
-
- if (event == BTA_AR_AVDT_CONN_EVT || event == AVDT_CONNECT_IND_EVT ||
- event == AVDT_DISCONNECT_IND_EVT)
- {
- evt = BTA_AV_SIG_CHG_EVT;
- if (event == AVDT_DISCONNECT_IND_EVT) {
- p_scb = bta_av_addr_to_scb(bd_addr);
- if (p_scb) {
- uint16_t handle =
- BTM_GetHCIConnHandle(p_scb->PeerAddress(), BT_TRANSPORT_BR_EDR);
- if (bta_av_cb.offload_started_acl_hdl == handle ||
- bta_av_cb.offload_start_pending_acl_hdl == handle) {
- LOG_INFO("%s: Cleanup offload related flag", __func__);
- bta_av_cb.offload_started_acl_hdl = HCI_INVALID_HANDLE;
- bta_av_cb.offload_start_pending_acl_hdl = HCI_INVALID_HANDLE;
- }
- }
- } else if (event == AVDT_CONNECT_IND_EVT) {
- APPL_TRACE_DEBUG("%s: CONN_IND is ACP:%d", __func__,
- p_data->hdr.err_param);
- }
-
- tBTA_AV_STR_MSG* p_msg =
- (tBTA_AV_STR_MSG*)osi_malloc(sizeof(tBTA_AV_STR_MSG));
- p_msg->hdr.event = evt;
- p_msg->hdr.layer_specific = event;
- p_msg->hdr.offset = p_data->hdr.err_param;
- p_msg->bd_addr = bd_addr;
- p_msg->scb_index = scb_index;
- if (p_scb) {
- APPL_TRACE_DEBUG("%s: bta_handle x%x, role x%x", __func__, p_scb->hndl,
- p_scb->role);
- }
- LOG_INFO("%s: conn_cback bd_addr: %s", __func__,
- bd_addr.ToString().c_str());
- bta_sys_sendmsg(p_msg);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_a2dp_report_cback
- *
- * Description A2DP report callback.
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_av_a2dp_report_cback(UNUSED_ATTR uint8_t handle,
- UNUSED_ATTR AVDT_REPORT_TYPE type,
- UNUSED_ATTR tAVDT_REPORT_DATA* p_data) {
- /* Do not need to handle report data for now.
- * This empty function is here for conformance reasons. */
-}
-
-/*******************************************************************************
- *
- * Function bta_av_api_register
- *
- * Description allocate stream control block,
- * register the service to stack
- * create SDP record
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_av_api_register(tBTA_AV_DATA* p_data) {
- tBTA_AV_REGISTER registr;
- tBTA_AV_SCB* p_scb; /* stream control block */
- AvdtpRcb reg;
- AvdtpStreamConfig avdtp_stream_config;
- char* p_service_name;
- tBTA_UTL_COD cod;
-
- if (bta_av_cb.disabling || (bta_av_cb.features == 0)) {
- APPL_TRACE_WARNING(
- "%s: AV instance (features=%#x, reg_audio=%#x) is not "
- "ready for app_id %d",
- __func__, bta_av_cb.features, bta_av_cb.reg_audio,
- p_data->api_reg.app_id);
- tBTA_AV_API_REG* p_buf =
- (tBTA_AV_API_REG*)osi_malloc(sizeof(tBTA_AV_API_REG));
- memcpy(p_buf, &p_data->api_reg, sizeof(tBTA_AV_API_REG));
- bta_sys_sendmsg_delayed(
- p_buf, base::TimeDelta::FromMilliseconds(kEnablingAttemptsIntervalMs));
- return;
- }
-
- avdtp_stream_config.Reset();
-
- registr.status = BTA_AV_FAIL_RESOURCES;
- registr.app_id = p_data->api_reg.app_id;
- registr.chnl = (tBTA_AV_CHNL)p_data->hdr.layer_specific;
-
- char avrcp_version[PROPERTY_VALUE_MAX] = {0};
- osi_property_get(AVRCP_VERSION_PROPERTY, avrcp_version,
- AVRCP_DEFAULT_VERSION);
- LOG_INFO("%s: AVRCP version used for sdp: \"%s\"", __func__, avrcp_version);
-
- uint16_t profile_initialized = p_data->api_reg.service_uuid;
- if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK) {
- p_bta_av_cfg = &bta_avk_cfg;
- } else if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE) {
- p_bta_av_cfg = &bta_av_cfg;
-
- if (!strncmp(AVRCP_1_3_STRING, avrcp_version, sizeof(AVRCP_1_3_STRING))) {
- LOG_INFO("%s: AVRCP 1.3 capabilites used", __func__);
- p_bta_av_cfg = &bta_av_cfg_compatibility;
- }
- }
-
- APPL_TRACE_DEBUG("%s: profile: 0x%x", __func__, profile_initialized);
- if (p_bta_av_cfg == NULL) {
- APPL_TRACE_ERROR("%s: AV configuration is null!", __func__);
- return;
- }
-
- do {
- p_scb = bta_av_alloc_scb(registr.chnl);
- if (p_scb == NULL) {
- APPL_TRACE_ERROR("%s: failed to alloc SCB", __func__);
- break;
- }
-
- registr.hndl = p_scb->hndl;
- p_scb->app_id = registr.app_id;
-
- /* initialize the stream control block */
- registr.status = BTA_AV_SUCCESS;
-
- if (bta_av_cb.reg_audio == 0) {
- /* the first channel registered. register to AVDTP */
- reg.ctrl_mtu = 672;
- reg.ret_tout = BTA_AV_RET_TOUT;
- reg.sig_tout = BTA_AV_SIG_TOUT;
- reg.idle_tout = BTA_AV_IDLE_TOUT;
- reg.scb_index = p_scb->hdi;
- bta_ar_reg_avdt(®, bta_av_conn_cback);
- bta_sys_role_chg_register(&bta_av_sys_rs_cback);
-
- /* create remote control TG service if required */
- if (bta_av_cb.features & (BTA_AV_FEAT_RCTG)) {
- /* register with no authorization; let AVDTP use authorization instead
- */
- bta_ar_reg_avct();
-
- /* For the Audio Sink role we support additional TG to support
- * absolute volume.
- */
- if (is_new_avrcp_enabled()) {
- APPL_TRACE_DEBUG("%s: newavrcp is the owner of the AVRCP Target SDP "
- "record. Don't create the SDP record", __func__);
- } else {
- APPL_TRACE_DEBUG("%s: newavrcp is not enabled. Create SDP record",
- __func__);
-
- uint16_t profile_version = AVRC_REV_1_0;
- if (!strncmp(AVRCP_1_6_STRING, avrcp_version,
- sizeof(AVRCP_1_6_STRING))) {
- profile_version = AVRC_REV_1_6;
- } else if (!strncmp(AVRCP_1_5_STRING, avrcp_version,
- sizeof(AVRCP_1_5_STRING))) {
- profile_version = AVRC_REV_1_5;
- } else if (!strncmp(AVRCP_1_3_STRING, avrcp_version,
- sizeof(AVRCP_1_3_STRING))) {
- profile_version = AVRC_REV_1_3;
- } else {
- profile_version = AVRC_REV_1_4;
- }
-
- bta_ar_reg_avrc(
- UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target", NULL,
- p_bta_av_cfg->avrc_tg_cat,
- (bta_av_cb.features & BTA_AV_FEAT_BROWSE), profile_version);
- }
- }
-
- /* Set the Capturing service class bit */
- if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE)
- cod.service = BTM_COD_SERVICE_CAPTURING;
- else if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK)
- cod.service = BTM_COD_SERVICE_RENDERING;
- utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
- } /* if 1st channel */
-
- /* get stream configuration and create stream */
- avdtp_stream_config.cfg.num_codec = 1;
- avdtp_stream_config.nsc_mask = AvdtpStreamConfig::AVDT_NSC_RECONFIG;
- if (!(bta_av_cb.features & BTA_AV_FEAT_PROTECT)) {
- avdtp_stream_config.nsc_mask |= AvdtpStreamConfig::AVDT_NSC_SECURITY;
- }
- APPL_TRACE_DEBUG("%s: nsc_mask: 0x%x", __func__,
- avdtp_stream_config.nsc_mask);
-
- if (p_data->api_reg.p_service_name[0] == 0) {
- p_service_name = NULL;
- } else {
- p_service_name = p_data->api_reg.p_service_name;
- }
-
- p_scb->suspend_sup = true;
- p_scb->recfg_sup = true;
-
- avdtp_stream_config.scb_index = p_scb->hdi;
- avdtp_stream_config.p_avdt_ctrl_cback = &bta_av_proc_stream_evt;
-
- /* set up the audio stream control block */
- p_scb->p_cos = &bta_av_a2dp_cos;
- p_scb->media_type = AVDT_MEDIA_TYPE_AUDIO;
- avdtp_stream_config.cfg.psc_mask = AVDT_PSC_TRANS;
- avdtp_stream_config.media_type = AVDT_MEDIA_TYPE_AUDIO;
- avdtp_stream_config.mtu = MAX_3MBPS_AVDTP_MTU;
- btav_a2dp_codec_index_t codec_index_min = BTAV_A2DP_CODEC_INDEX_SOURCE_MIN;
- btav_a2dp_codec_index_t codec_index_max = BTAV_A2DP_CODEC_INDEX_SOURCE_MAX;
-
- if (bta_av_cb.features & BTA_AV_FEAT_REPORT) {
- avdtp_stream_config.cfg.psc_mask |= AVDT_PSC_REPORT;
- avdtp_stream_config.p_report_cback = bta_av_a2dp_report_cback;
- }
- if (bta_av_cb.features & BTA_AV_FEAT_DELAY_RPT)
- avdtp_stream_config.cfg.psc_mask |= AVDT_PSC_DELAY_RPT;
-
- if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE) {
- avdtp_stream_config.tsep = AVDT_TSEP_SRC;
- codec_index_min = BTAV_A2DP_CODEC_INDEX_SOURCE_MIN;
- codec_index_max = BTAV_A2DP_CODEC_INDEX_SOURCE_MAX;
- } else if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK) {
- avdtp_stream_config.tsep = AVDT_TSEP_SNK;
- avdtp_stream_config.p_sink_data_cback = bta_av_sink_data_cback;
- codec_index_min = BTAV_A2DP_CODEC_INDEX_SINK_MIN;
- codec_index_max = BTAV_A2DP_CODEC_INDEX_SINK_MAX;
- }
-
- /* Initialize handles to zero */
- for (int xx = 0; xx < BTAV_A2DP_CODEC_INDEX_MAX; xx++) {
- p_scb->seps[xx].av_handle = 0;
- }
-
- /* keep the configuration in the stream control block */
- p_scb->cfg = avdtp_stream_config.cfg;
- for (int i = codec_index_min; i < codec_index_max; i++) {
- btav_a2dp_codec_index_t codec_index =
- static_cast<btav_a2dp_codec_index_t>(i);
- if (!bta_av_co_is_supported_codec(codec_index)) {
- continue;
- }
- if (!(*bta_av_a2dp_cos.init)(codec_index, &avdtp_stream_config.cfg)) {
- continue;
- }
- if (AVDT_CreateStream(p_scb->app_id, &p_scb->seps[codec_index].av_handle,
- avdtp_stream_config) != AVDT_SUCCESS) {
- APPL_TRACE_WARNING(
- "%s: bta_handle=0x%x (app_id %d) failed to alloc an SEP index:%d",
- __func__, p_scb->hndl, p_scb->app_id, codec_index);
- continue;
- }
- /* Save a copy of the codec */
- memcpy(p_scb->seps[codec_index].codec_info,
- avdtp_stream_config.cfg.codec_info, AVDT_CODEC_SIZE);
- p_scb->seps[codec_index].tsep = avdtp_stream_config.tsep;
- if (avdtp_stream_config.tsep == AVDT_TSEP_SNK) {
- p_scb->seps[codec_index].p_app_sink_data_cback =
- p_data->api_reg.p_app_sink_data_cback;
- } else {
- /* In case of A2DP SOURCE we don't need a callback to
- * handle media packets.
- */
- p_scb->seps[codec_index].p_app_sink_data_cback = NULL;
- }
- }
-
- if (!bta_av_cb.reg_audio) {
- bta_av_cb.sdp_a2dp_handle = 0;
- bta_av_cb.sdp_a2dp_snk_handle = 0;
- if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE) {
- /* create the SDP records on the 1st audio channel */
- bta_av_cb.sdp_a2dp_handle = SDP_CreateRecord();
- A2DP_AddRecord(UUID_SERVCLASS_AUDIO_SOURCE, p_service_name, NULL,
- A2DP_SUPF_PLAYER, bta_av_cb.sdp_a2dp_handle);
- bta_sys_add_uuid(UUID_SERVCLASS_AUDIO_SOURCE);
- } else if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK) {
- bta_av_cb.sdp_a2dp_snk_handle = SDP_CreateRecord();
- A2DP_AddRecord(UUID_SERVCLASS_AUDIO_SINK, p_service_name, NULL,
- A2DP_SUPF_PLAYER, bta_av_cb.sdp_a2dp_snk_handle);
- bta_sys_add_uuid(UUID_SERVCLASS_AUDIO_SINK);
- }
- /* start listening when A2DP is registered */
- if (bta_av_cb.features & BTA_AV_FEAT_RCTG)
- bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1);
-
- /* if the AV and AVK are both supported, it cannot support the CT role
- */
- if (bta_av_cb.features & (BTA_AV_FEAT_RCCT)) {
- /* if TG is not supported, we need to register to AVCT now */
- if ((bta_av_cb.features & (BTA_AV_FEAT_RCTG)) == 0) {
- bta_ar_reg_avct();
- bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1);
- }
- /* create an SDP record as AVRC CT. We create 1.3 for SOURCE
- * because we rely on feature bits being scanned by external
- * devices more than the profile version itself.
- *
- * We create 1.4 for SINK since we support browsing.
- */
- if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE &&
- !is_new_avrcp_enabled()) {
- bta_ar_reg_avrc(UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL, NULL,
- p_bta_av_cfg->avrc_ct_cat,
- (bta_av_cb.features & BTA_AV_FEAT_BROWSE),
- AVRC_REV_1_3);
- } else if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK) {
- bta_ar_reg_avrc(UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL, NULL,
- p_bta_av_cfg->avrc_ct_cat,
- (bta_av_cb.features & BTA_AV_FEAT_BROWSE),
- AVRC_REV_1_6);
- }
- }
- }
- bta_av_cb.reg_audio |= BTA_AV_HNDL_TO_MSK(p_scb->hdi);
- APPL_TRACE_DEBUG("%s: reg_audio: 0x%x", __func__, bta_av_cb.reg_audio);
- } while (0);
-
- /* call callback with register event */
- tBTA_AV bta_av_data;
- bta_av_data.registr = registr;
- (*bta_av_cb.p_cback)(BTA_AV_REGISTER_EVT, &bta_av_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_api_deregister
- *
- * Description de-register a channel
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_api_deregister(tBTA_AV_DATA* p_data) {
- tBTA_AV_SCB* p_scb = bta_av_hndl_to_scb(p_data->hdr.layer_specific);
-
- if (p_scb) {
- p_scb->deregistering = true;
- bta_av_ssm_execute(p_scb, BTA_AV_API_CLOSE_EVT, p_data);
- } else {
- bta_av_dereg_comp(p_data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_ci_data
- *
- * Description Forward the BTA_AV_CI_SRC_DATA_READY_EVT to stream state
- * machine.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_av_ci_data(tBTA_AV_DATA* p_data) {
- tBTA_AV_SCB* p_scb;
- int i;
- uint8_t chnl = (uint8_t)p_data->hdr.layer_specific;
-
- for (i = 0; i < BTA_AV_NUM_STRS; i++) {
- p_scb = bta_av_cb.p_scb[i];
-
- if (p_scb && p_scb->chnl == chnl) {
- bta_av_ssm_execute(p_scb, BTA_AV_SRC_DATA_READY_EVT, p_data);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_rpc_conn
- *
- * Description report report channel open
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_av_rpc_conn(UNUSED_ATTR tBTA_AV_DATA* p_data) {}
-
-/*******************************************************************************
- *
- * Function bta_av_api_to_ssm
- *
- * Description forward the API request to stream state machine
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_av_api_to_ssm(tBTA_AV_DATA* p_data) {
- uint16_t event =
- p_data->hdr.event - BTA_AV_FIRST_A2S_API_EVT + BTA_AV_FIRST_A2S_SSM_EVT;
- tBTA_AV_HNDL handle = p_data->hdr.layer_specific;
- tBTA_AV_SCB* p_scb = bta_av_hndl_to_scb(handle);
-
- if (p_scb != nullptr) {
- bta_av_ssm_execute(p_scb, event, p_data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_chk_start
- *
- * Description if this is audio channel, check if more than one audio
- * channel is connected & already started.
- * This function needs to be kept very similar to
- * bta_av_chk_2nd_start
- *
- * Returns true, if need api_start
- *
- ******************************************************************************/
-bool bta_av_chk_start(tBTA_AV_SCB* p_scb) {
- bool start = false;
-
- if ((p_scb->chnl == BTA_AV_CHNL_AUDIO) && (bta_av_cb.audio_open_cnt >= 2) &&
- (((p_scb->role & BTA_AV_ROLE_AD_ACP) == 0) || // Outgoing connection or
- (bta_av_cb.features & BTA_AV_FEAT_ACP_START))) { // Auto-starting option
- // More than one audio channel is connected.
- // If this is the 2nd stream as ACP, give INT a chance to issue the START
- // command.
- for (int i = 0; i < BTA_AV_NUM_STRS; i++) {
- tBTA_AV_SCB* p_scbi = bta_av_cb.p_scb[i];
- if (p_scbi && p_scbi->chnl == BTA_AV_CHNL_AUDIO && p_scbi->co_started) {
- start = true;
- // May need to update the flush timeout of this already started stream
- if (p_scbi->co_started != bta_av_cb.audio_open_cnt) {
- p_scbi->co_started = bta_av_cb.audio_open_cnt;
- }
- }
- }
- }
-
- LOG_INFO(
- "%s: peer %s channel:%d bta_av_cb.audio_open_cnt:%d role:0x%x "
- "features:0x%x start:%s",
- __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->chnl,
- bta_av_cb.audio_open_cnt, p_scb->role, bta_av_cb.features,
- logbool(start).c_str());
- return start;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_restore_switch
- *
- * Description assume that the caller of this function already makes
- * sure that there's only one ACL connection left
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_restore_switch(void) {
- tBTA_AV_CB* p_cb = &bta_av_cb;
- int i;
- uint8_t mask;
-
- APPL_TRACE_DEBUG("%s: reg_audio: 0x%x", __func__, bta_av_cb.reg_audio);
- for (i = 0; i < BTA_AV_NUM_STRS; i++) {
- mask = BTA_AV_HNDL_TO_MSK(i);
- if (p_cb->conn_audio == mask) {
- if (p_cb->p_scb[i]) {
- BTM_unblock_role_switch_for(p_cb->p_scb[i]->PeerAddress());
- }
- break;
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_sys_rs_cback
- *
- * Description Receives the role change event from dm
- *
- * Returns (BTA_SYS_ROLE_CHANGE, new_role, hci_status, p_bda)
- *
- ******************************************************************************/
-static void bta_av_sys_rs_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status,
- uint8_t id, uint8_t app_id,
- const RawAddress& peer_addr) {
- int i;
- tBTA_AV_SCB* p_scb = NULL;
- tHCI_ROLE cur_role;
- uint8_t peer_idx = 0;
-
- APPL_TRACE_DEBUG(
- "%s: peer %s new_role:%d hci_status:0x%x bta_av_cb.rs_idx:%d", __func__,
- peer_addr.ToString().c_str(), id, app_id, bta_av_cb.rs_idx);
-
- for (i = 0; i < BTA_AV_NUM_STRS; i++) {
- /* loop through all the SCBs to find matching peer addresses and report the
- * role change event */
- /* note that more than one SCB (a2dp & vdp) maybe waiting for this event */
- p_scb = bta_av_cb.p_scb[i];
- if (p_scb && p_scb->PeerAddress() == peer_addr) {
- tBTA_AV_ROLE_RES* p_buf =
- (tBTA_AV_ROLE_RES*)osi_malloc(sizeof(tBTA_AV_ROLE_RES));
- APPL_TRACE_DEBUG(
- "%s: peer %s found: new_role:%d, hci_status:0x%x bta_handle:0x%x",
- __func__, peer_addr.ToString().c_str(), id, app_id, p_scb->hndl);
- p_buf->hdr.event = BTA_AV_ROLE_CHANGE_EVT;
- p_buf->hdr.layer_specific = p_scb->hndl;
- p_buf->new_role = id;
- p_buf->hci_status = app_id;
- bta_sys_sendmsg(p_buf);
-
- peer_idx = p_scb->hdi + 1; /* Handle index for the peer_addr */
- }
- }
-
- /* restore role switch policy, if role switch failed */
- if ((HCI_SUCCESS != app_id) &&
- (BTM_GetRole(peer_addr, &cur_role) == BTM_SUCCESS) &&
- (cur_role == HCI_ROLE_PERIPHERAL)) {
- BTM_unblock_role_switch_for(peer_addr);
- }
-
- /* if BTA_AvOpen() was called for other device, which caused the role switch
- * of the peer_addr, */
- /* we need to continue opening process for the BTA_AvOpen(). */
- if ((bta_av_cb.rs_idx != 0) && (bta_av_cb.rs_idx != peer_idx)) {
- if ((bta_av_cb.rs_idx - 1) < BTA_AV_NUM_STRS) {
- p_scb = bta_av_cb.p_scb[bta_av_cb.rs_idx - 1];
- }
- if (p_scb && p_scb->q_tag == BTA_AV_Q_TAG_OPEN) {
- APPL_TRACE_DEBUG("%s: peer %s rs_idx:%d, bta_handle:0x%x q_tag:%d",
- __func__, p_scb->PeerAddress().ToString().c_str(),
- bta_av_cb.rs_idx, p_scb->hndl, p_scb->q_tag);
-
- if (HCI_SUCCESS == app_id || HCI_ERR_NO_CONNECTION == app_id) {
- p_scb->q_info.open.switch_res = BTA_AV_RS_OK;
- } else {
- APPL_TRACE_ERROR(
- "%s: peer %s (p_scb peer %s) role switch failed: new_role:%d "
- "hci_status:0x%x",
- __func__, peer_addr.ToString().c_str(),
- p_scb->PeerAddress().ToString().c_str(), id, app_id);
- p_scb->q_info.open.switch_res = BTA_AV_RS_FAIL;
- }
-
- /* Continue av open process */
- bta_av_do_disc_a2dp(p_scb, (tBTA_AV_DATA*)&(p_scb->q_info.open));
- }
-
- bta_av_cb.rs_idx = 0;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_sco_chg_cback
- *
- * Description receive & process the SCO connection up/down event from sys.
- * call setup also triggers this callback, to suspend av before
- * SCO activity happens, or to resume av once call ends.
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_av_sco_chg_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
- UNUSED_ATTR uint8_t app_id,
- UNUSED_ATTR const RawAddress& peer_addr) {
- tBTA_AV_SCB* p_scb;
- int i;
- tBTA_AV_API_STOP stop;
-
- LOG(INFO) << __func__ << ": status=" << bta_sys_conn_status_text(status)
- << ", num_links=" << +id;
- if (id) {
- bta_av_cb.sco_occupied = true;
- LOG_DEBUG("SCO occupied peer:%s status:%s", PRIVATE_ADDRESS(peer_addr),
- bta_sys_conn_status_text(status).c_str());
-
- if (bta_av_cb.features & BTA_AV_FEAT_NO_SCO_SSPD) {
- return;
- }
-
- /* either BTA_SYS_SCO_OPEN or BTA_SYS_SCO_CLOSE with remaining active SCO */
- for (i = 0; i < BTA_AV_NUM_STRS; i++) {
- p_scb = bta_av_cb.p_scb[i];
-
- if (p_scb && p_scb->co_started && (!p_scb->sco_suspend)) {
- VLOG(1) << __func__ << ": suspending scb:" << i;
- /* scb is used and started, not suspended automatically */
- p_scb->sco_suspend = true;
- stop.flush = false;
- stop.suspend = true;
- stop.reconfig_stop = false;
- bta_av_ssm_execute(p_scb, BTA_AV_AP_STOP_EVT, (tBTA_AV_DATA*)&stop);
- }
- }
- } else {
- bta_av_cb.sco_occupied = false;
- LOG_DEBUG("SCO unoccupied peer:%s status:%s", PRIVATE_ADDRESS(peer_addr),
- bta_sys_conn_status_text(status).c_str());
-
- if (bta_av_cb.features & BTA_AV_FEAT_NO_SCO_SSPD) {
- return;
- }
-
- for (i = 0; i < BTA_AV_NUM_STRS; i++) {
- p_scb = bta_av_cb.p_scb[i];
-
- if (p_scb && p_scb->sco_suspend) /* scb is used and suspended for SCO */
- {
- VLOG(1) << __func__ << ": starting scb:" << i;
- bta_av_ssm_execute(p_scb, BTA_AV_AP_START_EVT, NULL);
- }
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_switch_if_needed
- *
- * Description This function checks if there is another existing AV
- * channel that is local as peripheral role.
- * If so, role switch and remove it from link policy.
- *
- * Returns true, if role switch is done
- *
- ******************************************************************************/
-bool bta_av_switch_if_needed(tBTA_AV_SCB* p_scb) {
- // TODO: A workaround for devices that are connected first, become
- // Central, and block follow-up role changes - b/72122792 .
- return false;
-#if 0
- uint8_t role;
- bool needed = false;
- tBTA_AV_SCB* p_scbi;
- int i;
- uint8_t mask;
-
- for (i = 0; i < BTA_AV_NUM_STRS; i++) {
- mask = BTA_AV_HNDL_TO_MSK(i);
- p_scbi = bta_av_cb.p_scb[i];
- if (p_scbi && (p_scb->hdi != i) && /* not the original channel */
- ((bta_av_cb.conn_audio & mask))) /* connected audio */
- {
- BTM_GetRole(p_scbi->PeerAddress(), &role);
- /* this channel is open - clear the role switch link policy for this link
- */
- if (HCI_ROLE_CENTRAL != role) {
- if (bta_av_cb.features & BTA_AV_FEAT_CENTRAL)
- BTM_block_role_switch_for(p_scbi->PeerAddress());
- if (BTM_CMD_STARTED !=
- BTM_SwitchRole(p_scbi->PeerAddress(), HCI_ROLE_CENTRAL)) {
- /* can not switch role on SCBI
- * start the timer on SCB - because this function is ONLY called when
- * SCB gets API_OPEN */
- bta_sys_start_timer(p_scb->avrc_ct_timer, BTA_AV_RS_TIME_VAL,
- BTA_AV_AVRC_TIMER_EVT, p_scb->hndl);
- }
- needed = true;
- /* mark the original channel as waiting for RS result */
- bta_av_cb.rs_idx = p_scb->hdi + 1;
- break;
- }
- }
- }
- return needed;
-#endif
-}
-
-/*******************************************************************************
- *
- * Function bta_av_link_role_ok
- *
- * Description This function checks if the SCB has existing ACL connection
- * If so, check if the link role fits the requirements.
- *
- * Returns true, if role is ok
- *
- ******************************************************************************/
-bool bta_av_link_role_ok(tBTA_AV_SCB* p_scb, uint8_t bits) {
- tHCI_ROLE role;
- if (BTM_GetRole(p_scb->PeerAddress(), &role) != BTM_SUCCESS) {
- LOG_WARN("Unable to find link role for device:%s",
- PRIVATE_ADDRESS(p_scb->PeerAddress()));
- return true;
- }
-
- if (role != HCI_ROLE_CENTRAL && (A2DP_BitsSet(bta_av_cb.conn_audio) > bits)) {
- LOG_INFO(
- "Switch link role to central peer:%s bta_handle:0x%x current_role:%s"
- " conn_audio:0x%x bits:%d features:0x%x",
- PRIVATE_ADDRESS(p_scb->PeerAddress()), p_scb->hndl,
- RoleText(role).c_str(), bta_av_cb.conn_audio, bits, bta_av_cb.features);
- const tBTM_STATUS status = BTM_SwitchRoleToCentral(p_scb->PeerAddress());
- switch (status) {
- case BTM_CMD_STARTED:
- break;
- case BTM_MODE_UNSUPPORTED:
- case BTM_DEV_RESTRICT_LISTED:
- // Role switch can never happen, but indicate to caller
- // a result such that a timer will not start to repeatedly
- // try something not possible.
- LOG_ERROR("Link can never role switch to central device:%s",
- PRIVATE_ADDRESS(p_scb->PeerAddress()));
- break;
- default:
- /* can not switch role on SCB - start the timer on SCB */
- p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RES_START;
- LOG_ERROR("Unable to switch role to central device:%s error:%s",
- PRIVATE_ADDRESS(p_scb->PeerAddress()),
- btm_status_text(status).c_str());
- return false;
- }
- }
- return true;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_dup_audio_buf
- *
- * Description dup the audio data to the q_info.a2dp of other audio
- * channels
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_dup_audio_buf(tBTA_AV_SCB* p_scb, BT_HDR* p_buf) {
- /* Test whether there is more than one audio channel connected */
- if ((p_buf == NULL) || (bta_av_cb.audio_open_cnt < 2)) return;
-
- uint16_t copy_size = BT_HDR_SIZE + p_buf->len + p_buf->offset;
- for (int i = 0; i < BTA_AV_NUM_STRS; i++) {
- tBTA_AV_SCB* p_scbi = bta_av_cb.p_scb[i];
-
- if (i == p_scb->hdi) continue; /* Ignore the original channel */
- if ((p_scbi == NULL) || !p_scbi->co_started)
- continue; /* Ignore if SCB is not used or started */
- if (!(bta_av_cb.conn_audio & BTA_AV_HNDL_TO_MSK(i)))
- continue; /* Audio is not connected */
-
- /* Enqueue the data */
- BT_HDR* p_new = (BT_HDR*)osi_malloc(copy_size);
- memcpy(p_new, p_buf, copy_size);
- list_append(p_scbi->a2dp_list, p_new);
-
- if (list_length(p_scbi->a2dp_list) > p_bta_av_cfg->audio_mqs) {
- // Drop the oldest packet
- bta_av_co_audio_drop(p_scbi->hndl, p_scbi->PeerAddress());
- BT_HDR* p_buf_drop = static_cast<BT_HDR*>(list_front(p_scbi->a2dp_list));
- list_remove(p_scbi->a2dp_list, p_buf_drop);
- osi_free(p_buf_drop);
- }
- }
-}
-
-static void bta_av_non_state_machine_event(uint16_t event,
- tBTA_AV_DATA* p_data) {
- switch (event) {
- case BTA_AV_API_ENABLE_EVT:
- bta_av_api_enable(p_data);
- break;
- case BTA_AV_API_REGISTER_EVT:
- bta_av_api_register(p_data);
- break;
- case BTA_AV_API_DEREGISTER_EVT:
- bta_av_api_deregister(p_data);
- break;
- case BTA_AV_API_DISCONNECT_EVT:
- bta_av_api_disconnect(p_data);
- break;
- case BTA_AV_CI_SRC_DATA_READY_EVT:
- bta_av_ci_data(p_data);
- break;
- case BTA_AV_SIG_CHG_EVT:
- bta_av_sig_chg(p_data);
- break;
- case BTA_AV_SIGNALLING_TIMER_EVT:
- bta_av_signalling_timer(p_data);
- break;
- case BTA_AV_SDP_AVRC_DISC_EVT:
- bta_av_rc_disc_done(p_data);
- break;
- case BTA_AV_AVRC_CLOSE_EVT:
- bta_av_rc_closed(p_data);
- break;
- case BTA_AV_AVRC_BROWSE_OPEN_EVT:
- bta_av_rc_browse_opened(p_data);
- break;
- case BTA_AV_AVRC_BROWSE_CLOSE_EVT:
- bta_av_rc_browse_closed(p_data);
- break;
- case BTA_AV_CONN_CHG_EVT:
- bta_av_conn_chg(p_data);
- break;
- case BTA_AV_DEREG_COMP_EVT:
- bta_av_dereg_comp(p_data);
- break;
- case BTA_AV_AVDT_RPT_CONN_EVT:
- bta_av_rpc_conn(p_data);
- break;
- case BTA_AV_API_START_EVT:
- bta_av_api_to_ssm(p_data);
- break;
- case BTA_AV_API_STOP_EVT:
- bta_av_api_to_ssm(p_data);
- break;
- }
-}
-
-static void bta_av_better_state_machine(tBTA_AV_CB* p_cb, uint16_t event,
- tBTA_AV_DATA* p_data) {
- switch (p_cb->state) {
- case BTA_AV_INIT_ST:
- switch (event) {
- case BTA_AV_API_DISABLE_EVT:
- bta_av_disable(p_cb, p_data);
- break;
- case BTA_AV_API_META_RSP_EVT:
- bta_av_rc_free_rsp(p_cb, p_data);
- break;
- case BTA_AV_AVRC_OPEN_EVT:
- p_cb->state = BTA_AV_OPEN_ST;
- bta_av_rc_opened(p_cb, p_data);
- break;
- case BTA_AV_AVRC_MSG_EVT:
- bta_av_rc_free_browse_msg(p_cb, p_data);
- break;
- }
- break;
- case BTA_AV_OPEN_ST:
- switch (event) {
- case BTA_AV_API_DISABLE_EVT:
- p_cb->state = BTA_AV_INIT_ST;
- bta_av_disable(p_cb, p_data);
- break;
- case BTA_AV_API_REMOTE_CMD_EVT:
- bta_av_rc_remote_cmd(p_cb, p_data);
- break;
- case BTA_AV_API_VENDOR_CMD_EVT:
- bta_av_rc_vendor_cmd(p_cb, p_data);
- break;
- case BTA_AV_API_VENDOR_RSP_EVT:
- bta_av_rc_vendor_rsp(p_cb, p_data);
- break;
- case BTA_AV_API_META_RSP_EVT:
- bta_av_rc_meta_rsp(p_cb, p_data);
- break;
- case BTA_AV_API_RC_CLOSE_EVT:
- bta_av_rc_close(p_cb, p_data);
- break;
- case BTA_AV_AVRC_OPEN_EVT:
- bta_av_rc_opened(p_cb, p_data);
- break;
- case BTA_AV_AVRC_MSG_EVT:
- bta_av_rc_msg(p_cb, p_data);
- break;
- case BTA_AV_AVRC_NONE_EVT:
- p_cb->state = BTA_AV_INIT_ST;
- break;
- }
- break;
- }
-}
-
-void bta_av_sm_execute(tBTA_AV_CB* p_cb, uint16_t event, tBTA_AV_DATA* p_data) {
- APPL_TRACE_EVENT("%s: AV event=0x%x(%s) state=%d(%s)", __func__, event,
- bta_av_evt_code(event), p_cb->state,
- bta_av_st_code(p_cb->state));
- bta_av_better_state_machine(p_cb, event, p_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_hdl_event
- *
- * Description Advanced audio/video main event handling function.
- *
- *
- * Returns bool
- *
- ******************************************************************************/
-bool bta_av_hdl_event(BT_HDR_RIGID* p_msg) {
- if (p_msg->event > BTA_AV_LAST_EVT) {
- return true; /* to free p_msg */
- }
- if (p_msg->event >= BTA_AV_FIRST_NSM_EVT) {
- APPL_TRACE_VERBOSE("%s: AV nsm event=0x%x(%s)", __func__, p_msg->event,
- bta_av_evt_code(p_msg->event));
- bta_av_non_state_machine_event(p_msg->event, (tBTA_AV_DATA*)p_msg);
- } else if (p_msg->event >= BTA_AV_FIRST_SM_EVT &&
- p_msg->event <= BTA_AV_LAST_SM_EVT) {
- APPL_TRACE_VERBOSE("%s: AV sm event=0x%x(%s)", __func__, p_msg->event,
- bta_av_evt_code(p_msg->event));
- /* state machine events */
- bta_av_sm_execute(&bta_av_cb, p_msg->event, (tBTA_AV_DATA*)p_msg);
- } else {
- APPL_TRACE_VERBOSE("%s: bta_handle=0x%x", __func__, p_msg->layer_specific);
- /* stream state machine events */
- bta_av_ssm_execute(bta_av_hndl_to_scb(p_msg->layer_specific), p_msg->event,
- (tBTA_AV_DATA*)p_msg);
- }
- return true;
-}
-
-/*****************************************************************************
- * Debug Functions
- ****************************************************************************/
-/*******************************************************************************
- *
- * Function bta_av_st_code
- *
- * Description
- *
- * Returns char *
- *
- ******************************************************************************/
-static const char* bta_av_st_code(uint8_t state) {
- switch (state) {
- case BTA_AV_INIT_ST:
- return "INIT";
- case BTA_AV_OPEN_ST:
- return "OPEN";
- default:
- return "unknown";
- }
-}
-/*******************************************************************************
- *
- * Function bta_av_evt_code
- *
- * Description
- *
- * Returns char *
- *
- ******************************************************************************/
-const char* bta_av_evt_code(uint16_t evt_code) {
- switch (evt_code) {
- case BTA_AV_API_DISABLE_EVT:
- return "API_DISABLE";
- case BTA_AV_API_REMOTE_CMD_EVT:
- return "API_REMOTE_CMD";
- case BTA_AV_API_VENDOR_CMD_EVT:
- return "API_VENDOR_CMD";
- case BTA_AV_API_VENDOR_RSP_EVT:
- return "API_VENDOR_RSP";
- case BTA_AV_API_META_RSP_EVT:
- return "API_META_RSP_EVT";
- case BTA_AV_API_RC_CLOSE_EVT:
- return "API_RC_CLOSE";
- case BTA_AV_AVRC_OPEN_EVT:
- return "AVRC_OPEN";
- case BTA_AV_AVRC_MSG_EVT:
- return "AVRC_MSG";
- case BTA_AV_AVRC_NONE_EVT:
- return "AVRC_NONE";
-
- case BTA_AV_API_OPEN_EVT:
- return "API_OPEN";
- case BTA_AV_API_CLOSE_EVT:
- return "API_CLOSE";
- case BTA_AV_AP_START_EVT:
- return "AP_START";
- case BTA_AV_AP_STOP_EVT:
- return "AP_STOP";
- case BTA_AV_API_RECONFIG_EVT:
- return "API_RECONFIG";
- case BTA_AV_API_PROTECT_REQ_EVT:
- return "API_PROTECT_REQ";
- case BTA_AV_API_PROTECT_RSP_EVT:
- return "API_PROTECT_RSP";
- case BTA_AV_API_RC_OPEN_EVT:
- return "API_RC_OPEN";
- case BTA_AV_SRC_DATA_READY_EVT:
- return "SRC_DATA_READY";
- case BTA_AV_CI_SETCONFIG_OK_EVT:
- return "CI_SETCONFIG_OK";
- case BTA_AV_CI_SETCONFIG_FAIL_EVT:
- return "CI_SETCONFIG_FAIL";
- case BTA_AV_SDP_DISC_OK_EVT:
- return "SDP_DISC_OK";
- case BTA_AV_SDP_DISC_FAIL_EVT:
- return "SDP_DISC_FAIL";
- case BTA_AV_STR_DISC_OK_EVT:
- return "STR_DISC_OK";
- case BTA_AV_STR_DISC_FAIL_EVT:
- return "STR_DISC_FAIL";
- case BTA_AV_STR_GETCAP_OK_EVT:
- return "STR_GETCAP_OK";
- case BTA_AV_STR_GETCAP_FAIL_EVT:
- return "STR_GETCAP_FAIL";
- case BTA_AV_STR_OPEN_OK_EVT:
- return "STR_OPEN_OK";
- case BTA_AV_STR_OPEN_FAIL_EVT:
- return "STR_OPEN_FAIL";
- case BTA_AV_STR_START_OK_EVT:
- return "STR_START_OK";
- case BTA_AV_STR_START_FAIL_EVT:
- return "STR_START_FAIL";
- case BTA_AV_STR_CLOSE_EVT:
- return "STR_CLOSE";
- case BTA_AV_STR_CONFIG_IND_EVT:
- return "STR_CONFIG_IND";
- case BTA_AV_STR_SECURITY_IND_EVT:
- return "STR_SECURITY_IND";
- case BTA_AV_STR_SECURITY_CFM_EVT:
- return "STR_SECURITY_CFM";
- case BTA_AV_STR_WRITE_CFM_EVT:
- return "STR_WRITE_CFM";
- case BTA_AV_STR_SUSPEND_CFM_EVT:
- return "STR_SUSPEND_CFM";
- case BTA_AV_STR_RECONFIG_CFM_EVT:
- return "STR_RECONFIG_CFM";
- case BTA_AV_AVRC_TIMER_EVT:
- return "AVRC_TIMER";
- case BTA_AV_AVDT_CONNECT_EVT:
- return "AVDT_CONNECT";
- case BTA_AV_AVDT_DISCONNECT_EVT:
- return "AVDT_DISCONNECT";
- case BTA_AV_ROLE_CHANGE_EVT:
- return "ROLE_CHANGE";
- case BTA_AV_AVDT_DELAY_RPT_EVT:
- return "AVDT_DELAY_RPT";
- case BTA_AV_ACP_CONNECT_EVT:
- return "ACP_CONNECT";
- case BTA_AV_API_OFFLOAD_START_EVT:
- return "OFFLOAD_START";
- case BTA_AV_API_OFFLOAD_START_RSP_EVT:
- return "OFFLOAD_START_RSP";
-
- case BTA_AV_API_ENABLE_EVT:
- return "API_ENABLE";
- case BTA_AV_API_REGISTER_EVT:
- return "API_REG";
- case BTA_AV_API_DEREGISTER_EVT:
- return "API_DEREG";
- case BTA_AV_API_DISCONNECT_EVT:
- return "API_DISCNT";
- case BTA_AV_CI_SRC_DATA_READY_EVT:
- return "CI_DATA_READY";
- case BTA_AV_SIG_CHG_EVT:
- return "SIG_CHG";
- case BTA_AV_SIGNALLING_TIMER_EVT:
- return "SIGNALLING_TIMER";
- case BTA_AV_SDP_AVRC_DISC_EVT:
- return "SDP_AVRC_DISC";
- case BTA_AV_AVRC_CLOSE_EVT:
- return "AVRC_CLOSE";
- case BTA_AV_AVRC_BROWSE_OPEN_EVT:
- return "AVRC_BROWSE_OPEN";
- case BTA_AV_AVRC_BROWSE_CLOSE_EVT:
- return "AVRC_BROWSE_CLOSE";
- case BTA_AV_CONN_CHG_EVT:
- return "CONN_CHG";
- case BTA_AV_DEREG_COMP_EVT:
- return "DEREG_COMP";
- case BTA_AV_AVDT_RPT_CONN_EVT:
- return "RPT_CONN";
- case BTA_AV_API_START_EVT:
- return "API_START";
- case BTA_AV_API_STOP_EVT:
- return "API_STOP";
- default:
- return "unknown";
- }
-}
-
-void bta_debug_av_dump(int fd) {
- if (appl_trace_level < BT_TRACE_LEVEL_DEBUG) return;
-
- dprintf(fd, "\nBTA AV State:\n");
- dprintf(fd, " State Machine State: %s\n", bta_av_st_code(bta_av_cb.state));
- dprintf(fd, " SDP A2DP source handle: %d\n", bta_av_cb.sdp_a2dp_handle);
- dprintf(fd, " SDP A2DP sink handle: %d\n", bta_av_cb.sdp_a2dp_snk_handle);
- dprintf(fd, " Features: 0x%x\n", bta_av_cb.features);
- dprintf(fd, " SDP handle: %d\n", bta_av_cb.handle);
- dprintf(fd, " Disabling: %s\n", bta_av_cb.disabling ? "true" : "false");
- dprintf(fd, " SCO occupied: %s\n",
- bta_av_cb.sco_occupied ? "true" : "false");
- dprintf(fd, " Connected audio channels: %d\n", bta_av_cb.audio_open_cnt);
- dprintf(fd, " Connected audio channels mask: 0x%x\n", bta_av_cb.conn_audio);
- dprintf(fd, " Registered audio channels mask: 0x%x\n", bta_av_cb.reg_audio);
- dprintf(fd, " Connected LCBs mask: 0x%x\n", bta_av_cb.conn_lcb);
- dprintf(fd, " Offload start pending handle: %d\n",
- bta_av_cb.offload_start_pending_acl_hdl);
- dprintf(fd, " Offload started handle: %d\n",
- bta_av_cb.offload_started_acl_hdl);
-
- for (size_t i = 0; i < sizeof(bta_av_cb.lcb) / sizeof(bta_av_cb.lcb[0]);
- i++) {
- const tBTA_AV_LCB& lcb = bta_av_cb.lcb[i];
- if (lcb.addr.IsEmpty()) {
- continue;
- }
- dprintf(fd, "\n Link control block: %zu peer: %s\n", i,
- lcb.addr.ToString().c_str());
- dprintf(fd, " Connected stream handle mask: 0x%x\n", lcb.conn_msk);
- dprintf(fd, " Index(+1) to LCB: %d\n", lcb.lidx);
- }
- for (size_t i = 0; i < BTA_AV_NUM_STRS; i++) {
- const tBTA_AV_SCB* p_scb = bta_av_cb.p_scb[i];
- if (p_scb == nullptr) {
- continue;
- }
- if (p_scb->PeerAddress().IsEmpty()) {
- continue;
- }
- dprintf(fd, "\n BTA ID: %zu peer: %s\n", i,
- p_scb->PeerAddress().ToString().c_str());
- dprintf(fd, " SDP discovery started: %s\n",
- p_scb->sdp_discovery_started ? "true" : "false");
- for (size_t j = 0; j < BTAV_A2DP_CODEC_INDEX_MAX; j++) {
- const tBTA_AV_SEP& sep = p_scb->seps[j];
- if (sep.av_handle == 0) {
- continue;
- }
- dprintf(fd, " SEP ID: %zu\n", j);
- dprintf(fd, " SEP AVDTP handle: %d\n", sep.av_handle);
- dprintf(fd, " Local SEP type: %d\n", sep.tsep);
- dprintf(fd, " Codec: %s\n", A2DP_CodecName(sep.codec_info));
- }
- dprintf(fd, " BTA info tag: %d\n", p_scb->q_tag);
- dprintf(fd, " API Open peer: %s\n",
- p_scb->q_info.open.bd_addr.ToString().c_str());
- dprintf(fd, " Use AVRCP: %s\n",
- p_scb->q_info.open.use_rc ? "true" : "false");
- dprintf(fd, " Switch result: %d\n", p_scb->q_info.open.switch_res);
- dprintf(fd, " Initiator UUID: 0x%x\n", p_scb->q_info.open.uuid);
- dprintf(fd, " Saved API Open peer: %s\n",
- p_scb->open_api.bd_addr.ToString().c_str());
- dprintf(fd, " Use AVRCP: %s\n",
- p_scb->open_api.use_rc ? "true" : "false");
- dprintf(fd, " Switch result: %d\n", p_scb->open_api.switch_res);
- dprintf(fd, " Initiator UUID: 0x%x\n", p_scb->open_api.uuid);
- dprintf(fd, " Link signalling timer: %s\n",
- alarm_is_scheduled(p_scb->link_signalling_timer) ? "Scheduled"
- : "Not scheduled");
- dprintf(fd, " Accept signalling timer: %s\n",
- alarm_is_scheduled(p_scb->accept_signalling_timer)
- ? "Scheduled"
- : "Not scheduled");
- // TODO: Print p_scb->sep_info[], cfg, avrc_ct_timer, current_codec ?
- dprintf(fd, " L2CAP Channel ID: %d\n", p_scb->l2c_cid);
- dprintf(fd, " Stream MTU: %d\n", p_scb->stream_mtu);
- dprintf(fd, " AVDTP version: 0x%x\n", p_scb->AvdtpVersion());
- dprintf(fd, " Media type: %d\n", p_scb->media_type);
- dprintf(fd, " Congested: %s\n", p_scb->cong ? "true" : "false");
- dprintf(fd, " Open status: %d\n", p_scb->open_status);
- dprintf(fd, " Channel: %d\n", p_scb->chnl);
- dprintf(fd, " BTA handle: 0x%x\n", p_scb->hndl);
- dprintf(fd, " Protocol service capabilities mask: 0x%x\n",
- p_scb->cur_psc_mask);
- dprintf(fd, " AVDTP handle: %d\n", p_scb->avdt_handle);
- dprintf(fd, " Stream control block index: %d\n", p_scb->hdi);
- dprintf(fd, " State machine state: %s(%d)\n",
- bta_av_sst_code(p_scb->state), p_scb->state);
- dprintf(fd, " AVDTP label: 0x%x\n", p_scb->avdt_label);
- dprintf(fd, " Application ID: %d\n", p_scb->app_id);
- dprintf(fd, " Role: 0x%x\n", p_scb->role);
- dprintf(fd, " Queued L2CAP buffers: %d\n", p_scb->l2c_bufs);
- dprintf(fd, " AVRCP allowed: %s\n", p_scb->use_rc ? "true" : "false");
- dprintf(fd, " Stream started: %s\n", p_scb->started ? "true" : "false");
- dprintf(fd, " Stream call-out started: %d\n", p_scb->co_started);
- dprintf(fd, " AVDTP Reconfig supported: %s\n",
- p_scb->recfg_sup ? "true" : "false");
- dprintf(fd, " AVDTP Suspend supported: %s\n",
- p_scb->suspend_sup ? "true" : "false");
- dprintf(fd, " Deregistering: %s\n",
- p_scb->deregistering ? "true" : "false");
- dprintf(fd, " SCO automatic Suspend: %s\n",
- p_scb->sco_suspend ? "true" : "false");
- dprintf(fd, " Incoming/outgoing connection collusion mask: 0x%x\n",
- p_scb->coll_mask);
- dprintf(fd, " Wait mask: 0x%x\n", p_scb->wait);
- dprintf(fd, " Don't use RTP header: %s\n",
- p_scb->no_rtp_header ? "true" : "false");
- dprintf(fd, " Intended UUID of Initiator to connect to: 0x%x\n",
- p_scb->uuid_int);
- }
-}
diff --git a/bta/av/bta_av_ssm.cc b/bta/av/bta_av_ssm.cc
deleted file mode 100644
index 1a6922c..0000000
--- a/bta/av/bta_av_ssm.cc
+++ /dev/null
@@ -1,593 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2004-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the stream state machine for the BTA advanced audio/video.
- *
- ******************************************************************************/
-
-#include "bt_target.h" // Must be first to define build configuration
-
-#include "bta/av/bta_av_int.h"
-#include "osi/include/log.h"
-
-/*****************************************************************************
- * Constants and types
- ****************************************************************************/
-
-/* state machine states */
-enum {
- BTA_AV_INIT_SST,
- BTA_AV_INCOMING_SST,
- BTA_AV_OPENING_SST,
- BTA_AV_OPEN_SST,
- BTA_AV_RCFG_SST,
- BTA_AV_CLOSING_SST
-};
-
-static void bta_av_better_stream_state_machine(tBTA_AV_SCB* p_scb,
- uint16_t event,
- tBTA_AV_DATA* p_data) {
- uint8_t previous_state = p_scb->state;
- tBTA_AV_ACT event_handler1 = nullptr;
- tBTA_AV_ACT event_handler2 = nullptr;
- switch (p_scb->state) {
- case BTA_AV_INIT_SST:
- switch (event) {
- case BTA_AV_API_OPEN_EVT:
- p_scb->state = BTA_AV_OPENING_SST;
- event_handler1 = &bta_av_do_disc_a2dp;
- break;
- case BTA_AV_API_CLOSE_EVT:
- event_handler1 = &bta_av_cleanup;
- break;
- case BTA_AV_SDP_DISC_OK_EVT:
- event_handler1 = &bta_av_free_sdb;
- break;
- case BTA_AV_SDP_DISC_FAIL_EVT:
- event_handler1 = &bta_av_free_sdb;
- break;
- case BTA_AV_STR_CONFIG_IND_EVT:
- p_scb->state = BTA_AV_INCOMING_SST;
- event_handler1 = &bta_av_config_ind;
- break;
- case BTA_AV_ACP_CONNECT_EVT:
- p_scb->state = BTA_AV_INCOMING_SST;
- break;
- case BTA_AV_API_OFFLOAD_START_EVT:
- event_handler1 = &bta_av_offload_req;
- break;
- case BTA_AV_API_OFFLOAD_START_RSP_EVT:
- event_handler1 = &bta_av_offload_rsp;
- break;
- }
- break;
- case BTA_AV_INCOMING_SST:
- switch (event) {
- case BTA_AV_API_OPEN_EVT:
- event_handler1 = &bta_av_open_at_inc;
- break;
- case BTA_AV_API_CLOSE_EVT:
- p_scb->state = BTA_AV_CLOSING_SST;
- event_handler1 = &bta_av_cco_close;
- event_handler2 = &bta_av_disconnect_req;
- break;
- case BTA_AV_API_PROTECT_REQ_EVT:
- event_handler1 = &bta_av_security_req;
- break;
- case BTA_AV_API_PROTECT_RSP_EVT:
- event_handler1 = &bta_av_security_rsp;
- break;
- case BTA_AV_CI_SETCONFIG_OK_EVT:
- event_handler1 = &bta_av_setconfig_rsp;
- event_handler2 = &bta_av_st_rc_timer;
- break;
- case BTA_AV_CI_SETCONFIG_FAIL_EVT:
- p_scb->state = BTA_AV_INIT_SST;
- event_handler1 = &bta_av_setconfig_rej;
- event_handler2 = &bta_av_cleanup;
- break;
- case BTA_AV_SDP_DISC_OK_EVT:
- event_handler1 = &bta_av_free_sdb;
- break;
- case BTA_AV_SDP_DISC_FAIL_EVT:
- event_handler1 = &bta_av_free_sdb;
- break;
- case BTA_AV_STR_DISC_OK_EVT:
- event_handler1 = &bta_av_disc_res_as_acp;
- break;
- case BTA_AV_STR_GETCAP_OK_EVT:
- event_handler1 = &bta_av_save_caps;
- break;
- case BTA_AV_STR_OPEN_OK_EVT:
- p_scb->state = BTA_AV_OPEN_SST;
- event_handler1 = &bta_av_str_opened;
- break;
- case BTA_AV_STR_CLOSE_EVT:
- p_scb->state = BTA_AV_INIT_SST;
- event_handler1 = &bta_av_cco_close;
- event_handler2 = &bta_av_cleanup;
- break;
- case BTA_AV_STR_CONFIG_IND_EVT:
- event_handler1 = &bta_av_config_ind;
- break;
- case BTA_AV_STR_SECURITY_IND_EVT:
- event_handler1 = &bta_av_security_ind;
- break;
- case BTA_AV_STR_SECURITY_CFM_EVT:
- event_handler1 = &bta_av_security_cfm;
- break;
- case BTA_AV_AVDT_DISCONNECT_EVT:
- p_scb->state = BTA_AV_CLOSING_SST;
- event_handler1 = &bta_av_cco_close;
- event_handler2 = &bta_av_disconnect_req;
- break;
- case BTA_AV_AVDT_DELAY_RPT_EVT:
- event_handler1 = &bta_av_delay_co;
- break;
- case BTA_AV_API_OFFLOAD_START_EVT:
- event_handler1 = &bta_av_offload_req;
- break;
- case BTA_AV_API_OFFLOAD_START_RSP_EVT:
- event_handler1 = &bta_av_offload_rsp;
- break;
- }
- break;
- case BTA_AV_OPENING_SST:
- switch (event) {
- case BTA_AV_API_CLOSE_EVT:
- p_scb->state = BTA_AV_CLOSING_SST;
- event_handler1 = &bta_av_do_close;
- break;
- case BTA_AV_API_PROTECT_REQ_EVT:
- event_handler1 = &bta_av_security_req;
- break;
- case BTA_AV_API_PROTECT_RSP_EVT:
- event_handler1 = &bta_av_security_rsp;
- break;
- case BTA_AV_SDP_DISC_OK_EVT:
- event_handler1 = &bta_av_connect_req;
- break;
- case BTA_AV_SDP_DISC_FAIL_EVT:
- event_handler1 = &bta_av_connect_req;
- break;
- case BTA_AV_STR_DISC_OK_EVT:
- event_handler1 = &bta_av_disc_results;
- break;
- case BTA_AV_STR_DISC_FAIL_EVT:
- p_scb->state = BTA_AV_CLOSING_SST;
- event_handler1 = &bta_av_open_failed;
- break;
- case BTA_AV_STR_GETCAP_OK_EVT:
- event_handler1 = &bta_av_getcap_results;
- break;
- case BTA_AV_STR_GETCAP_FAIL_EVT:
- p_scb->state = BTA_AV_CLOSING_SST;
- event_handler1 = &bta_av_open_failed;
- break;
- case BTA_AV_STR_OPEN_OK_EVT:
- p_scb->state = BTA_AV_OPEN_SST;
- event_handler1 = &bta_av_st_rc_timer;
- event_handler2 = &bta_av_str_opened;
- break;
- case BTA_AV_STR_OPEN_FAIL_EVT:
- p_scb->state = BTA_AV_CLOSING_SST;
- event_handler1 = &bta_av_open_failed;
- break;
- case BTA_AV_STR_CONFIG_IND_EVT:
- p_scb->state = BTA_AV_INCOMING_SST;
- event_handler1 = &bta_av_config_ind;
- break;
- case BTA_AV_STR_SECURITY_IND_EVT:
- event_handler1 = &bta_av_security_ind;
- break;
- case BTA_AV_STR_SECURITY_CFM_EVT:
- event_handler1 = &bta_av_security_cfm;
- break;
- case BTA_AV_AVRC_TIMER_EVT:
- event_handler1 = &bta_av_switch_role;
- break;
- case BTA_AV_AVDT_CONNECT_EVT:
- event_handler1 = &bta_av_discover_req;
- break;
- case BTA_AV_AVDT_DISCONNECT_EVT:
- p_scb->state = BTA_AV_INIT_SST;
- event_handler1 = &bta_av_conn_failed;
- break;
- case BTA_AV_ROLE_CHANGE_EVT:
- event_handler1 = &bta_av_role_res;
- break;
- case BTA_AV_AVDT_DELAY_RPT_EVT:
- event_handler1 = &bta_av_delay_co;
- break;
- case BTA_AV_API_OFFLOAD_START_EVT:
- event_handler1 = &bta_av_offload_req;
- break;
- case BTA_AV_API_OFFLOAD_START_RSP_EVT:
- event_handler1 = &bta_av_offload_rsp;
- break;
- }
- break;
- case BTA_AV_OPEN_SST:
- switch (event) {
- case BTA_AV_API_CLOSE_EVT:
- p_scb->state = BTA_AV_CLOSING_SST;
- event_handler1 = &bta_av_do_close;
- break;
- case BTA_AV_AP_START_EVT:
- event_handler1 = &bta_av_do_start;
- break;
- case BTA_AV_AP_STOP_EVT:
- event_handler1 = &bta_av_str_stopped;
- break;
- case BTA_AV_API_RECONFIG_EVT:
- p_scb->state = BTA_AV_RCFG_SST;
- event_handler1 = &bta_av_reconfig;
- break;
- case BTA_AV_API_PROTECT_REQ_EVT:
- event_handler1 = &bta_av_security_req;
- break;
- case BTA_AV_API_PROTECT_RSP_EVT:
- event_handler1 = &bta_av_security_rsp;
- break;
- case BTA_AV_API_RC_OPEN_EVT:
- event_handler1 = &bta_av_set_use_rc;
- break;
- case BTA_AV_SRC_DATA_READY_EVT:
- event_handler1 = &bta_av_data_path;
- break;
- case BTA_AV_SDP_DISC_OK_EVT:
- event_handler1 = &bta_av_free_sdb;
- break;
- case BTA_AV_SDP_DISC_FAIL_EVT:
- event_handler1 = &bta_av_free_sdb;
- break;
- case BTA_AV_STR_GETCAP_OK_EVT:
- event_handler1 = &bta_av_save_caps;
- break;
- case BTA_AV_STR_START_OK_EVT:
- event_handler1 = &bta_av_start_ok;
- break;
- case BTA_AV_STR_START_FAIL_EVT:
- event_handler1 = &bta_av_start_failed;
- break;
- case BTA_AV_STR_CLOSE_EVT:
- p_scb->state = BTA_AV_INIT_SST;
- event_handler1 = &bta_av_str_closed;
- break;
- case BTA_AV_STR_CONFIG_IND_EVT:
- event_handler1 = &bta_av_setconfig_rej;
- break;
- case BTA_AV_STR_SECURITY_IND_EVT:
- event_handler1 = &bta_av_security_ind;
- break;
- case BTA_AV_STR_SECURITY_CFM_EVT:
- event_handler1 = &bta_av_security_cfm;
- break;
- case BTA_AV_STR_WRITE_CFM_EVT:
- event_handler1 = &bta_av_clr_cong;
- event_handler2 = &bta_av_data_path;
- break;
- case BTA_AV_STR_SUSPEND_CFM_EVT:
- event_handler1 = &bta_av_suspend_cfm;
- break;
- case BTA_AV_AVRC_TIMER_EVT:
- event_handler1 = &bta_av_open_rc;
- break;
- case BTA_AV_AVDT_DISCONNECT_EVT:
- p_scb->state = BTA_AV_INIT_SST;
- event_handler1 = &bta_av_str_closed;
- break;
- case BTA_AV_ROLE_CHANGE_EVT:
- event_handler1 = &bta_av_role_res;
- break;
- case BTA_AV_AVDT_DELAY_RPT_EVT:
- event_handler1 = &bta_av_delay_co;
- break;
- case BTA_AV_API_OFFLOAD_START_EVT:
- event_handler1 = &bta_av_offload_req;
- break;
- case BTA_AV_API_OFFLOAD_START_RSP_EVT:
- event_handler1 = &bta_av_offload_rsp;
- break;
- }
- break;
- case BTA_AV_RCFG_SST:
- switch (event) {
- case BTA_AV_API_CLOSE_EVT:
- p_scb->state = BTA_AV_CLOSING_SST;
- event_handler1 = &bta_av_disconnect_req;
- break;
- case BTA_AV_API_RECONFIG_EVT:
- event_handler1 = &bta_av_reconfig;
- break;
- case BTA_AV_SDP_DISC_OK_EVT:
- event_handler1 = &bta_av_free_sdb;
- break;
- case BTA_AV_SDP_DISC_FAIL_EVT:
- event_handler1 = &bta_av_free_sdb;
- break;
- case BTA_AV_STR_DISC_OK_EVT:
- event_handler1 = &bta_av_disc_results;
- break;
- case BTA_AV_STR_DISC_FAIL_EVT:
- p_scb->state = BTA_AV_INIT_SST;
- event_handler1 = &bta_av_str_closed;
- break;
- case BTA_AV_STR_GETCAP_OK_EVT:
- event_handler1 = &bta_av_getcap_results;
- break;
- case BTA_AV_STR_GETCAP_FAIL_EVT:
- p_scb->state = BTA_AV_INIT_SST;
- event_handler1 = &bta_av_str_closed;
- break;
- case BTA_AV_STR_OPEN_OK_EVT:
- p_scb->state = BTA_AV_OPEN_SST;
- event_handler1 = &bta_av_rcfg_str_ok;
- break;
- case BTA_AV_STR_OPEN_FAIL_EVT:
- event_handler1 = &bta_av_rcfg_failed;
- break;
- case BTA_AV_STR_CLOSE_EVT:
- event_handler1 = &bta_av_rcfg_connect;
- break;
- case BTA_AV_STR_CONFIG_IND_EVT:
- event_handler1 = &bta_av_setconfig_rej;
- break;
- case BTA_AV_STR_SUSPEND_CFM_EVT:
- event_handler1 = &bta_av_suspend_cfm;
- event_handler2 = &bta_av_suspend_cont;
- break;
- case BTA_AV_STR_RECONFIG_CFM_EVT:
- event_handler1 = &bta_av_rcfg_cfm;
- break;
- case BTA_AV_AVDT_CONNECT_EVT:
- event_handler1 = &bta_av_rcfg_open;
- break;
- case BTA_AV_AVDT_DISCONNECT_EVT:
- event_handler1 = &bta_av_rcfg_discntd;
- break;
- case BTA_AV_AVDT_DELAY_RPT_EVT:
- event_handler1 = &bta_av_delay_co;
- break;
- case BTA_AV_API_OFFLOAD_START_EVT:
- event_handler1 = &bta_av_offload_req;
- break;
- case BTA_AV_API_OFFLOAD_START_RSP_EVT:
- event_handler1 = &bta_av_offload_rsp;
- break;
- }
- break;
- case BTA_AV_CLOSING_SST:
- switch (event) {
- case BTA_AV_API_CLOSE_EVT:
- event_handler1 = &bta_av_disconnect_req;
- break;
- case BTA_AV_SDP_DISC_OK_EVT:
- p_scb->state = BTA_AV_INIT_SST;
- event_handler1 = &bta_av_sdp_failed;
- break;
- case BTA_AV_SDP_DISC_FAIL_EVT:
- p_scb->state = BTA_AV_INIT_SST;
- event_handler1 = &bta_av_sdp_failed;
- break;
- case BTA_AV_STR_OPEN_OK_EVT:
- event_handler1 = &bta_av_do_close;
- break;
- case BTA_AV_STR_OPEN_FAIL_EVT:
- event_handler1 = &bta_av_disconnect_req;
- break;
- case BTA_AV_STR_CLOSE_EVT:
- event_handler1 = &bta_av_disconnect_req;
- break;
- case BTA_AV_STR_CONFIG_IND_EVT:
- event_handler1 = &bta_av_setconfig_rej;
- break;
- case BTA_AV_STR_SECURITY_IND_EVT:
- event_handler1 = &bta_av_security_rej;
- break;
- case BTA_AV_AVDT_DISCONNECT_EVT:
- p_scb->state = BTA_AV_INIT_SST;
- event_handler1 = &bta_av_str_closed;
- break;
- case BTA_AV_API_OFFLOAD_START_EVT:
- event_handler1 = &bta_av_offload_req;
- break;
- case BTA_AV_API_OFFLOAD_START_RSP_EVT:
- event_handler1 = &bta_av_offload_rsp;
- break;
- }
- break;
- }
-
- if (previous_state != p_scb->state) {
- LOG_INFO("peer %s p_scb=%#x(%p) AV event=0x%x(%s) state=%d(%s) -> %d(%s)",
- p_scb->PeerAddress().ToString().c_str(), p_scb->hndl, p_scb, event,
- bta_av_evt_code(event), previous_state,
- bta_av_sst_code(previous_state), p_scb->state,
- bta_av_sst_code(p_scb->state));
-
- } else {
- LOG_DEBUG("peer %s p_scb=%#x(%p) AV event=0x%x(%s) state=%d(%s)",
- p_scb->PeerAddress().ToString().c_str(), p_scb->hndl, p_scb,
- event, bta_av_evt_code(event), p_scb->state,
- bta_av_sst_code(p_scb->state));
- }
-
- if (event_handler1 != nullptr) {
- event_handler1(p_scb, p_data);
- }
- if (event_handler2 != nullptr) {
- event_handler2(p_scb, p_data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_av_ssm_execute
- *
- * Description Stream state machine event handling function for AV
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_av_ssm_execute(tBTA_AV_SCB* p_scb, uint16_t event,
- tBTA_AV_DATA* p_data) {
- if (p_scb == NULL) {
- /* this stream is not registered */
- APPL_TRACE_EVENT("%s: AV channel not registered", __func__);
- return;
- }
-
- bta_av_better_stream_state_machine(p_scb, event, p_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_av_is_scb_opening
- *
- * Description Returns true is scb is in opening state.
- *
- *
- * Returns true if scb is in opening state.
- *
- ******************************************************************************/
-bool bta_av_is_scb_opening(tBTA_AV_SCB* p_scb) {
- bool is_opening = false;
-
- if (p_scb) {
- if (p_scb->state == BTA_AV_OPENING_SST) is_opening = true;
- }
-
- return is_opening;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_is_scb_incoming
- *
- * Description Returns true is scb is in incoming state.
- *
- *
- * Returns true if scb is in incoming state.
- *
- ******************************************************************************/
-bool bta_av_is_scb_incoming(tBTA_AV_SCB* p_scb) {
- bool is_incoming = false;
-
- if (p_scb) {
- if (p_scb->state == BTA_AV_INCOMING_SST) is_incoming = true;
- }
-
- return is_incoming;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_set_scb_sst_init
- *
- * Description Set SST state to INIT.
- * Use this function to change SST outside of state machine.
- *
- * Returns None
- *
- ******************************************************************************/
-void bta_av_set_scb_sst_init(tBTA_AV_SCB* p_scb) {
- if (p_scb == nullptr) {
- return;
- }
-
- uint8_t next_state = BTA_AV_INIT_SST;
-
- APPL_TRACE_VERBOSE(
- "%s: peer %s AV (hndl=0x%x) state=%d(%s) next state=%d(%s) p_scb=%p",
- __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->hndl,
- p_scb->state, bta_av_sst_code(p_scb->state), next_state,
- bta_av_sst_code(next_state), p_scb);
-
- p_scb->state = next_state;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_is_scb_init
- *
- * Description Returns true is scb is in init state.
- *
- *
- * Returns true if scb is in incoming state.
- *
- ******************************************************************************/
-bool bta_av_is_scb_init(tBTA_AV_SCB* p_scb) {
- bool is_init = false;
-
- if (p_scb) {
- if (p_scb->state == BTA_AV_INIT_SST) is_init = true;
- }
-
- return is_init;
-}
-
-/*******************************************************************************
- *
- * Function bta_av_set_scb_sst_incoming
- *
- * Description Set SST state to incoming.
- * Use this function to change SST outside of state machine.
- *
- * Returns None
- *
- ******************************************************************************/
-void bta_av_set_scb_sst_incoming(tBTA_AV_SCB* p_scb) {
- if (p_scb) {
- p_scb->state = BTA_AV_INCOMING_SST;
- }
-}
-
-/*****************************************************************************
- * Debug Functions
- ****************************************************************************/
-/*******************************************************************************
- *
- * Function bta_av_sst_code
- *
- * Description
- *
- * Returns char *
- *
- ******************************************************************************/
-const char* bta_av_sst_code(uint8_t state) {
- switch (state) {
- case BTA_AV_INIT_SST:
- return "INIT";
- case BTA_AV_INCOMING_SST:
- return "INCOMING";
- case BTA_AV_OPENING_SST:
- return "OPENING";
- case BTA_AV_OPEN_SST:
- return "OPEN";
- case BTA_AV_RCFG_SST:
- return "RCFG";
- case BTA_AV_CLOSING_SST:
- return "CLOSING";
- default:
- return "unknown";
- }
-}
diff --git a/bta/csis/csis_client.cc b/bta/csis/csis_client.cc
deleted file mode 100644
index d5ab973..0000000
--- a/bta/csis/csis_client.cc
+++ /dev/null
@@ -1,1925 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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 <base/bind.h>
-#include <base/callback.h>
-#include <base/logging.h>
-#include <base/strings/string_number_conversions.h>
-#include <hardware/bt_csis.h>
-#include <hardware/bt_gatt_types.h>
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "advertise_data_parser.h"
-#include "bta_api.h"
-#include "bta_csis_api.h"
-#include "bta_gatt_api.h"
-#include "bta_gatt_queue.h"
-#include "bta_groups.h"
-#include "btif_storage.h"
-#include "csis_types.h"
-#include "gap_api.h"
-#include "gatt_api.h"
-#include "osi/include/osi.h"
-#include "osi/include/properties.h"
-#include "stack/btm/btm_dev.h"
-#include "stack/btm/btm_int.h"
-#include "stack/btm/btm_sec.h"
-#include "stack/crypto_toolbox/crypto_toolbox.h"
-
-using base::Closure;
-using bluetooth::Uuid;
-using bluetooth::csis::ConnectionState;
-using bluetooth::csis::CsisClient;
-using bluetooth::csis::CsisDevice;
-using bluetooth::csis::CsisDiscoveryState;
-using bluetooth::csis::CsisGroup;
-using bluetooth::csis::CsisGroupLockStatus;
-using bluetooth::csis::CsisInstance;
-using bluetooth::csis::CsisLockCb;
-using bluetooth::csis::CsisLockState;
-using bluetooth::csis::kCsisLockUuid;
-using bluetooth::csis::kCsisRankUuid;
-using bluetooth::csis::kCsisServiceUuid;
-using bluetooth::csis::kCsisSirkUuid;
-using bluetooth::csis::kCsisSizeUuid;
-
-using bluetooth::groups::DeviceGroups;
-using bluetooth::groups::DeviceGroupsCallbacks;
-
-namespace {
-class CsisClientImpl;
-CsisClientImpl* instance;
-DeviceGroupsCallbacks* device_group_callbacks;
-
-/**
- * -----------------------------------------------------------------------------
- * Coordinated Set Service - Client role
- * -----------------------------------------------------------------------------
- *
- * CSIP allows to organize audio servers into sets e.g. Stereo Set, 5.1 Set
- * and speed up connecting it.
- *
- * Since leaudio has already grouping API it was decided to integrate here CSIS
- * and allow it to group devices semi-automatically.
- *
- * Flow:
- * If connected device contains CSIS services, and it is included into CAP
- * service or is not included at all, implementation reads all its
- * characteristisc. The only mandatory characteristic is Set Identity Resolving
- * Key (SIRK) and once this is read implementation assumes there is at least 2
- * devices in the set and start to search for other members by looking for new
- * Advertising Type (RSI Type) and Resolvable Set Identifier (RSI) in it.
- * In the meantime other CSIS characteristics are read and Set Size might be
- * updated. When new set member is found, there is callback called to upper
- * layer with the address and group id for which member has been found. During
- * this time Search is stopped. Upper layers bonds new devices and connect Le
- * Audio profile. If there are other members to find, implementations repeats
- * the procedure.
- *
- */
-
-class CsisClientImpl : public CsisClient {
- static constexpr uint8_t CSIS_STORAGE_CURRENT_LAYOUT_MAGIC = 0x10;
- static constexpr size_t CSIS_STORAGE_HEADER_SZ =
- sizeof(CSIS_STORAGE_CURRENT_LAYOUT_MAGIC) +
- sizeof(uint8_t); /* num_of_sets */
- static constexpr size_t CSIS_STORAGE_ENTRY_SZ =
- sizeof(uint8_t) /* set_id */ + sizeof(uint8_t) /* desired_size */ +
- Octet16().size();
-
- public:
- CsisClientImpl(bluetooth::csis::CsisClientCallbacks* callbacks,
- Closure initCb)
- : gatt_if_(0), callbacks_(callbacks) {
- BTA_GATTC_AppRegister(
- [](tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
- if (instance && p_data) instance->GattcCallback(event, p_data);
- },
- base::Bind(
- [](Closure initCb, uint8_t client_id, uint8_t status) {
- if (status != GATT_SUCCESS) {
- LOG(ERROR) << "Can't start Coordinated Set Service client "
- "profile - no gatt clients left!";
- return;
- }
- instance->gatt_if_ = client_id;
- initCb.Run();
-
- DeviceGroups::Initialize(device_group_callbacks);
- instance->dev_groups_ = DeviceGroups::Get();
- },
- initCb),
- true);
-
- DLOG(INFO) << __func__ << " Background scan enabled";
- CsisObserverSetBackground(true);
- }
-
- ~CsisClientImpl() override = default;
-
- std::shared_ptr<bluetooth::csis::CsisGroup> AssignCsisGroup(
- const RawAddress& address, int group_id,
- bool create_group_if_non_existing, const bluetooth::Uuid& uuid) {
- auto csis_group = FindCsisGroup(group_id);
- if (!csis_group) {
- if (create_group_if_non_existing) {
- /* Let's create a group */
- auto g = std::make_shared<CsisGroup>(group_id, uuid);
- csis_groups_.push_back(g);
- csis_group = FindCsisGroup(group_id);
- } else {
- LOG(ERROR) << __func__ << ": Missing group - that shall not happen";
- return nullptr;
- }
- }
-
- auto device = FindDeviceByAddress(address);
- if (device == nullptr) {
- auto dev = std::make_shared<CsisDevice>(address, false);
- devices_.push_back(dev);
- device = FindDeviceByAddress(address);
- }
-
- if (!csis_group->IsDeviceInTheGroup(device)) csis_group->AddDevice(device);
-
- return csis_group;
- }
-
- void OnGroupAddedCb(const RawAddress& address, const bluetooth::Uuid& uuid,
- int group_id) {
- DLOG(INFO) << __func__ << " address: " << address << " uuid: " << uuid
- << " group_id: " << group_id;
-
- AssignCsisGroup(address, group_id, true, uuid);
- }
-
- void OnGroupMemberAddedCb(const RawAddress& address, int group_id) {
- DLOG(INFO) << __func__ << " address: " << address
- << " group_id: " << group_id;
-
- AssignCsisGroup(address, group_id, false, Uuid::kEmpty);
- }
-
- void OnGroupRemovedCb(const bluetooth::Uuid& uuid, int group_id) {
- RemoveCsisGroup(group_id);
- }
-
- void OnGroupMemberRemovedCb(const RawAddress& address, int group_id) {
- DLOG(INFO) << __func__ << ": " << address << " group_id: " << group_id;
-
- auto device = FindDeviceByAddress(address);
- if (device) RemoveCsisDevice(device, group_id);
- }
-
- void OnGroupAddFromStorageCb(const RawAddress& address,
- const bluetooth::Uuid& uuid, int group_id) {
- auto device = FindDeviceByAddress(address);
- if (device == nullptr) return;
-
- auto csis_group = FindCsisGroup(group_id);
- if (csis_group == nullptr) {
- LOG(ERROR) << __func__ << "the csis group (id: " << group_id
- << ") does not exist";
- return;
- }
-
- if (!csis_group->IsDeviceInTheGroup(device)) {
- LOG(ERROR) << __func__ << "the csis group (id: " << group_id
- << ") does contain the device: " << address;
- return;
- }
-
- if (csis_group->GetUuid() == Uuid::kEmpty) {
- csis_group->SetUuid(uuid);
- }
-
- callbacks_->OnDeviceAvailable(device->addr, csis_group->GetGroupId(),
- csis_group->GetDesiredSize(), uuid);
- }
-
- void Connect(const RawAddress& address) override {
- DLOG(INFO) << __func__ << ": " << address;
-
- auto device = FindDeviceByAddress(address);
- if (device == nullptr) {
- devices_.emplace_back(std::make_shared<CsisDevice>(address, true));
- } else {
- device->connecting_actively = true;
- }
-
- BTA_GATTC_Open(gatt_if_, address, true, false);
- }
-
- void Disconnect(const RawAddress& addr) override {
- DLOG(INFO) << __func__ << ": " << addr;
-
- btif_storage_set_csis_autoconnect(addr, false);
-
- auto device = FindDeviceByAddress(addr);
- if (device == nullptr) {
- LOG(WARNING) << "Device not connected to profile" << addr;
- return;
- }
-
- /* Removes all active connections or registrations for connection */
- if (device->IsConnected()) {
- BTA_GATTC_Close(device->conn_id);
- } else {
- BTA_GATTC_CancelOpen(gatt_if_, addr, false);
- DoDisconnectCleanUp(device);
- }
- }
-
- void RemoveDevice(const RawAddress& addr) override {
- DLOG(INFO) << __func__ << ": " << addr;
-
- auto device = FindDeviceByAddress(addr);
- if (!device) return;
-
- Disconnect(addr);
-
- dev_groups_->RemoveDevice(addr);
- btif_storage_remove_csis_device(addr);
- }
-
- int GetGroupId(const RawAddress& addr, Uuid uuid) override {
- auto device = FindDeviceByAddress(addr);
- if (device == nullptr) return bluetooth::groups::kGroupUnknown;
-
- int group_id = dev_groups_->GetGroupId(addr, uuid);
- auto csis_group = FindCsisGroup(group_id);
- if (csis_group == nullptr) return bluetooth::groups::kGroupUnknown;
-
- return csis_group->GetGroupId();
- }
-
- void HandleCsisLockProcedureError(
- std::shared_ptr<CsisGroup>& csis_group,
- std::shared_ptr<CsisDevice>& csis_device,
- CsisGroupLockStatus status =
- CsisGroupLockStatus::FAILED_LOCKED_BY_OTHER) {
- /* Clear information about ongoing lock procedure */
- CsisLockCb cb = csis_group->GetLockCb();
- csis_group->SetTargetLockState(CsisLockState::CSIS_STATE_UNSET);
-
- int group_id = csis_group->GetGroupId();
- CsisLockState current_lock_state = csis_group->GetCurrentLockState();
- /* Send unlock to previous devices. It shall be done in reverse order. */
- auto prev_dev = csis_group->GetPrevDevice(csis_device);
- while (prev_dev) {
- if (prev_dev->IsConnected()) {
- auto prev_csis_instance = prev_dev->GetCsisInstanceByGroupId(group_id);
- LOG_ASSERT(prev_csis_instance) << " prev_csis_instance does not exist!";
- SetLock(prev_dev, prev_csis_instance, current_lock_state);
- }
- prev_dev = csis_group->GetPrevDevice(prev_dev);
- }
- /* Call application callback */
- NotifyGroupStatus(group_id, false, status, std::move(cb));
- }
-
- void OnGattCsisWriteLockRsp(uint16_t conn_id, tGATT_STATUS status,
- uint16_t handle, void* data) {
- auto device = FindDeviceByConnId(conn_id);
- if (device == nullptr) {
- LOG(ERROR) << __func__ << " Device not there";
- return;
- }
-
- int group_id = PTR_TO_UINT(data);
- auto csis_group = FindCsisGroup(group_id);
- if (csis_group == nullptr) {
- LOG(ERROR) << __func__ << " There is no group? " << group_id;
- return;
- }
-
- CsisLockState target_lock_state = csis_group->GetTargetLockState();
- if (target_lock_state == CsisLockState::CSIS_STATE_UNSET) return;
-
- if (status != GATT_SUCCESS &&
- status != bluetooth::csis::kCsisErrorCodeLockAlreadyGranted) {
- if (target_lock_state == CsisLockState::CSIS_STATE_UNLOCKED) {
- /* When unlocking just drop the counter on error and that is it */
- csis_group->UpdateLockTransitionCnt(-1);
- return;
- }
-
- /* In case of GATT ERROR */
- LOG(ERROR) << __func__ << " Incorrect write status "
- << loghex((int)(status));
-
- /* Unlock previous devices */
- HandleCsisLockProcedureError(csis_group, device);
- return;
- }
-
- /* All is good, continue. Try to send lock to other devices.*/
- auto csis_instance = device->GetCsisInstanceByGroupId(group_id);
- LOG_ASSERT(csis_instance) << " csis_instance does not exist!";
- csis_instance->SetLockState(target_lock_state);
-
- if (csis_group->GetLockTransitionCnt() == 0) {
- LOG(ERROR) << __func__ << " Not expected lock state";
- return;
- }
-
- if (csis_group->UpdateLockTransitionCnt(-1) == 0) {
- csis_group->SetCurrentLockState(csis_group->GetTargetLockState());
- CsisLockCompleted(
- csis_group,
- csis_group->GetCurrentLockState() == CsisLockState::CSIS_STATE_LOCKED,
- CsisGroupLockStatus::SUCCESS);
- return;
- }
-
- if (target_lock_state == CsisLockState::CSIS_STATE_LOCKED) {
- std::shared_ptr<CsisDevice> next_dev;
-
- do {
- next_dev = csis_group->GetNextDevice(device);
- if (!next_dev) break;
- } while (!next_dev->IsConnected());
-
- if (next_dev) {
- auto next_csis_inst = next_dev->GetCsisInstanceByGroupId(group_id);
- LOG_ASSERT(csis_instance) << " csis_instance does not exist!";
- if (next_csis_inst->GetLockState() ==
- CsisLockState::CSIS_STATE_LOCKED) {
- /* Somebody else managed to lock it.
- * Unlock previous devices
- */
- HandleCsisLockProcedureError(csis_group, device);
- return;
- }
- SetLock(next_dev, next_csis_inst, CsisLockState::CSIS_STATE_LOCKED);
- }
- }
- }
-
- void SetLock(std::shared_ptr<CsisDevice>& device,
- std::shared_ptr<CsisInstance>& csis_instance,
- CsisLockState lock) {
- std::vector<uint8_t> value = {
- (std::underlying_type<CsisLockState>::type)lock};
-
- LOG(INFO) << __func__ << " " << device->addr
- << " rank: " << int(csis_instance->GetRank()) << " conn_id "
- << device->conn_id << " handle "
- << loghex(+(csis_instance->svc_data.lock_handle.val_hdl));
-
- BtaGattQueue::WriteCharacteristic(
- device->conn_id, csis_instance->svc_data.lock_handle.val_hdl, value,
- GATT_WRITE,
- [](uint16_t conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
- const uint8_t* value, void* data) {
- if (instance)
- instance->OnGattCsisWriteLockRsp(conn_id, status, handle, data);
- },
- UINT_TO_PTR(csis_instance->GetGroupId()));
- }
-
- void NotifyGroupStatus(int group_id, bool lock, CsisGroupLockStatus status,
- CsisLockCb cb) {
- callbacks_->OnGroupLockChanged(group_id, lock, status);
- if (cb) std::move(cb).Run(group_id, lock, status);
- }
-
- std::vector<RawAddress> GetDeviceList(int group_id) override {
- std::vector<RawAddress> result;
- auto csis_group = FindCsisGroup(group_id);
-
- if (!csis_group || csis_group->IsEmpty()) return result;
-
- auto csis_device = csis_group->GetFirstDevice();
- while (csis_device) {
- result.push_back(csis_device->addr);
- csis_device = csis_group->GetNextDevice(csis_device);
- }
-
- return result;
- }
-
- void LockGroup(int group_id, bool lock, CsisLockCb cb) override {
- if (lock)
- DLOG(INFO) << __func__ << " Locking group: " << int(group_id);
- else
- DLOG(INFO) << __func__ << " Unlocking group: " << int(group_id);
-
- /* For now we try to lock only connected devices in the group
- * TODO: We can consider reconnected to not connected devices and then
- * locked them
- */
- auto csis_group = FindCsisGroup(group_id);
- if (csis_group == nullptr) {
- LOG(ERROR) << __func__ << " Group not found: " << group_id;
- NotifyGroupStatus(group_id, false,
- CsisGroupLockStatus::FAILED_INVALID_GROUP,
- std::move(cb));
- return;
- }
-
- if (csis_group->IsEmpty()) {
- NotifyGroupStatus(group_id, false,
- CsisGroupLockStatus::FAILED_GROUP_EMPTY, std::move(cb));
- return;
- }
-
- if (csis_group->GetTargetLockState() != CsisLockState::CSIS_STATE_UNSET) {
- /* CSIS operation ongoing */
-
- DLOG(INFO) << __func__ << " Lock operation ongoing:"
- << "group id: " << group_id << "target state "
- << (csis_group->GetTargetLockState() ==
- CsisLockState::CSIS_STATE_LOCKED
- ? "lock"
- : "unlock");
- return;
- }
-
- CsisLockState new_lock_state = lock ? CsisLockState::CSIS_STATE_LOCKED
- : CsisLockState::CSIS_STATE_UNLOCKED;
-
- if (csis_group->GetCurrentLockState() == new_lock_state) {
- DLOG(INFO) << __func__ << " Nothing to do as requested lock is there";
- NotifyGroupStatus(group_id, lock, CsisGroupLockStatus::SUCCESS,
- std::move(cb));
- return;
- }
-
- if (lock && !csis_group->IsAvailableForCsisLockOperation()) {
- DLOG(INFO) << __func__ << " Group " << group_id << " locked by other";
- NotifyGroupStatus(group_id, false,
- CsisGroupLockStatus::FAILED_LOCKED_BY_OTHER,
- std::move(cb));
- return;
- }
-
- csis_group->SetTargetLockState(new_lock_state, std::move(cb));
-
- if (lock) {
- /* In locking case we need to make sure we lock all the device
- * and that in case of error on the way to lock the group, we
- * can revert lock previously locked devices as per specification.
- */
- auto csis_device = csis_group->GetFirstDevice();
- auto csis_instance = csis_device->GetCsisInstanceByGroupId(group_id);
- LOG_ASSERT(csis_instance) << " csis_instance does not exist!";
- SetLock(csis_device, csis_instance, new_lock_state);
- } else {
- /* For unlocking, we don't have to monitor status of unlocking device,
- * therefore, we can just send unlock to all of them, in oposite rank
- * order and check if we get new state notification.
- */
- auto csis_device = csis_group->GetLastDevice();
- auto csis_instance = csis_device->GetCsisInstanceByGroupId(group_id);
- LOG_ASSERT(csis_instance) << " csis_instance does not exist!";
- while (csis_device) {
- if ((csis_device->IsConnected()) &&
- ((csis_instance->GetLockState() != new_lock_state))) {
- csis_group->UpdateLockTransitionCnt(1);
- SetLock(csis_device, csis_instance, new_lock_state);
- }
- csis_device = csis_group->GetPrevDevice(csis_device);
- }
- }
- }
-
- bool SerializeSets(const RawAddress& addr, std::vector<uint8_t>& out) const {
- auto device = FindDeviceByAddress(addr);
- if (device == nullptr) {
- LOG(WARNING) << __func__ << " Skipping unknown device addr= " << addr;
- return false;
- }
-
- if (device->GetNumberOfCsisInstances() == 0) {
- LOG(WARNING) << __func__ << " No CSIS instances for addr= " << addr;
- return false;
- }
-
- DLOG(INFO) << __func__ << ": device=" << device->addr;
-
- auto num_sets = device->GetNumberOfCsisInstances();
- if ((num_sets == 0) || (num_sets > std::numeric_limits<uint8_t>::max()))
- return false;
-
- out.resize(CSIS_STORAGE_HEADER_SZ + (num_sets * CSIS_STORAGE_ENTRY_SZ));
- auto* ptr = out.data();
-
- /* header */
- UINT8_TO_STREAM(ptr, CSIS_STORAGE_CURRENT_LAYOUT_MAGIC);
- UINT8_TO_STREAM(ptr, num_sets);
-
- /* set entries */
- device->ForEachCsisInstance(
- [&](const std::shared_ptr<CsisInstance>& csis_inst) {
- auto gid = csis_inst->GetGroupId();
- auto csis_group = FindCsisGroup(gid);
- if (csis_group == nullptr) {
- LOG(ERROR) << "SerializeSets: No matching group found!";
- return;
- }
-
- UINT8_TO_STREAM(ptr, gid);
- UINT8_TO_STREAM(ptr, csis_group->GetDesiredSize());
- Octet16 sirk = csis_group->GetSirk();
- memcpy(ptr, sirk.data(), sirk.size());
- ptr += sirk.size();
- });
-
- return true;
- }
-
- void DeserializeSets(const RawAddress& addr, const std::vector<uint8_t>& in) {
- if (in.size() < CSIS_STORAGE_HEADER_SZ + CSIS_STORAGE_ENTRY_SZ) return;
- auto* ptr = in.data();
-
- uint8_t magic;
- STREAM_TO_UINT8(magic, ptr);
-
- if (magic == CSIS_STORAGE_CURRENT_LAYOUT_MAGIC) {
- uint8_t num_sets;
- STREAM_TO_UINT8(num_sets, ptr);
-
- if (in.size() <
- CSIS_STORAGE_HEADER_SZ + (num_sets * CSIS_STORAGE_ENTRY_SZ)) {
- LOG(ERROR) << "Invalid persistent storage data";
- return;
- }
-
- /* sets entries */
- while (num_sets--) {
- uint8_t gid;
- Octet16 sirk;
- uint8_t size;
-
- STREAM_TO_UINT8(gid, ptr);
- STREAM_TO_UINT8(size, ptr);
- STREAM_TO_ARRAY(sirk.data(), ptr, (int)sirk.size());
-
- // Set grouping and SIRK
- auto csis_group = AssignCsisGroup(addr, gid, true, Uuid::kEmpty);
- csis_group->SetDesiredSize(size);
- csis_group->SetSirk(sirk);
- }
- }
- }
-
- void AddFromStorage(const RawAddress& addr, const std::vector<uint8_t>& in,
- bool autoconnect) {
- DeserializeSets(addr, in);
-
- auto device = FindDeviceByAddress(addr);
- if (device == nullptr) {
- device = std::make_shared<CsisDevice>(addr, false);
- devices_.push_back(device);
- }
-
- for (const auto& csis_group : csis_groups_) {
- if (!csis_group->IsDeviceInTheGroup(device)) continue;
-
- if (csis_group->GetUuid() != Uuid::kEmpty) {
- callbacks_->OnDeviceAvailable(device->addr, csis_group->GetGroupId(),
- csis_group->GetDesiredSize(),
- csis_group->GetUuid());
- }
- }
-
- if (autoconnect) {
- BTA_GATTC_Open(gatt_if_, addr, false, false);
- }
- }
-
- void CleanUp() {
- DLOG(INFO) << __func__;
-
- BTA_GATTC_AppDeregister(gatt_if_);
- for (auto& device : devices_) {
- if (device->IsConnected()) BTA_GATTC_Close(device->conn_id);
- DoDisconnectCleanUp(device);
- }
-
- devices_.clear();
-
- CsisObserverSetBackground(false);
- dev_groups_->CleanUp(device_group_callbacks);
- }
-
- void Dump(int fd) {
- std::stringstream stream;
-
- stream << " Groups\n";
- for (const auto& g : csis_groups_) {
- stream << " == id: " << g->GetGroupId() << " ==\n"
- << " uuid: " << g->GetUuid() << "\n"
- << " desired size: " << g->GetDesiredSize() << "\n"
- << " discoverable state: "
- << static_cast<int>(g->GetDiscoveryState()) << "\n"
- << " current lock state: "
- << static_cast<int>(g->GetCurrentLockState()) << "\n"
- << " target lock state: "
- << static_cast<int>(g->GetTargetLockState()) << "\n"
- << " devices: \n";
- for (auto& device : devices_) {
- if (!g->IsDeviceInTheGroup(device)) continue;
-
- stream << " == addr: " << device->addr << " ==\n"
- << " csis instance: data:"
- << "\n";
-
- auto instance = device->GetCsisInstanceByGroupId(g->GetGroupId());
- if (!instance) {
- stream << " No csis instance available\n";
- } else {
- stream << " rank: " << instance->GetRank() << "\n";
- }
-
- if (!device->IsConnected()) {
- stream << " Not connected\n";
- } else {
- stream << " Connected conn_id = "
- << std::to_string(device->conn_id) << "\n";
- }
- }
- }
-
- dprintf(fd, "%s", stream.str().c_str());
- }
-
- private:
- std::shared_ptr<CsisDevice> FindDeviceByConnId(uint16_t conn_id) {
- auto it = find_if(devices_.begin(), devices_.end(),
- CsisDevice::MatchConnId(conn_id));
- if (it != devices_.end()) return (*it);
-
- return nullptr;
- }
-
- void RemoveCsisDevice(std::shared_ptr<CsisDevice>& device, int group_id) {
- auto it = find_if(devices_.begin(), devices_.end(),
- CsisDevice::MatchAddress(device->addr));
- if (it == devices_.end()) return;
-
- if (group_id != bluetooth::groups::kGroupUnknown) {
- auto csis_group = FindCsisGroup(group_id);
- if (!csis_group) {
- /* This could happen when remove device is called when bonding is
- * removed */
- DLOG(INFO) << __func__ << " group not found " << group_id;
- return;
- }
-
- csis_group->RemoveDevice(device->addr);
- if (csis_group->IsEmpty()) {
- RemoveCsisGroup(group_id);
- }
- device->RemoveCsisInstance(group_id);
- }
-
- if (device->GetNumberOfCsisInstances() == 0) {
- devices_.erase(it);
- }
- }
-
- std::shared_ptr<CsisDevice> FindDeviceByAddress(
- const RawAddress& addr) const {
- auto it = find_if(devices_.cbegin(), devices_.cend(),
- CsisDevice::MatchAddress(addr));
- if (it != devices_.end()) return (*it);
-
- return nullptr;
- }
-
- std::shared_ptr<CsisGroup> FindCsisGroup(int group_id) const {
- auto it =
- find_if(csis_groups_.cbegin(), csis_groups_.cend(),
- [group_id](auto& g) { return (group_id == g->GetGroupId()); });
-
- if (it == csis_groups_.end()) return nullptr;
- return (*it);
- }
-
- void RemoveCsisGroup(int group_id) {
- for (auto it = csis_groups_.begin(); it != csis_groups_.end(); it++) {
- if ((*it)->GetGroupId() == group_id) {
- csis_groups_.erase(it);
- return;
- }
- }
- }
-
- /* Handle encryption */
- void OnEncrypted(std::shared_ptr<CsisDevice>& device) {
- DLOG(INFO) << __func__ << " " << device->addr;
-
- if (device->is_gatt_service_valid) {
- NotifyCsisDeviceValidAndStoreIfNeeded(device);
- } else {
- BTA_GATTC_ServiceSearchRequest(device->conn_id, &kCsisServiceUuid);
- }
- }
-
- void NotifyCsisDeviceValidAndStoreIfNeeded(
- std::shared_ptr<CsisDevice>& device) {
- /* Notify that we are ready to go. Notice that multiple callback calls
- * for a single device address can be called if device is in more than one
- * CSIS group.
- */
- bool notify_connected = false;
- for (const auto& csis_group : csis_groups_) {
- if (!csis_group->IsDeviceInTheGroup(device)) continue;
-
- int group_id = csis_group->GetGroupId();
- auto csis_instance = device->GetCsisInstanceByGroupId(group_id);
- DLOG(INFO) << __func__ << " group id " << group_id;
-
- if (!csis_instance) {
- /* This can happen when some other user added device to group in the
- * context which is not existing on the peer side. e.g. LeAudio added it
- * in the CAP context, but CSIS exist on the peer device without a
- * context. We will endup in having device in 2 groups. One in generic
- * context with valid csis_instance, and one in CAP context without csis
- * instance */
- LOG(INFO) << __func__ << " csis_instance does not exist for group "
- << group_id;
- continue;
- }
-
- callbacks_->OnDeviceAvailable(device->addr, group_id,
- csis_group->GetDesiredSize(),
- csis_instance->GetUuid());
- notify_connected = true;
- }
- if (notify_connected)
- callbacks_->OnConnectionState(device->addr, ConnectionState::CONNECTED);
-
- if (device->first_connection) {
- device->first_connection = false;
- btif_storage_set_csis_autoconnect(device->addr, true);
- }
- }
-
- void OnGattWriteCcc(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
- void* user_data) {
- LOG(INFO) << __func__ << " handle=" << loghex(handle);
-
- auto device = FindDeviceByConnId(conn_id);
- if (device == nullptr) {
- LOG(INFO) << __func__ << " unknown conn_id=" << loghex(conn_id);
- BtaGattQueue::Clean(conn_id);
- return;
- }
- }
-
- void OnCsisNotification(uint16_t conn_id, uint16_t handle, uint16_t len,
- const uint8_t* value) {
- auto device = FindDeviceByConnId(conn_id);
- if (device == nullptr) {
- LOG(WARNING) << "Skipping unknown device, conn_id=" << loghex(conn_id);
- return;
- }
-
- auto csis_instance = device->GetCsisInstanceByOwningHandle(handle);
- if (csis_instance == nullptr) {
- LOG(ERROR) << __func__
- << " unknown notification handle: " << loghex(handle)
- << " for conn_id: " << loghex(conn_id);
- return;
- }
-
- if (handle == csis_instance->svc_data.sirk_handle.val_hdl) {
- OnCsisSirkValueUpdate(conn_id, GATT_SUCCESS, handle, len, value);
- } else if (handle == csis_instance->svc_data.lock_handle.val_hdl) {
- OnCsisLockNotifications(device, csis_instance, len, value);
- } else if (handle == csis_instance->svc_data.size_handle.val_hdl) {
- OnCsisSizeValueUpdate(conn_id, GATT_SUCCESS, handle, len, value);
- } else {
- LOG(WARNING) << __func__ << " unknown notification handle "
- << loghex(handle) << " for conn_id " << loghex(conn_id);
- }
- }
-
- static CsisGroupLockStatus LockError2GroupLockStatus(tGATT_STATUS status) {
- switch (status) {
- case bluetooth::csis::kCsisErrorCodeLockDenied:
- return CsisGroupLockStatus::FAILED_LOCKED_BY_OTHER;
- case bluetooth::csis::kCsisErrorCodeReleaseNotAllowed:
- return CsisGroupLockStatus::FAILED_LOCKED_BY_OTHER;
- case bluetooth::csis::kCsisErrorCodeInvalidValue:
- return CsisGroupLockStatus::FAILED_OTHER_REASON;
- default:
- return CsisGroupLockStatus::FAILED_OTHER_REASON;
- }
- }
-
- void CsisLockCompleted(std::shared_ptr<CsisGroup>& csis_group, bool lock,
- CsisGroupLockStatus status) {
- DLOG(INFO) << __func__ << " group id: " << int(csis_group->GetGroupId())
- << "target state " << (lock ? "lock" : "unlock");
-
- NotifyGroupStatus(csis_group->GetGroupId(), lock, status,
- std::move(csis_group->GetLockCb()));
- csis_group->SetTargetLockState(CsisLockState::CSIS_STATE_UNSET);
- }
-
- void OnCsisLockNotifications(std::shared_ptr<CsisDevice>& device,
- std::shared_ptr<CsisInstance>& csis_instance,
- uint16_t len, const uint8_t* value) {
- if (len != 1) {
- LOG(ERROR) << __func__ << " invalid notification len: " << loghex(len);
- return;
- }
-
- CsisLockState new_lock = (CsisLockState)(value[0]);
-
- DLOG(INFO) << " New lock state: " << int(new_lock)
- << " device rank: " << int(csis_instance->GetRank()) << "\n";
-
- csis_instance->SetLockState(new_lock);
-
- auto csis_group = FindCsisGroup(csis_instance->GetGroupId());
- if (!csis_group) return;
-
- CsisLockCb cb = csis_group->GetLockCb();
- if (csis_group->GetTargetLockState() == CsisLockState::CSIS_STATE_UNSET) {
- if (csis_group->GetCurrentLockState() ==
- CsisLockState::CSIS_STATE_LOCKED &&
- new_lock == CsisLockState::CSIS_STATE_UNLOCKED) {
- /* We are here when members fires theirs lock timeout.
- * Not sure what to do with our current lock state. For now we will
- * change local lock state after first set member removes its lock. Then
- * we count that others will do the same
- */
- csis_group->SetCurrentLockState(CsisLockState::CSIS_STATE_UNLOCKED);
- NotifyGroupStatus(csis_group->GetGroupId(), false,
- CsisGroupLockStatus::SUCCESS, std::move(cb));
- }
- return;
- }
-
- if (csis_group->GetCurrentLockState() != csis_group->GetTargetLockState()) {
- /* We are in process of changing lock state. If new device lock
- * state is what is targeted that means all is good, we don't need
- * to do here nothing, as state will be changed once all the
- * characteristics are written. If new device state is not what is
- * targeted, that means, device changed stated unexpectedly and locking
- * procedure is broken
- */
- if (new_lock != csis_group->GetTargetLockState()) {
- /* Device changed back the lock state from what we expected, skip
- * locking and notify user about that
- */
- CsisLockCompleted(csis_group, false,
- CsisGroupLockStatus::FAILED_OTHER_REASON);
- }
- }
- }
-
- void OnCsisSizeValueUpdate(uint16_t conn_id, tGATT_STATUS status,
- uint16_t handle, uint16_t len,
- const uint8_t* value) {
- auto device = FindDeviceByConnId(conn_id);
-
- if (device == nullptr) {
- LOG(WARNING) << "Skipping unknown device, conn_id=" << loghex(conn_id);
- return;
- }
-
- DLOG(INFO) << __func__ << " " << device->addr
- << " status: " << loghex(+status);
-
- if (status != GATT_SUCCESS) {
- LOG(ERROR) << __func__ << " Could not read characteristic at handle="
- << loghex(handle);
- BTA_GATTC_Close(device->conn_id);
- return;
- }
-
- if (len != 1) {
- LOG(ERROR) << "Invalid size value length=" << +len
- << " at handle=" << loghex(handle);
- BTA_GATTC_Close(device->conn_id);
- return;
- }
-
- auto csis_instance = device->GetCsisInstanceByOwningHandle(handle);
- if (csis_instance == nullptr) {
- LOG(ERROR) << __func__ << " Unknown csis instance";
- BTA_GATTC_Close(device->conn_id);
- return;
- }
- auto csis_group = FindCsisGroup(csis_instance->GetGroupId());
- if (!csis_group) {
- LOG(ERROR) << __func__ << " Unknown group id yet";
- return;
- }
-
- csis_group->SetDesiredSize(value[0]);
- }
-
- void OnCsisLockReadRsp(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
- uint16_t len, const uint8_t* value) {
- auto device = FindDeviceByConnId(conn_id);
- if (device == nullptr) {
- LOG(WARNING) << "Skipping unknown device, conn_id=" << loghex(conn_id);
- return;
- }
-
- LOG(INFO) << __func__ << " " << device->addr
- << " status: " << loghex(+status);
-
- if (status != GATT_SUCCESS) {
- LOG(ERROR) << __func__ << " Could not read characteristic at handle="
- << loghex(handle);
- BTA_GATTC_Close(device->conn_id);
- return;
- }
-
- if (len != 1) {
- LOG(ERROR) << " Invalid lock value length=" << +len
- << " at handle=" << loghex(handle);
- BTA_GATTC_Close(device->conn_id);
- return;
- }
-
- auto csis_instance = device->GetCsisInstanceByOwningHandle(handle);
- if (csis_instance == nullptr) {
- LOG(ERROR) << __func__ << " Unknown csis instance";
- BTA_GATTC_Close(device->conn_id);
- return;
- }
- csis_instance->SetLockState((CsisLockState)(value[0]));
- }
-
- void OnCsisRankReadRsp(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
- uint16_t len, const uint8_t* value) {
- auto device = FindDeviceByConnId(conn_id);
- if (device == nullptr) {
- LOG(WARNING) << __func__
- << " Skipping unknown device, conn_id=" << loghex(conn_id);
- return;
- }
-
- DLOG(INFO) << __func__ << " " << device->addr
- << " status: " << loghex(+status) << " rank:" << int(value[0]);
-
- if (status != GATT_SUCCESS) {
- LOG(ERROR) << __func__ << " Could not read characteristic at handle="
- << loghex(handle);
- BTA_GATTC_Close(device->conn_id);
- return;
- }
-
- if (len != 1) {
- LOG(ERROR) << __func__ << "Invalid rank value length=" << +len
- << " at handle=" << loghex(handle);
- BTA_GATTC_Close(device->conn_id);
- return;
- }
-
- auto csis_instance = device->GetCsisInstanceByOwningHandle(handle);
- if (csis_instance == nullptr) {
- LOG(ERROR) << __func__ << " Unknown csis instance handle " << int(handle);
- BTA_GATTC_Close(device->conn_id);
- return;
- }
-
- csis_instance->SetRank((value[0]));
- auto csis_group = FindCsisGroup(csis_instance->GetGroupId());
- csis_group->SortByCsisRank();
- }
-
- void OnCsisObserveCompleted(void) {
- if (discovering_group_ == -1) {
- LOG(ERROR) << __func__ << " No ongoing CSIS discovery - disable scan";
- return;
- }
-
- auto csis_group = FindCsisGroup(discovering_group_);
- discovering_group_ = -1;
- if (csis_group->IsGroupComplete())
- csis_group->SetDiscoveryState(
- CsisDiscoveryState::CSIS_DISCOVERY_COMPLETED);
- else
- csis_group->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_IDLE);
-
- LOG(INFO) << __func__;
- }
-
- /*
- * Sirk shall be in LE order
- * encrypted_sirk: LE order
- */
- bool sdf(const RawAddress& address, const Octet16& encrypted_sirk,
- Octet16& sirk) {
- tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(address);
- if (!p_dev_rec) {
- LOG(ERROR) << __func__ << " No security for " << address;
- return false;
- }
-
- DLOG(INFO) << __func__ << " LTK "
- << base::HexEncode(p_dev_rec->ble.keys.pltk.data(), 16);
- DLOG(INFO) << __func__ << " IRK "
- << base::HexEncode(p_dev_rec->ble.keys.irk.data(), 16);
-
- /* Calculate salt CSIS d1.0r05 4.3 */
- Octet16 zero_key;
- memset(zero_key.data(), 0, 16);
-
- std::string msg1 = "SIRKenc";
- std::reverse(msg1.begin(), msg1.end());
-
- Octet16 s1 = crypto_toolbox::aes_cmac(zero_key, (uint8_t*)(msg1.c_str()),
- msg1.size());
- DLOG(INFO) << "s1 (le) " << base::HexEncode(s1.data(), 16);
-
- /* Create K = LTK */
- DLOG(INFO) << "K (le) "
- << base::HexEncode(p_dev_rec->ble.keys.pltk.data(), 16) << "\n";
-
- Octet16 T = crypto_toolbox::aes_cmac(s1, p_dev_rec->ble.keys.pltk);
- DLOG(INFO) << "T (le)" << base::HexEncode(T.data(), 16) << "\n";
-
- std::string msg2 = "csis";
- std::reverse(msg2.begin(), msg2.end());
-
- Octet16 k1 =
- crypto_toolbox::aes_cmac(T, (uint8_t*)(msg2.c_str()), msg2.size());
- DLOG(INFO) << "K1 (le) " << base::HexEncode(k1.data(), 16) << "\n";
-
- for (int i = 0; i < 16; i++) sirk[i] = encrypted_sirk[i] ^ k1[i];
-
- DLOG(INFO) << "SIRK (le)" << base::HexEncode(sirk.data(), 16) << "\n";
- return true;
- }
-
- std::vector<RawAddress> GetAllRsiFromAdvertising(
- const tBTA_DM_INQ_RES* result) {
- const uint8_t* p_service_data = result->p_eir;
- uint16_t remaining_data_len = result->eir_len;
- std::vector<RawAddress> devices;
- uint8_t service_data_len = 0;
-
- while ((p_service_data = AdvertiseDataParser::GetFieldByType(
- p_service_data + service_data_len,
- (remaining_data_len -= service_data_len), BTM_BLE_AD_TYPE_RSI,
- &service_data_len))) {
- RawAddress bda;
- STREAM_TO_BDADDR(bda, p_service_data);
- devices.push_back(std::move(bda));
- }
-
- return std::move(devices);
- }
-
- void OnActiveScanResult(const tBTA_DM_INQ_RES* result) {
- auto csis_device = FindDeviceByAddress(result->bd_addr);
- if (csis_device) {
- DLOG(INFO) << __func__ << " Drop same device .." << result->bd_addr;
- return;
- }
-
- auto all_rsi = GetAllRsiFromAdvertising(result);
- if (all_rsi.empty()) return;
-
- /* Notify only the actively searched group */
- auto csis_group = FindCsisGroup(discovering_group_);
- if (csis_group == nullptr) {
- LOG(ERROR) << " No ongoing CSIS discovery - disable scan";
- CsisActiveObserverSet(false);
- return;
- }
-
- auto discovered_group_rsi = std::find_if(
- all_rsi.cbegin(), all_rsi.cend(), [&csis_group](const auto& rsi) {
- return csis_group->IsRsiMatching(rsi);
- });
- if (discovered_group_rsi != all_rsi.cend()) {
- DLOG(INFO) << "Found set member " << result->bd_addr;
- callbacks_->OnSetMemberAvailable(result->bd_addr,
- csis_group->GetGroupId());
-
- /* Switch back to the opportunistic observer mode.
- * When second device will pair, csis will restart active scan
- * to search more members if needed */
- CsisActiveObserverSet(false);
- csis_group->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_IDLE);
- }
- }
-
- void CsisActiveObserverSet(bool enable) {
- LOG(INFO) << __func__ << " CSIS Discovery SET: " << enable;
-
- BTA_DmBleCsisObserve(
- enable, [](tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_data) {
- /* If there's no instance we are most likely shutting
- * down the whole stack and we can ignore this event.
- */
- if (instance == nullptr) return;
-
- if (event == BTA_DM_INQ_CMPL_EVT) {
- LOG(INFO) << "BLE observe complete. Num Resp: "
- << static_cast<int>(p_data->inq_cmpl.num_resps);
- instance->OnCsisObserveCompleted();
- instance->CsisObserverSetBackground(true);
- return;
- }
-
- if (event != BTA_DM_INQ_RES_EVT) {
- LOG(WARNING) << "Unknown event: " << event;
- return;
- }
-
- instance->OnActiveScanResult(&p_data->inq_res);
- });
- BTA_DmBleScan(enable, bluetooth::csis::kDefaultScanDurationS);
-
- /* Need to call it by ourselfs */
- if (!enable) {
- OnCsisObserveCompleted();
- CsisObserverSetBackground(true);
- }
- }
-
- void CsisActiveDiscovery(std::shared_ptr<CsisGroup> csis_group) {
- if ((csis_group->GetDiscoveryState() !=
- CsisDiscoveryState::CSIS_DISCOVERY_IDLE)) {
- LOG(ERROR) << __func__
- << " Incorrect ase group: " << csis_group->GetGroupId()
- << " state "
- << loghex(static_cast<int>(csis_group->GetDiscoveryState()));
- return;
- }
-
- csis_group->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_ONGOING);
- /* TODO Maybe we don't need it */
- discovering_group_ = csis_group->GetGroupId();
- CsisActiveObserverSet(true);
- }
-
- void OnScanBackgroundResult(const tBTA_DM_INQ_RES* result) {
- if (csis_groups_.empty()) return;
-
- auto csis_device = FindDeviceByAddress(result->bd_addr);
- if (csis_device) {
- DLOG(INFO) << __func__ << " Drop same device .." << result->bd_addr;
- return;
- }
-
- auto all_rsi = GetAllRsiFromAdvertising(result);
- if (all_rsi.empty()) return;
-
- /* Notify all the groups this device belongs to. */
- for (auto& group : csis_groups_) {
- for (auto& rsi : all_rsi) {
- if (group->IsRsiMatching(rsi)) {
- DLOG(INFO) << " Found set member in background scan "
- << result->bd_addr;
- callbacks_->OnSetMemberAvailable(result->bd_addr,
- group->GetGroupId());
- break;
- }
- }
- }
- }
-
- void CsisObserverSetBackground(bool enable) {
- DLOG(INFO) << __func__ << " CSIS Discovery background: " << enable;
-
- BTA_DmBleCsisObserve(
- enable, [](tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_data) {
- /* If there's no instance we are most likely shutting
- * down the whole stack and we can ignore this event.
- */
- if (instance == nullptr) return;
-
- if (event == BTA_DM_INQ_CMPL_EVT) {
- DLOG(INFO) << "BLE observe complete. Num Resp: "
- << static_cast<int>(p_data->inq_cmpl.num_resps);
- return;
- }
-
- if (event != BTA_DM_INQ_RES_EVT) {
- LOG(WARNING) << "Unknown event: " << event;
- return;
- }
-
- instance->OnScanBackgroundResult(&p_data->inq_res);
- });
- }
-
- void OnCsisSirkValueUpdate(uint16_t conn_id, tGATT_STATUS status,
- uint16_t handle, uint16_t len,
- const uint8_t* value,
- bool notify_valid_services = true) {
- auto device = FindDeviceByConnId(conn_id);
- if (device == nullptr) {
- LOG(WARNING) << __func__
- << " Skipping unknown device, conn_id=" << loghex(conn_id);
- return;
- }
-
- DLOG(INFO) << __func__ << " " << device->addr
- << " status: " << loghex(+status);
-
- if (status != GATT_SUCCESS) {
- /* TODO handle error codes:
- * kCsisErrorCodeLockAccessSirkRejected
- * kCsisErrorCodeLockOobSirkOnly
- */
- LOG(ERROR) << __func__ << " Could not read characteristic at handle="
- << loghex(handle);
- BTA_GATTC_Close(device->conn_id);
- return;
- }
-
- if (len != bluetooth::csis::kCsisSirkCharLen) {
- LOG(ERROR) << "Invalid sirk value length=" << +len
- << " at handle=" << loghex(handle);
- BTA_GATTC_Close(device->conn_id);
- return;
- }
-
- auto csis_instance = device->GetCsisInstanceByOwningHandle(handle);
- if (csis_instance == nullptr) {
- LOG(ERROR) << __func__ << " Unknown csis instance: handle "
- << loghex(handle);
- BTA_GATTC_Close(device->conn_id);
- return;
- }
-
- uint8_t sirk_type = value[0];
- LOG(INFO) << __func__ << " SIRK Type: " << +sirk_type;
-
- /* Verify if sirk is not all zeros */
- Octet16 zero{};
- if (memcmp(zero.data(), value + 1, 16) == 0) {
- LOG(ERROR) << "Received invalid zero SIRK address: "
- << loghex(device->conn_id) << ". Disconnecting ";
- BTA_GATTC_Close(device->conn_id);
- return;
- }
-
- Octet16 received_sirk;
- memcpy(received_sirk.data(), value + 1, 16);
-
- if (sirk_type == bluetooth::csis::kCsisSirkTypeEncrypted) {
- /* Decrypt encrypted SIRK */
- Octet16 sirk;
- sdf(device->addr, received_sirk, sirk);
- received_sirk = sirk;
- }
-
- /* SIRK is ready. Add device to the group */
-
- std::shared_ptr<CsisGroup> csis_group;
- int group_id = csis_instance->GetGroupId();
- if (group_id != bluetooth::groups::kGroupUnknown) {
- /* Group already exist. */
- csis_group = FindCsisGroup(group_id);
- LOG_ASSERT(csis_group) << " group does not exist? " << group_id;
- } else {
- /* Now having SIRK we can decide if the device belongs to some group we
- * know or this is a new group
- */
- for (auto& g : csis_groups_) {
- if (g->IsSirkBelongsToGroup(received_sirk)) {
- group_id = g->GetGroupId();
- break;
- }
- }
-
- if (group_id == bluetooth::groups::kGroupUnknown) {
- /* Here it means, we have new group. Let's us create it */
- group_id =
- dev_groups_->AddDevice(device->addr, csis_instance->GetUuid());
- LOG_ASSERT(group_id != -1);
-
- /* Create new group */
- auto g =
- std::make_shared<CsisGroup>(group_id, csis_instance->GetUuid());
- csis_groups_.push_back(g);
- } else {
- dev_groups_->AddDevice(device->addr, csis_instance->GetUuid(),
- group_id);
- }
-
- csis_group = FindCsisGroup(group_id);
- csis_group->AddDevice(device);
- /* Let's update csis instance group id */
- csis_instance->SetGroupId(group_id);
- }
-
- csis_group->SetSirk(received_sirk);
- device->is_gatt_service_valid = true;
- btif_storage_update_csis_info(device->addr);
-
- if (notify_valid_services) NotifyCsisDeviceValidAndStoreIfNeeded(device);
-
- DLOG(INFO) << " SIRK " << base::HexEncode(received_sirk.data(), 16)
- << " address" << device->addr;
-
- DLOG(INFO) << " Expected group size "
- << loghex(csis_group->GetDesiredSize())
- << ", actual group Size: "
- << loghex(csis_group->GetCurrentSize());
-
- /* Start active search for the other device */
- if (csis_group->GetDesiredSize() > csis_group->GetCurrentSize())
- CsisActiveDiscovery(csis_group);
- }
-
- void DoDisconnectCleanUp(std::shared_ptr<CsisDevice> device) {
- DLOG(INFO) << __func__ << ": device=" << device->addr;
-
- device->ForEachCsisInstance(
- [&](const std::shared_ptr<CsisInstance>& csis_inst) {
- DisableGattNotification(device->conn_id, device->addr,
- csis_inst->svc_data.lock_handle.val_hdl);
- DisableGattNotification(device->conn_id, device->addr,
- csis_inst->svc_data.sirk_handle.val_hdl);
- DisableGattNotification(device->conn_id, device->addr,
- csis_inst->svc_data.size_handle.val_hdl);
- });
-
- if (device->IsConnected()) {
- BtaGattQueue::Clean(device->conn_id);
- device->conn_id = GATT_INVALID_CONN_ID;
- }
- }
-
- bool OnCsisServiceFound(std::shared_ptr<CsisDevice> device,
- const gatt::Service* service,
- const bluetooth::Uuid& context_uuid,
- bool is_last_instance) {
- DLOG(INFO) << __func__ << " service handle: " << loghex(service->handle)
- << " end handle: " << loghex(service->end_handle)
- << " uuid: " << context_uuid;
-
- auto csis_inst = std::make_shared<CsisInstance>(
- (uint16_t)service->handle, (uint16_t)service->end_handle, context_uuid);
-
- /* Let's check if we know group of this device */
- int group_id = dev_groups_->GetGroupId(device->addr, context_uuid);
- if (group_id != bluetooth::groups::kGroupUnknown)
- csis_inst->SetGroupId(group_id);
-
- /* Initially validate and store GATT service discovery data */
- for (const gatt::Characteristic& charac : service->characteristics) {
- if (charac.uuid == kCsisLockUuid) {
- /* Find the mandatory CCC descriptor */
- uint16_t ccc_handle =
- FindCccHandle(device->conn_id, charac.value_handle);
- if (ccc_handle == GAP_INVALID_HANDLE) {
- DLOG(ERROR) << __func__
- << ": no HAS Active Preset CCC descriptor found!";
- return false;
- }
- csis_inst->svc_data.lock_handle.val_hdl = charac.value_handle;
- csis_inst->svc_data.lock_handle.ccc_hdl = ccc_handle;
-
- SubscribeForNotifications(device->conn_id, device->addr,
- charac.value_handle, ccc_handle);
-
- DLOG(INFO) << __func__ << " Lock UUID found handle: "
- << loghex(csis_inst->svc_data.lock_handle.val_hdl)
- << " ccc handle: "
- << loghex(csis_inst->svc_data.lock_handle.ccc_hdl);
- } else if (charac.uuid == kCsisRankUuid) {
- csis_inst->svc_data.rank_handle = charac.value_handle;
-
- DLOG(INFO) << __func__ << " Rank UUID found handle: "
- << loghex(csis_inst->svc_data.rank_handle);
- } else if (charac.uuid == kCsisSirkUuid) {
- /* Find the optional CCC descriptor */
- uint16_t ccc_handle =
- FindCccHandle(device->conn_id, charac.value_handle);
- csis_inst->svc_data.sirk_handle.ccc_hdl = ccc_handle;
- csis_inst->svc_data.sirk_handle.val_hdl = charac.value_handle;
-
- if (ccc_handle != GAP_INVALID_HANDLE)
- SubscribeForNotifications(device->conn_id, device->addr,
- charac.value_handle, ccc_handle);
-
- DLOG(INFO) << __func__ << " SIRK UUID found handle: "
- << loghex(csis_inst->svc_data.sirk_handle.val_hdl)
- << " ccc handle: "
- << loghex(csis_inst->svc_data.sirk_handle.ccc_hdl);
- } else if (charac.uuid == kCsisSizeUuid) {
- /* Find the optional CCC descriptor */
- uint16_t ccc_handle =
- FindCccHandle(device->conn_id, charac.value_handle);
- csis_inst->svc_data.size_handle.ccc_hdl = ccc_handle;
- csis_inst->svc_data.size_handle.val_hdl = charac.value_handle;
-
- if (ccc_handle != GAP_INVALID_HANDLE)
- SubscribeForNotifications(device->conn_id, device->addr,
- charac.value_handle, ccc_handle);
-
- DLOG(INFO) << __func__ << " Size UUID found handle: "
- << loghex(csis_inst->svc_data.size_handle.val_hdl)
- << " ccc handle: "
- << loghex(csis_inst->svc_data.size_handle.ccc_hdl);
- }
- }
-
- /* Sirk is the only mandatory characteristic. If it is in
- * place, service is OK
- */
- if (csis_inst->svc_data.sirk_handle.val_hdl == GAP_INVALID_HANDLE) {
- /* We have some characteristics but all dependencies are not satisfied */
- LOG(ERROR) << __func__ << " Service has a broken structure.";
- return false;
- }
- device->SetCsisInstance(csis_inst->svc_data.start_handle, csis_inst);
-
- /* Read SIRK */
- BtaGattQueue::ReadCharacteristic(
- device->conn_id, csis_inst->svc_data.sirk_handle.val_hdl,
- [](uint16_t conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
- uint8_t* value, void* user_data) {
- if (instance)
- instance->OnCsisSirkValueUpdate(conn_id, status, handle, len, value,
- (bool)user_data);
- },
- (void*)is_last_instance);
-
- /* Read Lock */
- if (csis_inst->svc_data.lock_handle.val_hdl != GAP_INVALID_HANDLE) {
- BtaGattQueue::ReadCharacteristic(
- device->conn_id, csis_inst->svc_data.lock_handle.val_hdl,
- [](uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
- uint16_t len, uint8_t* value, void* user_data) {
- if (instance)
- instance->OnCsisLockReadRsp(conn_id, status, handle, len, value);
- },
- nullptr);
- }
-
- /* Read Size */
- if (csis_inst->svc_data.size_handle.val_hdl != GAP_INVALID_HANDLE) {
- BtaGattQueue::ReadCharacteristic(
- device->conn_id, csis_inst->svc_data.size_handle.val_hdl,
- [](uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
- uint16_t len, uint8_t* value, void* user_data) {
- if (instance)
- instance->OnCsisSizeValueUpdate(conn_id, status, handle, len,
- value);
- },
- nullptr);
- }
-
- /* Read Rank */
- if (csis_inst->svc_data.rank_handle != GAP_INVALID_HANDLE) {
- BtaGattQueue::ReadCharacteristic(
- device->conn_id, csis_inst->svc_data.rank_handle,
- [](uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
- uint16_t len, uint8_t* value, void* user_data) {
- if (instance)
- instance->OnCsisRankReadRsp(conn_id, status, handle, len, value);
- },
- nullptr);
- }
- return true;
- }
-
- /* These are all generic GATT event handlers calling HAS specific code. */
- void GattcCallback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
- LOG(INFO) << __func__ << " event = " << static_cast<int>(event);
-
- /* This is in case Csis CleanUp is already done
- * while GATT is still up and could send events
- */
- if (!instance) return;
-
- switch (event) {
- case BTA_GATTC_DEREG_EVT:
- break;
-
- case BTA_GATTC_OPEN_EVT:
- OnGattConnected(p_data->open);
- break;
-
- case BTA_GATTC_CLOSE_EVT:
- OnGattDisconnected(p_data->close);
- break;
-
- case BTA_GATTC_SEARCH_CMPL_EVT:
- OnGattServiceSearchComplete(p_data->search_cmpl);
- break;
-
- case BTA_GATTC_NOTIF_EVT:
- OnGattNotification(p_data->notify);
- break;
-
- case BTA_GATTC_ENC_CMPL_CB_EVT:
- OnLeEncryptionComplete(p_data->enc_cmpl.remote_bda, BTM_SUCCESS);
- break;
-
- case BTA_GATTC_SRVC_CHG_EVT:
- OnGattServiceChangeEvent(p_data->remote_bda);
- break;
-
- case BTA_GATTC_SRVC_DISC_DONE_EVT:
- OnGattServiceDiscoveryDoneEvent(p_data->remote_bda);
- break;
-
- default:
- break;
- }
- }
-
- void OnGattConnected(const tBTA_GATTC_OPEN& evt) {
- DLOG(INFO) << __func__ << ": address=" << evt.remote_bda
- << ", conn_id=" << evt.conn_id;
-
- auto device = FindDeviceByAddress(evt.remote_bda);
- if (device == nullptr) {
- DLOG(WARNING) << "Skipping unknown device, address=" << evt.remote_bda;
- BTA_GATTC_Close(evt.conn_id);
- return;
- }
-
- if (evt.status != GATT_SUCCESS) {
- DLOG(INFO) << "Failed to connect to server device";
- if (device->connecting_actively)
- callbacks_->OnConnectionState(evt.remote_bda,
- ConnectionState::DISCONNECTED);
- DoDisconnectCleanUp(device);
- return;
- }
-
- device->connecting_actively = false;
- device->conn_id = evt.conn_id;
-
- /* Verify bond */
- uint8_t sec_flag = 0;
- BTM_GetSecurityFlagsByTransport(evt.remote_bda, &sec_flag, BT_TRANSPORT_LE);
-
- /* If link has been encrypted look for the service or report */
- if (sec_flag & BTM_SEC_FLAG_ENCRYPTED) {
- if (device->is_gatt_service_valid) {
- instance->OnEncrypted(device);
- } else {
- BTA_GATTC_ServiceSearchRequest(device->conn_id, &kCsisServiceUuid);
- }
-
- return;
- }
-
- int result = BTM_SetEncryption(
- evt.remote_bda, BT_TRANSPORT_LE,
- [](const RawAddress* bd_addr, tBT_TRANSPORT transport, void* p_ref_data,
- tBTM_STATUS status) {
- if (instance) instance->OnLeEncryptionComplete(*bd_addr, status);
- },
- nullptr, BTM_BLE_SEC_ENCRYPT);
-
- DLOG(INFO) << __func__
- << " Encryption required. Request result: " << result;
- }
-
- void OnGattDisconnected(const tBTA_GATTC_CLOSE& evt) {
- auto device = FindDeviceByAddress(evt.remote_bda);
- if (device == nullptr) {
- LOG(WARNING) << "Skipping unknown device disconnect, conn_id="
- << loghex(evt.conn_id);
- return;
- }
-
- DLOG(INFO) << __func__ << ": device=" << device->addr;
-
- callbacks_->OnConnectionState(evt.remote_bda,
- ConnectionState::DISCONNECTED);
-
- // Unlock others only if device was locked by us but has disconnected
- // unexpectedly.
- if ((evt.reason == GATT_CONN_TIMEOUT) ||
- (evt.reason == GATT_CONN_TERMINATE_PEER_USER)) {
- device->ForEachCsisInstance(
- [&](const std::shared_ptr<CsisInstance>& csis_inst) {
- auto csis_group = FindCsisGroup(csis_inst->GetGroupId());
- if (csis_group == nullptr) return;
- if ((csis_group->GetCurrentLockState() ==
- CsisLockState::CSIS_STATE_LOCKED)) {
- HandleCsisLockProcedureError(
- csis_group, device,
- CsisGroupLockStatus::LOCKED_GROUP_MEMBER_LOST);
- }
- });
- }
-
- DoDisconnectCleanUp(device);
- }
-
- void OnGattServiceSearchComplete(const tBTA_GATTC_SEARCH_CMPL& evt) {
- auto device = FindDeviceByConnId(evt.conn_id);
-
- if (device == nullptr) {
- LOG(WARNING) << __func__ << " Skipping unknown device, conn_id="
- << loghex(evt.conn_id);
- return;
- }
-
- /* Ignore if our service data is valid (discovery initiated by someone
- * else?) */
- if (!device->is_gatt_service_valid) {
- if (evt.status != GATT_SUCCESS) {
- LOG(ERROR) << __func__ << " Service discovery failed";
- BTA_GATTC_Close(device->conn_id);
- DoDisconnectCleanUp(device);
- return;
- }
-
- DLOG(INFO) << __func__;
-
- const std::list<gatt::Service>* all_services =
- BTA_GATTC_GetServices(device->conn_id);
-
- std::vector<uint16_t> all_csis_start_handles;
-
- /* Le's just find all the CSIS primary services and store the start
- * handles */
- for (auto& svrc : *all_services) {
- if (svrc.uuid == kCsisServiceUuid) {
- all_csis_start_handles.push_back(svrc.handle);
- }
- }
-
- if (all_csis_start_handles.size() == 0) {
- DLOG(INFO) << __func__ << " No Csis instances found";
- BTA_GATTC_Close(device->conn_id);
- RemoveCsisDevice(device, bluetooth::groups::kGroupUnknown);
- return;
- }
-
- for (auto& svrc : *all_services) {
- if (svrc.uuid == kCsisServiceUuid) continue;
-
- /* Try to find context for CSIS instances */
- for (auto& included_srvc : svrc.included_services) {
- if (included_srvc.uuid == kCsisServiceUuid) {
- auto csis_svrc = BTA_GATTC_GetOwningService(
- device->conn_id, included_srvc.start_handle);
- auto iter = std::find(all_csis_start_handles.begin(),
- all_csis_start_handles.end(),
- included_srvc.start_handle);
- if (iter != all_csis_start_handles.end())
- all_csis_start_handles.erase(iter);
- instance->OnCsisServiceFound(device, csis_svrc, svrc.uuid,
- all_csis_start_handles.empty());
- }
- }
- }
-
- /* Here if CSIS is included, all_csis_start_handles should be empty
- * Otherwise it means, we have some primary CSIS without a context,
- * which means it is for the complete device.
- * As per spec, there can be only one service like this.
- */
- if (all_csis_start_handles.size()) {
- DLOG(INFO) << __func__ << " there is " << all_csis_start_handles.size()
- << " primary services without a context";
- auto csis_svrc = BTA_GATTC_GetOwningService(device->conn_id,
- all_csis_start_handles[0]);
- instance->OnCsisServiceFound(
- device, csis_svrc, bluetooth::groups::kGenericContextUuid, true);
- all_csis_start_handles.clear();
- }
- } else {
- /* This might be set already if there is no optional attributes to read
- * or write.
- */
- if (evt.status == GATT_SUCCESS) {
- NotifyCsisDeviceValidAndStoreIfNeeded(device);
- }
- }
- }
-
- void OnGattNotification(const tBTA_GATTC_NOTIFY& evt) {
- /* Reject invalid lengths and indications as they are not supported */
- if (!evt.is_notify || evt.len > GATT_MAX_ATTR_LEN) {
- LOG(ERROR) << __func__ << ": rejected BTA_GATTC_NOTIF_EVT. is_notify = "
- << evt.is_notify << ", len=" << static_cast<int>(evt.len);
- }
-
- OnCsisNotification(evt.conn_id, evt.handle, evt.len, evt.value);
- }
-
- void OnLeEncryptionComplete(const RawAddress& address, uint8_t status) {
- DLOG(INFO) << __func__ << " " << address;
- auto device = FindDeviceByAddress(address);
- if (device == nullptr) {
- LOG(WARNING) << "Skipping unknown device" << address;
- return;
- }
-
- if (status != BTM_SUCCESS) {
- LOG(ERROR) << "encryption failed"
- << " status: " << status;
-
- BTA_GATTC_Close(device->conn_id);
- return;
- }
-
- if (device->is_gatt_service_valid) {
- instance->OnEncrypted(device);
- } else {
- device->first_connection = true;
- BTA_GATTC_ServiceSearchRequest(device->conn_id, &kCsisServiceUuid);
- }
- }
-
- void OnGattServiceChangeEvent(const RawAddress& address) {
- auto device = FindDeviceByAddress(address);
- if (!device) {
- LOG(WARNING) << "Skipping unknown device" << address;
- return;
- }
-
- DLOG(INFO) << __func__ << ": address=" << address;
-
- /* Invalidate service discovery results */
- BtaGattQueue::Clean(device->conn_id);
- device->first_connection = true;
- device->ClearSvcData();
- }
-
- void OnGattServiceDiscoveryDoneEvent(const RawAddress& address) {
- auto device = FindDeviceByAddress(address);
- if (!device) {
- LOG(WARNING) << "Skipping unknown device" << address;
- return;
- }
-
- DLOG(INFO) << __func__ << ": address=" << address;
-
- if (!device->is_gatt_service_valid)
- BTA_GATTC_ServiceSearchRequest(device->conn_id, &kCsisServiceUuid);
- }
-
- static uint16_t FindCccHandle(uint16_t conn_id, uint16_t char_handle) {
- const gatt::Characteristic* p_char =
- BTA_GATTC_GetCharacteristic(conn_id, char_handle);
- if (!p_char) {
- LOG(WARNING) << __func__ << ": No such characteristic: " << char_handle;
- return GAP_INVALID_HANDLE;
- }
-
- for (const gatt::Descriptor& desc : p_char->descriptors) {
- if (desc.uuid == Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG))
- return desc.handle;
- }
-
- return GAP_INVALID_HANDLE;
- }
-
- void SubscribeForNotifications(uint16_t conn_id, const RawAddress& address,
- uint16_t value_handle, uint16_t ccc_handle) {
- if (value_handle != GAP_INVALID_HANDLE) {
- tGATT_STATUS register_status =
- BTA_GATTC_RegisterForNotifications(gatt_if_, address, value_handle);
- DLOG(INFO) << __func__ << ": BTA_GATTC_RegisterForNotifications, status="
- << loghex(+register_status)
- << " value=" << loghex(value_handle)
- << " ccc=" << loghex(ccc_handle);
-
- if (register_status != GATT_SUCCESS) return;
- }
-
- std::vector<uint8_t> value(2);
- uint8_t* value_ptr = value.data();
- UINT16_TO_STREAM(value_ptr, GATT_CHAR_CLIENT_CONFIG_NOTIFICATION);
- BtaGattQueue::WriteDescriptor(
- conn_id, ccc_handle, std::move(value), GATT_WRITE,
- [](uint16_t conn_id, tGATT_STATUS status, uint16_t value_handle,
- uint16_t len, const uint8_t* value, void* user_data) {
- if (instance)
- instance->OnGattWriteCcc(conn_id, status, value_handle, user_data);
- },
- nullptr);
- }
-
- void DisableGattNotification(uint16_t conn_id, const RawAddress& address,
- uint16_t value_handle) {
- if (value_handle != GAP_INVALID_HANDLE) {
- tGATT_STATUS register_status =
- BTA_GATTC_DeregisterForNotifications(gatt_if_, address, value_handle);
- DLOG(INFO) << __func__ << ": DisableGattNotification, status="
- << loghex(+register_status)
- << " value=" << loghex(value_handle);
-
- if (register_status != GATT_SUCCESS) return;
- }
- }
-
- uint8_t gatt_if_;
- bluetooth::csis::CsisClientCallbacks* callbacks_;
- std::list<std::shared_ptr<CsisDevice>> devices_;
- std::list<std::shared_ptr<CsisGroup>> csis_groups_;
- DeviceGroups* dev_groups_;
- int discovering_group_ = -1;
-};
-
-class DeviceGroupsCallbacksImpl : public DeviceGroupsCallbacks {
- public:
- void OnGroupAdded(const RawAddress& address, const bluetooth::Uuid& uuid,
- int group_id) override {
- if (instance) instance->OnGroupAddedCb(address, uuid, group_id);
- }
-
- void OnGroupMemberAdded(const RawAddress& address, int group_id) override {
- if (instance) instance->OnGroupMemberAddedCb(address, group_id);
- }
-
- void OnGroupRemoved(const bluetooth::Uuid& uuid, int group_id) override {
- if (instance) instance->OnGroupRemovedCb(uuid, group_id);
- }
-
- void OnGroupMemberRemoved(const RawAddress& address, int group_id) override {
- if (instance) instance->OnGroupMemberRemovedCb(address, group_id);
- }
-
- void OnGroupAddFromStorage(const RawAddress& address,
- const bluetooth::Uuid& uuid,
- int group_id) override {
- if (instance) instance->OnGroupAddFromStorageCb(address, uuid, group_id);
- }
-};
-
-class DeviceGroupsCallbacksImpl;
-DeviceGroupsCallbacksImpl deviceGroupsCallbacksImpl;
-
-} // namespace
-
-void CsisClient::Initialize(bluetooth::csis::CsisClientCallbacks* callbacks,
- Closure initCb) {
- if (instance) {
- LOG(ERROR) << __func__ << ": Already initialized!";
- return;
- }
-
- device_group_callbacks = &deviceGroupsCallbacksImpl;
- instance = new CsisClientImpl(callbacks, initCb);
-}
-
-bool CsisClient::IsCsisClientRunning() { return instance; }
-
-CsisClient* CsisClient::Get(void) {
- CHECK(instance);
- return instance;
-}
-
-void CsisClient::AddFromStorage(const RawAddress& addr,
- const std::vector<uint8_t>& in,
- bool autoconnect) {
- if (!instance) {
- LOG(ERROR) << __func__ << ": Not initialized yet!";
- return;
- }
-
- instance->AddFromStorage(addr, in, autoconnect);
-}
-
-bool CsisClient::GetForStorage(const RawAddress& addr,
- std::vector<uint8_t>& out) {
- if (!instance) {
- LOG(ERROR) << __func__ << ": Not initialized yet";
- return false;
- }
-
- return instance->SerializeSets(addr, out);
-}
-
-void CsisClient::CleanUp() {
- CsisClientImpl* ptr = instance;
- instance = nullptr;
-
- if (ptr) {
- ptr->CleanUp();
- delete ptr;
- }
-}
-
-void CsisClient::DebugDump(int fd) {
- dprintf(fd, "Coordinated Set Service Client:\n");
- if (instance) instance->Dump(fd);
- dprintf(fd, "\n");
-}
diff --git a/bta/csis/csis_client_test.cc b/bta/csis/csis_client_test.cc
deleted file mode 100644
index f3aaefe..0000000
--- a/bta/csis/csis_client_test.cc
+++ /dev/null
@@ -1,1134 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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 <base/bind.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "bind_helpers.h"
-#include "bta_csis_api.h"
-#include "bta_dm_api_mock.h"
-#include "bta_gatt_api_mock.h"
-#include "bta_gatt_queue_mock.h"
-#include "btif_storage.h"
-#include "btm_api_mock.h"
-#include "csis_types.h"
-#include "gatt/database_builder.h"
-#include "hardware/bt_gatt_types.h"
-
-std::map<std::string, int> mock_function_count_map;
-
-namespace bluetooth {
-namespace csis {
-namespace internal {
-namespace {
-
-using base::Bind;
-using base::Closure;
-using base::Unretained;
-
-using bluetooth::csis::ConnectionState;
-using bluetooth::csis::CsisClient;
-using bluetooth::csis::CsisClientCallbacks;
-using bluetooth::csis::CsisClientInterface;
-using bluetooth::csis::CsisGroupLockStatus;
-using bluetooth::groups::DeviceGroups;
-
-using testing::_;
-using testing::DoAll;
-using testing::DoDefault;
-using testing::Invoke;
-using testing::Mock;
-using testing::NotNull;
-using testing::Return;
-using testing::SaveArg;
-using testing::SetArgPointee;
-using testing::WithArg;
-
-// Disables most likely false-positives from base::SplitString()
-extern "C" const char* __asan_default_options() {
- return "detect_container_overflow=0";
-}
-
-RawAddress GetTestAddress(int index) {
- CHECK_LT(index, UINT8_MAX);
- RawAddress result = {
- {0xC0, 0xDE, 0xC0, 0xDE, 0x00, static_cast<uint8_t>(index)}};
- return result;
-}
-
-/* Csis lock callback */
-class MockCsisLockCallback {
- public:
- MockCsisLockCallback() = default;
- ~MockCsisLockCallback() = default;
- MOCK_METHOD((void), CsisGroupLockCb,
- (int group_id, bool locked, CsisGroupLockStatus status));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockCsisLockCallback);
-};
-
-static MockCsisLockCallback* csis_lock_callback_mock;
-
-void SetMockCsisLockCallback(MockCsisLockCallback* mock) {
- csis_lock_callback_mock = mock;
-}
-
-/* Csis callbacks to JNI */
-class MockCsisCallbacks : public CsisClientCallbacks {
- public:
- MockCsisCallbacks() = default;
- ~MockCsisCallbacks() override = default;
-
- MOCK_METHOD((void), OnConnectionState,
- (const RawAddress& address, ConnectionState state), (override));
- MOCK_METHOD((void), OnDeviceAvailable,
- (const RawAddress& address, int group_id, int group_size,
- const bluetooth::Uuid& uuid),
- (override));
- MOCK_METHOD((void), OnSetMemberAvailable,
- (const RawAddress& address, int group_id), (override));
- MOCK_METHOD((void), OnGroupLockChanged,
- (int group_id, bool locked,
- bluetooth::csis::CsisGroupLockStatus status),
- (override));
- MOCK_METHOD((void), OnGattCsisWriteLockRsp,
- (uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
- void* data));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockCsisCallbacks);
-};
-
-class CsisClientTest : public ::testing::Test {
- private:
- void set_sample_database(uint16_t conn_id, bool csis, bool csis_broken,
- uint8_t rank, uint8_t sirk_msb = 1) {
- gatt::DatabaseBuilder builder;
- builder.AddService(0x0001, 0x0003, Uuid::From16Bit(0x1800), true);
- builder.AddCharacteristic(0x0002, 0x0003, Uuid::From16Bit(0x2a00),
- GATT_CHAR_PROP_BIT_READ);
- if (csis) {
- builder.AddService(0x0010, 0x0030, kCsisServiceUuid, true);
- builder.AddCharacteristic(
- 0x0020, 0x0021, kCsisSirkUuid,
- GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
-
- builder.AddDescriptor(0x0022,
- Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
- builder.AddCharacteristic(
- 0x0023, 0x0024, kCsisSizeUuid,
- GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
- builder.AddDescriptor(0x0025,
- Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
- builder.AddCharacteristic(0x0026, 0x0027, kCsisLockUuid,
- GATT_CHAR_PROP_BIT_READ |
- GATT_CHAR_PROP_BIT_NOTIFY |
- GATT_CHAR_PROP_BIT_WRITE);
- builder.AddDescriptor(0x0028,
- Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
- builder.AddCharacteristic(0x0029, 0x0030, kCsisRankUuid,
- GATT_CHAR_PROP_BIT_READ);
- }
- if (csis_broken) {
- builder.AddCharacteristic(
- 0x0020, 0x0021, kCsisSirkUuid,
- GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
-
- builder.AddDescriptor(0x0022,
- Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
- }
- builder.AddService(0x0090, 0x0093,
- Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER), true);
- builder.AddCharacteristic(0x0091, 0x0092,
- Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD),
- GATT_CHAR_PROP_BIT_NOTIFY);
- builder.AddDescriptor(0x0093,
- Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
- services_map[conn_id] = builder.Build().Services();
-
- ON_CALL(gatt_queue, ReadCharacteristic(conn_id, _, _, _))
- .WillByDefault(
- Invoke([rank, sirk_msb](uint16_t conn_id, uint16_t handle,
- GATT_READ_OP_CB cb, void* cb_data) -> void {
- std::vector<uint8_t> value;
-
- switch (handle) {
- case 0x0003:
- /* device name */
- value.resize(20);
- break;
- case 0x0021:
- value.assign(17, 1);
- value[16] = sirk_msb;
- break;
- case 0x0024:
- value.resize(1);
- break;
- case 0x0027:
- value.resize(1);
- break;
- case 0x0030:
- value.resize(1);
- value.assign(1, rank);
- break;
- default:
- ASSERT_TRUE(false);
- return;
- }
-
- cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
- cb_data);
- }));
- }
-
- void set_sample_database_double_csis(uint16_t conn_id, uint8_t rank_1,
- uint8_t rank_2, bool broken,
- uint8_t sirk1_infill = 1,
- uint8_t sirk2_infill = 2) {
- gatt::DatabaseBuilder builder;
-
- builder.AddService(0x0001, 0x0003, Uuid::From16Bit(0x1800), true);
- builder.AddCharacteristic(0x0002, 0x0003, Uuid::From16Bit(0x2a00),
- GATT_CHAR_PROP_BIT_READ);
- builder.AddService(0x0010, 0x0026, bluetooth::Uuid::From16Bit(0x1850),
- true);
- builder.AddIncludedService(0x0011, kCsisServiceUuid, 0x0031, 0x0041);
- builder.AddCharacteristic(
- 0x0031, 0x0032, kCsisSirkUuid,
- GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
-
- builder.AddDescriptor(0x0033,
- Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
- builder.AddCharacteristic(
- 0x0034, 0x0035, kCsisSizeUuid,
- GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
- builder.AddDescriptor(0x0036,
- Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
- builder.AddCharacteristic(0x0037, 0x0038, kCsisLockUuid,
- GATT_CHAR_PROP_BIT_READ |
- GATT_CHAR_PROP_BIT_NOTIFY |
- GATT_CHAR_PROP_BIT_WRITE);
- builder.AddDescriptor(0x0039,
- Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
- builder.AddCharacteristic(0x0040, 0x0041, kCsisRankUuid,
- GATT_CHAR_PROP_BIT_READ);
-
- if (broken) {
- builder.AddCharacteristic(
- 0x0020, 0x0021, kCsisSirkUuid,
- GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
-
- builder.AddDescriptor(0x0022,
- Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
- }
-
- builder.AddService(0x0042, 0x0044, bluetooth::Uuid::From16Bit(0x1860),
- true);
- builder.AddIncludedService(0x0043, kCsisServiceUuid, 0x0045, 0x0055);
-
- builder.AddCharacteristic(
- 0x0045, 0x0046, kCsisSirkUuid,
- GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
-
- builder.AddDescriptor(0x0047,
- Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
- builder.AddCharacteristic(
- 0x0048, 0x0049, kCsisSizeUuid,
- GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
- builder.AddDescriptor(0x0050,
- Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
- builder.AddCharacteristic(0x0051, 0x0052, kCsisLockUuid,
- GATT_CHAR_PROP_BIT_READ |
- GATT_CHAR_PROP_BIT_NOTIFY |
- GATT_CHAR_PROP_BIT_WRITE);
- builder.AddDescriptor(0x0053,
- Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
- builder.AddCharacteristic(0x0054, 0x0055, kCsisRankUuid,
- GATT_CHAR_PROP_BIT_READ);
-
- builder.AddService(0x0090, 0x0093,
- Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER), true);
- builder.AddCharacteristic(0x0091, 0x0092,
- Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD),
- GATT_CHAR_PROP_BIT_NOTIFY);
- builder.AddDescriptor(0x0093,
- Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
- services_map[conn_id] = builder.Build().Services();
-
- ON_CALL(gatt_queue, ReadCharacteristic(conn_id, _, _, _))
- .WillByDefault(Invoke([sirk1_infill, sirk2_infill, rank_1, rank_2](
- uint16_t conn_id, uint16_t handle,
- GATT_READ_OP_CB cb, void* cb_data) -> void {
- std::vector<uint8_t> value;
-
- switch (handle) {
- case 0x0003:
- /* device name */
- value.resize(20);
- break;
- case 0x0032:
- value.resize(17);
- value.assign(17, sirk1_infill);
- value[0] = 1; // Plain text SIRK
- break;
- case 0x0035:
- value.resize(1);
- value.assign(1, 2);
- break;
- case 0x0038:
- value.resize(1);
- break;
- case 0x0041:
- value.resize(1);
- value.assign(1, rank_1);
- break;
- case 0x0046:
- value.resize(17);
- value.assign(17, sirk2_infill);
- value[0] = 1; // Plain text SIRK
- break;
- case 0x0049:
- value.resize(1);
- value.assign(1, 2);
- break;
- case 0x0052:
- value.resize(1);
- break;
- case 0x0055:
- value.resize(1);
- value.assign(1, rank_2);
- break;
- default:
- LOG(ERROR) << " Unknown handle? " << +handle;
- ASSERT_TRUE(false);
- return;
- }
-
- cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
- cb_data);
- }));
- }
-
- protected:
- void SetUp(void) override {
- mock_function_count_map.clear();
- bluetooth::manager::SetMockBtmInterface(&btm_interface);
- dm::SetMockBtaDmInterface(&dm_interface);
- gatt::SetMockBtaGattInterface(&gatt_interface);
- gatt::SetMockBtaGattQueue(&gatt_queue);
- SetMockCsisLockCallback(&csis_lock_cb);
- callbacks.reset(new MockCsisCallbacks());
-
- ON_CALL(gatt_interface, GetCharacteristic(_, _))
- .WillByDefault(
- Invoke([&](uint16_t conn_id,
- uint16_t handle) -> const gatt::Characteristic* {
- std::list<gatt::Service>& services = services_map[conn_id];
- for (auto const& service : services) {
- for (auto const& characteristic : service.characteristics) {
- if (characteristic.value_handle == handle) {
- return &characteristic;
- }
- }
- }
-
- return nullptr;
- }));
-
- // default action for GetOwningService function call
- ON_CALL(gatt_interface, GetOwningService(_, _))
- .WillByDefault(Invoke(
- [&](uint16_t conn_id, uint16_t handle) -> const gatt::Service* {
- std::list<gatt::Service>& services = services_map[conn_id];
- for (auto const& service : services) {
- if (service.handle <= handle && service.end_handle >= handle) {
- return &service;
- }
- }
-
- return nullptr;
- }));
-
- // default action for GetServices function call
- ON_CALL(gatt_interface, GetServices(_))
- .WillByDefault(WithArg<0>(
- Invoke([&](uint16_t conn_id) -> std::list<gatt::Service>* {
- return &services_map[conn_id];
- })));
-
- // default action for RegisterForNotifications function call
- ON_CALL(gatt_interface, RegisterForNotifications(gatt_if, _, _))
- .WillByDefault(Return(GATT_SUCCESS));
-
- // default action for DeregisterForNotifications function call
- ON_CALL(gatt_interface, DeregisterForNotifications(gatt_if, _, _))
- .WillByDefault(Return(GATT_SUCCESS));
-
- // default action for WriteDescriptor function call
- ON_CALL(gatt_queue, WriteDescriptor(_, _, _, _, _, _))
- .WillByDefault(
- Invoke([](uint16_t conn_id, uint16_t handle,
- std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
- GATT_WRITE_OP_CB cb, void* cb_data) -> void {
- if (cb)
- cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
- cb_data);
- }));
- }
-
- void TearDown(void) override {
- services_map.clear();
- callbacks.reset();
- CsisClient::CleanUp();
- gatt::SetMockBtaGattInterface(nullptr);
- bluetooth::manager::SetMockBtmInterface(nullptr);
- }
-
- void TestAppRegister(void) {
- BtaAppRegisterCallback app_register_callback;
- EXPECT_CALL(gatt_interface, AppRegister(_, _, _))
- .WillOnce(DoAll(SaveArg<0>(&gatt_callback),
- SaveArg<1>(&app_register_callback)));
- CsisClient::Initialize(callbacks.get(),
- Bind(&btif_storage_load_bonded_csis_devices));
- ASSERT_TRUE(gatt_callback);
- ASSERT_TRUE(app_register_callback);
- app_register_callback.Run(gatt_if, GATT_SUCCESS);
- ASSERT_TRUE(CsisClient::IsCsisClientRunning());
- }
-
- void TestAppUnregister(void) {
- EXPECT_CALL(gatt_interface, AppDeregister(gatt_if));
- CsisClient::CleanUp();
- ASSERT_FALSE(CsisClient::IsCsisClientRunning());
- gatt_callback = nullptr;
- }
-
- void TestConnect(const RawAddress& address) {
- // by default indicate link as encrypted
- ON_CALL(btm_interface, GetSecurityFlagsByTransport(address, NotNull(), _))
- .WillByDefault(
- DoAll(SetArgPointee<1>(BTM_SEC_FLAG_ENCRYPTED), Return(true)));
-
- EXPECT_CALL(gatt_interface, Open(gatt_if, address, true, _));
- CsisClient::Get()->Connect(address);
- Mock::VerifyAndClearExpectations(&gatt_interface);
- Mock::VerifyAndClearExpectations(&btm_interface);
- }
-
- void TestDisconnect(const RawAddress& address, uint16_t conn_id) {
- if (conn_id != GATT_INVALID_CONN_ID) {
- EXPECT_CALL(gatt_interface, Close(conn_id));
- EXPECT_CALL(*callbacks, OnConnectionState(test_address,
- ConnectionState::DISCONNECTED));
- } else {
- EXPECT_CALL(gatt_interface, CancelOpen(_, address, _));
- }
- CsisClient::Get()->Disconnect(address);
- }
-
- void TestAddFromStorage(const RawAddress& address, uint16_t conn_id,
- std::vector<uint8_t>& storage_buf) {
- EXPECT_CALL(*callbacks,
- OnConnectionState(address, ConnectionState::CONNECTED))
- .Times(1);
- EXPECT_CALL(*callbacks, OnDeviceAvailable(address, _, _, _)).Times(1);
- EXPECT_CALL(gatt_interface, Open(gatt_if, address, false, _))
- .WillOnce(Invoke([this, conn_id](tGATT_IF client_if,
- const RawAddress& remote_bda,
- bool is_direct, bool opportunistic) {
- InjectConnectedEvent(remote_bda, conn_id);
- GetSearchCompleteEvent(conn_id);
- }));
- CsisClient::AddFromStorage(address, storage_buf, true);
- }
-
- void InjectConnectedEvent(const RawAddress& address, uint16_t conn_id) {
- tBTA_GATTC_OPEN event_data = {
- .status = GATT_SUCCESS,
- .conn_id = conn_id,
- .client_if = gatt_if,
- .remote_bda = address,
- .transport = GATT_TRANSPORT_LE,
- .mtu = 240,
- };
-
- gatt_callback(BTA_GATTC_OPEN_EVT, (tBTA_GATTC*)&event_data);
- }
-
- void InjectDisconnectedEvent(
- const RawAddress& address, uint16_t conn_id,
- tGATT_DISCONN_REASON reason = GATT_CONN_TERMINATE_PEER_USER) {
- tBTA_GATTC_CLOSE event_data = {
- .status = GATT_SUCCESS,
- .conn_id = conn_id,
- .client_if = gatt_if,
- .remote_bda = address,
- .reason = reason,
- };
-
- gatt_callback(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC*)&event_data);
- }
-
- void GetSearchCompleteEvent(uint16_t conn_id) {
- tBTA_GATTC_SEARCH_CMPL event_data = {
- .status = GATT_SUCCESS,
- .conn_id = conn_id,
- };
-
- gatt_callback(BTA_GATTC_SEARCH_CMPL_EVT, (tBTA_GATTC*)&event_data);
- }
-
- void TestReadCharacteristic(const RawAddress& address, uint16_t conn_id,
- std::vector<uint16_t> handles) {
- SetSampleDatabaseCsis(conn_id, 1);
- TestAppRegister();
- TestConnect(address);
- InjectConnectedEvent(address, conn_id);
-
- EXPECT_CALL(gatt_queue, ReadCharacteristic(conn_id, _, _, _))
- .WillRepeatedly(DoDefault());
- for (auto const& handle : handles) {
- EXPECT_CALL(gatt_queue, ReadCharacteristic(conn_id, handle, _, _))
- .WillOnce(DoDefault());
- }
-
- GetSearchCompleteEvent(conn_id);
- TestAppUnregister();
- }
-
- void GetDisconnectedEvent(const RawAddress& address, uint16_t conn_id) {
- tBTA_GATTC_CLOSE event_data = {
- .status = GATT_SUCCESS,
- .conn_id = conn_id,
- .client_if = gatt_if,
- .remote_bda = address,
- .reason = GATT_CONN_TERMINATE_PEER_USER,
- };
-
- gatt_callback(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC*)&event_data);
- }
-
- void SetEncryptionResult(const RawAddress& address, bool success) {
- ON_CALL(btm_interface, GetSecurityFlagsByTransport(address, NotNull(), _))
- .WillByDefault(DoAll(SetArgPointee<1>(0), Return(true)));
- EXPECT_CALL(btm_interface,
- SetEncryption(address, _, NotNull(), _, BTM_BLE_SEC_ENCRYPT))
- .WillOnce(Invoke(
- [&success](const RawAddress& bd_addr, tBT_TRANSPORT transport,
- tBTM_SEC_CALLBACK* p_callback, void* p_ref_data,
- tBTM_BLE_SEC_ACT sec_act) -> tBTM_STATUS {
- p_callback(&bd_addr, transport, p_ref_data,
- success ? BTM_SUCCESS : BTM_FAILED_ON_SECURITY);
- return BTM_SUCCESS;
- }));
- }
-
- void SetSampleDatabaseCsis(uint16_t conn_id, uint8_t rank,
- uint8_t sirk_msb = 1) {
- set_sample_database(conn_id, true, false, rank, sirk_msb);
- }
- void SetSampleDatabaseNoCsis(uint16_t conn_id, uint8_t rank) {
- set_sample_database(conn_id, false, false, rank);
- }
- void SetSampleDatabaseCsisBroken(uint16_t conn_id, uint rank) {
- set_sample_database(conn_id, false, true, rank);
- }
- void SetSampleDatabaseDoubleCsis(uint16_t conn_id, uint8_t rank_1,
- uint8_t rank_2) {
- set_sample_database_double_csis(conn_id, rank_1, rank_2, false);
- }
- void SetSampleDatabaseDoubleCsisBroken(uint16_t conn_id, uint8_t rank_1,
- uint8_t rank_2) {
- set_sample_database_double_csis(conn_id, rank_1, rank_2, true);
- }
-
- std::unique_ptr<MockCsisCallbacks> callbacks;
- std::unique_ptr<MockCsisCallbacks> lock_callback;
- bluetooth::manager::MockBtmInterface btm_interface;
- dm::MockBtaDmInterface dm_interface;
- gatt::MockBtaGattInterface gatt_interface;
- gatt::MockBtaGattQueue gatt_queue;
- MockCsisLockCallback csis_lock_cb;
- tBTA_GATTC_CBACK* gatt_callback;
- const uint8_t gatt_if = 0xff;
- std::map<uint16_t, std::list<gatt::Service>> services_map;
-
- const RawAddress test_address = GetTestAddress(0);
- const RawAddress test_address2 = GetTestAddress(1);
-};
-
-TEST_F(CsisClientTest, test_get_uninitialized) {
- ASSERT_DEATH(CsisClient::Get(), "");
-}
-
-TEST_F(CsisClientTest, test_initialize) {
- CsisClient::Initialize(callbacks.get(), base::DoNothing());
- ASSERT_TRUE(CsisClient::IsCsisClientRunning());
- CsisClient::CleanUp();
-}
-
-TEST_F(CsisClientTest, test_initialize_twice) {
- CsisClient::Initialize(callbacks.get(), base::DoNothing());
- CsisClient* csis_p = CsisClient::Get();
- CsisClient::Initialize(callbacks.get(), base::DoNothing());
- ASSERT_EQ(csis_p, CsisClient::Get());
- CsisClient::CleanUp();
-}
-
-TEST_F(CsisClientTest, test_cleanup_initialized) {
- CsisClient::Initialize(callbacks.get(), base::DoNothing());
- CsisClient::CleanUp();
- ASSERT_FALSE(CsisClient::IsCsisClientRunning());
-}
-
-TEST_F(CsisClientTest, test_cleanup_uninitialized) {
- CsisClient::CleanUp();
- ASSERT_FALSE(CsisClient::IsCsisClientRunning());
-}
-
-TEST_F(CsisClientTest, test_app_registration) {
- TestAppRegister();
- TestAppUnregister();
-}
-
-TEST_F(CsisClientTest, test_connect) {
- TestAppRegister();
- TestConnect(GetTestAddress(0));
- TestAppUnregister();
-}
-
-TEST_F(CsisClientTest, test_disconnect_non_connected) {
- TestAppRegister();
- TestConnect(test_address);
- TestDisconnect(test_address, GATT_INVALID_CONN_ID);
- TestAppUnregister();
-}
-
-TEST_F(CsisClientTest, test_disconnect_connected) {
- TestAppRegister();
- TestConnect(test_address);
- InjectConnectedEvent(test_address, 1);
- TestDisconnect(test_address, 1);
- InjectDisconnectedEvent(test_address, 1);
- TestAppUnregister();
-}
-
-TEST_F(CsisClientTest, test_disconnected) {
- TestAppRegister();
- TestConnect(test_address);
- InjectConnectedEvent(test_address, 1);
- EXPECT_CALL(*callbacks,
- OnConnectionState(test_address, ConnectionState::DISCONNECTED));
- InjectDisconnectedEvent(test_address, 1);
-
- TestAppUnregister();
-}
-
-TEST_F(CsisClientTest, test_discovery_csis_found) {
- SetSampleDatabaseCsis(1, 1);
- TestAppRegister();
- TestConnect(test_address);
- EXPECT_CALL(*callbacks,
- OnConnectionState(test_address, ConnectionState::CONNECTED));
- EXPECT_CALL(*callbacks, OnDeviceAvailable(test_address, _, _, _));
- InjectConnectedEvent(test_address, 1);
- GetSearchCompleteEvent(1);
- Mock::VerifyAndClearExpectations(callbacks.get());
- TestAppUnregister();
-}
-
-TEST_F(CsisClientTest, test_discovery_csis_not_found) {
- SetSampleDatabaseNoCsis(1, 1);
- TestAppRegister();
- TestConnect(test_address);
- EXPECT_CALL(gatt_interface, Close(1));
- InjectConnectedEvent(test_address, 1);
- GetSearchCompleteEvent(1);
- Mock::VerifyAndClearExpectations(callbacks.get());
- TestAppUnregister();
-}
-
-TEST_F(CsisClientTest, test_discovery_csis_broken) {
- SetSampleDatabaseCsisBroken(1, 1);
- TestAppRegister();
- TestConnect(test_address);
- EXPECT_CALL(gatt_interface, Close(1));
- InjectConnectedEvent(test_address, 1);
- GetSearchCompleteEvent(1);
- Mock::VerifyAndClearExpectations(callbacks.get());
- TestAppUnregister();
-}
-
-class CsisClientCallbackTest : public CsisClientTest {
- protected:
- const RawAddress test_address = GetTestAddress(0);
- uint16_t conn_id = 22;
-
- void SetUp(void) override {
- CsisClientTest::SetUp();
- SetSampleDatabaseCsis(conn_id, 1);
- TestAppRegister();
- TestConnect(test_address);
- InjectConnectedEvent(test_address, conn_id);
- GetSearchCompleteEvent(conn_id);
- }
-
- void TearDown(void) override {
- TestAppUnregister();
- CsisClientTest::TearDown();
- }
-
- void GetNotificationEvent(uint16_t handle, std::vector<uint8_t>& value) {
- tBTA_GATTC_NOTIFY event_data = {
- .conn_id = conn_id,
- .bda = test_address,
- .handle = handle,
- .len = (uint8_t)value.size(),
- .is_notify = true,
- };
-
- std::copy(value.begin(), value.end(), event_data.value);
- gatt_callback(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC*)&event_data);
- }
-};
-
-TEST_F(CsisClientCallbackTest, test_on_group_lock_changed_group_not_found) {
- bool callback_called = false;
- EXPECT_CALL(
- *callbacks,
- OnGroupLockChanged(2, false, CsisGroupLockStatus::FAILED_INVALID_GROUP));
- CsisClient::Get()->LockGroup(
- 2, true,
- base::BindOnce(
- [](bool* callback_called, int group_id, bool locked,
- CsisGroupLockStatus status) {
- if ((group_id == 2) &&
- (status == CsisGroupLockStatus::FAILED_INVALID_GROUP))
- *callback_called = true;
- },
- &callback_called));
- ASSERT_TRUE(callback_called);
-}
-
-TEST_F(CsisClientTest, test_get_group_id) {
- SetSampleDatabaseCsis(1, 1);
- TestAppRegister();
- TestConnect(test_address);
- EXPECT_CALL(*callbacks,
- OnConnectionState(test_address, ConnectionState::CONNECTED));
- EXPECT_CALL(*callbacks, OnDeviceAvailable(test_address, _, _, _));
- InjectConnectedEvent(test_address, 1);
- GetSearchCompleteEvent(1);
- int group_id = CsisClient::Get()->GetGroupId(test_address);
- ASSERT_TRUE(group_id == 1);
- TestAppUnregister();
-}
-
-TEST_F(CsisClientTest, test_is_group_empty) {
- std::list<std::shared_ptr<CsisGroup>> csis_groups_;
- auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
- csis_groups_.push_back(g_1);
-
- ASSERT_TRUE(g_1->IsEmpty());
-}
-
-TEST_F(CsisClientTest, test_add_device_to_group) {
- auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
- auto d_1 = std::make_shared<CsisDevice>();
-
- ASSERT_TRUE(g_1->IsEmpty());
- g_1->AddDevice(d_1);
- ASSERT_FALSE(g_1->IsEmpty());
-}
-
-TEST_F(CsisClientTest, test_set_desired_size) {
- auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
- g_1->SetDesiredSize(10);
- ASSERT_EQ((int)sizeof(g_1), 16);
-}
-
-TEST_F(CsisClientTest, test_get_desired_size) {
- auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
- g_1->SetDesiredSize(10);
- ASSERT_EQ(g_1->GetDesiredSize(), 10);
-}
-
-TEST_F(CsisClientTest, test_is_device_in_the_group) {
- auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
- auto d_1 = std::make_shared<CsisDevice>();
- g_1->AddDevice(d_1);
- g_1->IsDeviceInTheGroup(d_1);
-}
-
-TEST_F(CsisClientTest, test_get_current_size) {
- const RawAddress test_address_1 = GetTestAddress(0);
- const RawAddress test_address_2 = GetTestAddress(1);
- const RawAddress test_address_3 = GetTestAddress(2);
- auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
- auto d_1 = std::make_shared<CsisDevice>(test_address_1, true);
- auto d_2 = std::make_shared<CsisDevice>(test_address_2, true);
- auto d_3 = std::make_shared<CsisDevice>(test_address_3, true);
- g_1->AddDevice(d_1);
- g_1->AddDevice(d_2);
- g_1->AddDevice(d_3);
- ASSERT_EQ(3, g_1->GetCurrentSize());
-}
-
-TEST_F(CsisClientTest, test_set_current_lock_state_unset) {
- auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
- g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_UNSET);
- ASSERT_EQ(g_1->GetCurrentLockState(), CsisLockState::CSIS_STATE_UNSET);
-}
-
-TEST_F(CsisClientTest, test_set_current_lock_state_locked) {
- auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
- g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_LOCKED);
- ASSERT_EQ(g_1->GetCurrentLockState(), CsisLockState::CSIS_STATE_LOCKED);
-}
-
-TEST_F(CsisClientTest, test_set_current_lock_state_unlocked) {
- auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
- g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_UNLOCKED);
- ASSERT_EQ(g_1->GetCurrentLockState(), CsisLockState::CSIS_STATE_UNLOCKED);
-}
-
-TEST_F(CsisClientTest, test_set_various_lock_states) {
- auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
- g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_UNLOCKED);
- ASSERT_EQ(g_1->GetCurrentLockState(), CsisLockState::CSIS_STATE_UNLOCKED);
- g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_LOCKED);
- ASSERT_EQ(g_1->GetCurrentLockState(), CsisLockState::CSIS_STATE_LOCKED);
- g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_UNSET);
- ASSERT_EQ(g_1->GetCurrentLockState(), CsisLockState::CSIS_STATE_UNSET);
-}
-
-TEST_F(CsisClientTest, test_set_discovery_state_completed) {
- auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
- g_1->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_COMPLETED);
- ASSERT_EQ(g_1->GetDiscoveryState(),
- CsisDiscoveryState::CSIS_DISCOVERY_COMPLETED);
-}
-
-TEST_F(CsisClientTest, test_set_discovery_state_idle) {
- auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
- g_1->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_IDLE);
- ASSERT_EQ(g_1->GetDiscoveryState(), CsisDiscoveryState::CSIS_DISCOVERY_IDLE);
-}
-
-TEST_F(CsisClientTest, test_set_discovery_state_ongoing) {
- auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
- g_1->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_ONGOING);
- ASSERT_EQ(g_1->GetDiscoveryState(),
- CsisDiscoveryState::CSIS_DISCOVERY_ONGOING);
-}
-
-TEST_F(CsisClientTest, test_set_various_discovery_states) {
- auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
- g_1->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_COMPLETED);
- ASSERT_EQ(g_1->GetDiscoveryState(),
- CsisDiscoveryState::CSIS_DISCOVERY_COMPLETED);
- g_1->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_IDLE);
- ASSERT_EQ(g_1->GetDiscoveryState(), CsisDiscoveryState::CSIS_DISCOVERY_IDLE);
- g_1->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_ONGOING);
- ASSERT_EQ(g_1->GetDiscoveryState(),
- CsisDiscoveryState::CSIS_DISCOVERY_ONGOING);
-}
-
-TEST_F(CsisClientTest, test_get_first_last_device) {
- const RawAddress test_address_3 = GetTestAddress(3);
- const RawAddress test_address_4 = GetTestAddress(4);
- const RawAddress test_address_5 = GetTestAddress(5);
- auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
- auto d_1 = std::make_shared<CsisDevice>(test_address_3, true);
- auto d_2 = std::make_shared<CsisDevice>(test_address_4, true);
- auto d_3 = std::make_shared<CsisDevice>(test_address_5, true);
- g_1->AddDevice(d_1);
- g_1->AddDevice(d_2);
- g_1->AddDevice(d_3);
- ASSERT_EQ(g_1->GetLastDevice(), d_3);
- ASSERT_EQ(g_1->GetFirstDevice(), d_1);
-}
-
-TEST_F(CsisClientTest, test_get_set_sirk) {
- auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
- Octet16 sirk = {1};
- g_1->SetSirk(sirk);
- ASSERT_EQ(g_1->GetSirk(), sirk);
-}
-
-class CsisMultiClientTest : public CsisClientTest {
- protected:
- const RawAddress test_address_1 = GetTestAddress(1);
- const RawAddress test_address_2 = GetTestAddress(2);
-
- void SetUp(void) override {
- CsisClientTest::SetUp();
- TestAppRegister();
- SetSampleDatabaseDoubleCsis(0x001, 1, 2);
- }
-};
-
-class CsisMultiClientTestBroken : public CsisClientTest {
- protected:
- const RawAddress test_address_1 = GetTestAddress(1);
- const RawAddress test_address_2 = GetTestAddress(2);
-
- void SetUp(void) override {
- CsisClientTest::SetUp();
- TestAppRegister();
- SetSampleDatabaseDoubleCsisBroken(0x001, 1, 2);
- }
-};
-
-TEST_F(CsisMultiClientTest, test_add_multiple_instances) {
- TestAppUnregister();
- CsisClientTest::TearDown();
-}
-
-TEST_F(CsisMultiClientTest, test_cleanup_multiple_instances) {
- CsisClient::CleanUp();
- CsisClient::IsCsisClientRunning();
-}
-
-TEST_F(CsisMultiClientTest, test_connect_multiple_instances) {
- TestConnect(GetTestAddress(0));
- TestAppUnregister();
-}
-
-TEST_F(CsisMultiClientTest, test_disconnect_multiple_instances) {
- TestConnect(test_address);
- InjectConnectedEvent(test_address, 1);
- EXPECT_CALL(*callbacks,
- OnConnectionState(test_address, ConnectionState::DISCONNECTED));
- InjectDisconnectedEvent(test_address, 1);
-
- TestAppUnregister();
- CsisClientTest::TearDown();
-}
-
-TEST_F(CsisMultiClientTest, test_lock_multiple_instances) {
- TestConnect(test_address);
- InjectConnectedEvent(test_address, 1);
- GetSearchCompleteEvent(1);
-
- EXPECT_CALL(*callbacks,
- OnGroupLockChanged(1, true, CsisGroupLockStatus::SUCCESS));
- EXPECT_CALL(*csis_lock_callback_mock,
- CsisGroupLockCb(1, true, CsisGroupLockStatus::SUCCESS));
- ON_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _))
- .WillByDefault(
- Invoke([](uint16_t conn_id, uint16_t handle,
- std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
- GATT_WRITE_OP_CB cb, void* cb_data) -> void {
- if (cb)
- cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
- cb_data);
- }));
- CsisClient::Get()->LockGroup(
- 1, true,
- base::BindOnce([](int group_id, bool locked, CsisGroupLockStatus status) {
- csis_lock_callback_mock->CsisGroupLockCb(group_id, locked, status);
- }));
-
- EXPECT_CALL(*callbacks,
- OnGroupLockChanged(2, true, CsisGroupLockStatus::SUCCESS));
- EXPECT_CALL(*csis_lock_callback_mock,
- CsisGroupLockCb(2, true, CsisGroupLockStatus::SUCCESS));
- CsisClient::Get()->LockGroup(
- 2, true,
- base::BindOnce([](int group_id, bool locked, CsisGroupLockStatus status) {
- csis_lock_callback_mock->CsisGroupLockCb(group_id, locked, status);
- }));
-}
-
-TEST_F(CsisMultiClientTest, test_unlock_multiple_instances) {
- TestConnect(test_address);
- InjectConnectedEvent(test_address, 1);
- GetSearchCompleteEvent(1);
-
- ON_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _))
- .WillByDefault(
- Invoke([](uint16_t conn_id, uint16_t handle,
- std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
- GATT_WRITE_OP_CB cb, void* cb_data) -> void {
- if (cb)
- cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
- cb_data);
- }));
- CsisClient::Get()->LockGroup(
- 1, true,
- base::BindOnce([](int group_id, bool locked, CsisGroupLockStatus status) {
- csis_lock_callback_mock->CsisGroupLockCb(group_id, locked, status);
- }));
-
- EXPECT_CALL(*callbacks,
- OnGroupLockChanged(1, false, CsisGroupLockStatus::SUCCESS));
- EXPECT_CALL(*csis_lock_callback_mock,
- CsisGroupLockCb(1, false, CsisGroupLockStatus::SUCCESS));
- CsisClient::Get()->LockGroup(
- 1, false,
- base::BindOnce([](int group_id, bool locked, CsisGroupLockStatus status) {
- csis_lock_callback_mock->CsisGroupLockCb(group_id, locked, status);
- }));
-}
-
-TEST_F(CsisMultiClientTest, test_disconnect_locked_multiple_instances) {
- TestConnect(test_address);
- InjectConnectedEvent(test_address, 1);
- GetSearchCompleteEvent(1);
-
- TestConnect(test_address2);
- InjectConnectedEvent(test_address2, 2);
- GetSearchCompleteEvent(2);
-
- EXPECT_CALL(*callbacks,
- OnGroupLockChanged(1, true, CsisGroupLockStatus::SUCCESS));
- EXPECT_CALL(*csis_lock_callback_mock,
- CsisGroupLockCb(1, true, CsisGroupLockStatus::SUCCESS));
- ON_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _))
- .WillByDefault(
- Invoke([](uint16_t conn_id, uint16_t handle,
- std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
- GATT_WRITE_OP_CB cb, void* cb_data) -> void {
- if (cb)
- cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
- cb_data);
- }));
- CsisClient::Get()->LockGroup(
- 1, true,
- base::BindOnce([](int group_id, bool locked, CsisGroupLockStatus status) {
- csis_lock_callback_mock->CsisGroupLockCb(group_id, locked, status);
- }));
-
- EXPECT_CALL(*callbacks,
- OnGroupLockChanged(
- 1, false, CsisGroupLockStatus::LOCKED_GROUP_MEMBER_LOST));
- InjectDisconnectedEvent(test_address, 2, GATT_CONN_TIMEOUT);
-}
-
-TEST_F(CsisMultiClientTest, test_discover_multiple_instances) {
- TestConnect(test_address);
- EXPECT_CALL(*callbacks,
- OnConnectionState(test_address, ConnectionState::CONNECTED))
- .Times(1);
- EXPECT_CALL(*callbacks, OnDeviceAvailable(test_address, _, _, _)).Times(2);
- InjectConnectedEvent(test_address, 1);
- GetSearchCompleteEvent(1);
- Mock::VerifyAndClearExpectations(callbacks.get());
- TestAppUnregister();
-}
-
-TEST_F(CsisClientTest, test_storage_calls) {
- SetSampleDatabaseCsis(1, 1);
-
- ASSERT_EQ(0,
- mock_function_count_map["btif_storage_load_bonded_csis_devices"]);
- TestAppRegister();
- ASSERT_EQ(1,
- mock_function_count_map["btif_storage_load_bonded_csis_devices"]);
-
- ASSERT_EQ(0, mock_function_count_map["btif_storage_update_csis_info"]);
- ASSERT_EQ(0, mock_function_count_map["btif_storage_set_csis_autoconnect"]);
- TestConnect(test_address);
- InjectConnectedEvent(test_address, 1);
- GetSearchCompleteEvent(1);
- ASSERT_EQ(1, mock_function_count_map["btif_storage_set_csis_autoconnect"]);
- ASSERT_EQ(1, mock_function_count_map["btif_storage_update_csis_info"]);
-
- ASSERT_EQ(0, mock_function_count_map["btif_storage_remove_csis_device"]);
- CsisClient::Get()->RemoveDevice(test_address);
- ASSERT_EQ(1, mock_function_count_map["btif_storage_remove_csis_device"]);
-
- TestAppUnregister();
-}
-
-TEST_F(CsisClientTest, test_storage_content) {
- // Two devices in one set
- SetSampleDatabaseCsis(1, 1);
- SetSampleDatabaseCsis(2, 2);
- // Devices in the other set
- SetSampleDatabaseCsis(3, 1, 2);
- SetSampleDatabaseCsis(4, 1, 2);
-
- TestAppRegister();
- TestConnect(GetTestAddress(1));
- InjectConnectedEvent(GetTestAddress(1), 1);
- GetSearchCompleteEvent(1);
- ASSERT_EQ(1, CsisClient::Get()->GetGroupId(
- GetTestAddress(1), bluetooth::Uuid::From16Bit(0x0000)));
-
- TestConnect(GetTestAddress(2));
- InjectConnectedEvent(GetTestAddress(2), 2);
- GetSearchCompleteEvent(2);
- ASSERT_EQ(1, CsisClient::Get()->GetGroupId(
- GetTestAddress(2), bluetooth::Uuid::From16Bit(0x0000)));
-
- TestConnect(GetTestAddress(3));
- InjectConnectedEvent(GetTestAddress(3), 3);
- GetSearchCompleteEvent(3);
- ASSERT_EQ(2, CsisClient::Get()->GetGroupId(
- GetTestAddress(3), bluetooth::Uuid::From16Bit(0x0000)));
-
- std::vector<uint8_t> dev1_storage;
- std::vector<uint8_t> dev2_storage;
- std::vector<uint8_t> dev3_storage;
-
- // Store to byte buffer
- CsisClient::GetForStorage(GetTestAddress(1), dev1_storage);
- CsisClient::GetForStorage(GetTestAddress(2), dev2_storage);
- CsisClient::GetForStorage(GetTestAddress(3), dev3_storage);
- ASSERT_NE(0u, dev1_storage.size());
- ASSERT_NE(0u, dev2_storage.size());
- ASSERT_NE(0u, dev3_storage.size());
-
- // Clean it up
- TestAppUnregister();
-
- // Reinitialize service
- TestAppRegister();
-
- // Restore dev1 from the byte buffer
- TestAddFromStorage(GetTestAddress(1), 1, dev1_storage);
- ASSERT_EQ(1, CsisClient::Get()->GetGroupId(
- GetTestAddress(1), bluetooth::Uuid::From16Bit(0x0000)));
-
- // Restore dev2 from the byte buffer
- TestAddFromStorage(GetTestAddress(2), 2, dev2_storage);
- ASSERT_EQ(1, CsisClient::Get()->GetGroupId(
- GetTestAddress(2), bluetooth::Uuid::From16Bit(0x0000)));
-
- // Restore dev3 from the byte buffer
- TestAddFromStorage(GetTestAddress(3), 3, dev3_storage);
- ASSERT_EQ(2, CsisClient::Get()->GetGroupId(
- GetTestAddress(3), bluetooth::Uuid::From16Bit(0x0000)));
-
- // Restore not inerrogated dev4 - empty buffer but valid sirk for group 2
- std::vector<uint8_t> no_set_info;
- TestAddFromStorage(GetTestAddress(4), 4, no_set_info);
- ASSERT_EQ(2, CsisClient::Get()->GetGroupId(
- GetTestAddress(4), bluetooth::Uuid::From16Bit(0x0000)));
-
- TestAppUnregister();
-}
-
-} // namespace
-} // namespace internal
-} // namespace csis
-} // namespace bluetooth
diff --git a/bta/csis/csis_types.h b/bta/csis/csis_types.h
deleted file mode 100644
index 0be02fd..0000000
--- a/bta/csis/csis_types.h
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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 <base/logging.h>
-#include <base/strings/string_number_conversions.h>
-
-#include <algorithm>
-#include <map>
-#include <vector>
-
-#include "bta_csis_api.h"
-#include "bta_gatt_api.h"
-#include "bta_groups.h"
-#include "gap_api.h"
-#include "stack/crypto_toolbox/crypto_toolbox.h"
-
-namespace bluetooth {
-namespace csis {
-
-using bluetooth::csis::CsisLockCb;
-
-// CSIP additions
-/* Generic UUID is used when CSIS is not included in any context */
-static const bluetooth::Uuid kCsisServiceUuid = bluetooth::Uuid::From16Bit(0x1846);
-static const bluetooth::Uuid kCsisSirkUuid = bluetooth::Uuid::From16Bit(0x2B84);
-static const bluetooth::Uuid kCsisSizeUuid = bluetooth::Uuid::From16Bit(0x2B85);
-static const bluetooth::Uuid kCsisLockUuid = bluetooth::Uuid::From16Bit(0x2B86);
-static const bluetooth::Uuid kCsisRankUuid = bluetooth::Uuid::From16Bit(0x2B87);
-
-static constexpr uint8_t kCsisErrorCodeLockDenied = 0x80;
-static constexpr uint8_t kCsisErrorCodeReleaseNotAllowed = 0x81;
-static constexpr uint8_t kCsisErrorCodeInvalidValue = 0x82;
-static constexpr uint8_t kCsisErrorCodeLockAccessSirkRejected = 0x83;
-static constexpr uint8_t kCsisErrorCodeLockOobSirkOnly = 0x84;
-static constexpr uint8_t kCsisErrorCodeLockAlreadyGranted = 0x85;
-
-static constexpr uint8_t kCsisSirkTypeEncrypted = 0x00;
-static constexpr uint8_t kCsisSirkCharLen = 17;
-
-struct hdl_pair {
- hdl_pair() {}
- hdl_pair(uint16_t val_hdl, uint16_t ccc_hdl) : val_hdl(val_hdl), ccc_hdl(ccc_hdl) {}
-
- uint16_t val_hdl;
- uint16_t ccc_hdl;
-};
-
-/* CSIS Types */
-static constexpr uint8_t kDefaultScanDurationS = 5;
-static constexpr uint8_t kDefaultCsisSetSize = 2;
-static constexpr uint8_t kUnknownRank = 0xff;
-
-/* Enums */
-enum class CsisLockState : uint8_t {
- CSIS_STATE_UNSET = 0x00,
- CSIS_STATE_UNLOCKED,
- CSIS_STATE_LOCKED
-};
-
-enum class CsisDiscoveryState : uint8_t {
- CSIS_DISCOVERY_IDLE = 0x00,
- CSIS_DISCOVERY_ONGOING,
- CSIS_DISCOVERY_COMPLETED,
-};
-
-class GattServiceDevice {
- public:
- RawAddress addr;
- /*
- * This is true only during first connection to profile, until we store the
- * device.
- */
- bool first_connection;
-
- /*
- * We are making active attempt to connect to this device, 'direct connect'.
- */
- bool connecting_actively = false;
-
- uint16_t conn_id = GATT_INVALID_CONN_ID;
- uint16_t service_handle = GAP_INVALID_HANDLE;
- bool is_gatt_service_valid = false;
-
- GattServiceDevice(const RawAddress& addr, bool first_connection)
- : addr(addr), first_connection(first_connection) {}
-
- GattServiceDevice() : GattServiceDevice(RawAddress::kEmpty, false) {}
-
- bool IsConnected() const { return (conn_id != GATT_INVALID_CONN_ID); }
-
- class MatchAddress {
- private:
- RawAddress addr;
-
- public:
- MatchAddress(const RawAddress& addr) : addr(addr) {}
- bool operator()(const std::shared_ptr<GattServiceDevice>& other) const {
- return (addr == other->addr);
- }
- };
-
- class MatchConnId {
- private:
- uint16_t conn_id;
-
- public:
- MatchConnId(uint16_t conn_id) : conn_id(conn_id) {}
- bool operator()(const std::shared_ptr<GattServiceDevice>& other) const {
- return (conn_id == other->conn_id);
- }
- };
-};
-
-/*
- * CSIS instance represents single CSIS service on the remote device
- * along with the handle in database and specific data to control CSIS like:
- * rank, lock state.
- *
- * It also inclues UUID of the primary service which includes that CSIS
- * instance. If this is 0x0000 it means CSIS is per device and not for specific
- * service.
- */
-class CsisInstance {
- public:
- bluetooth::Uuid coordinated_service = bluetooth::groups::kGenericContextUuid;
-
- struct SvcData {
- uint16_t start_handle;
- uint16_t end_handle;
- struct hdl_pair sirk_handle;
- struct hdl_pair lock_handle;
- uint16_t rank_handle;
- struct hdl_pair size_handle;
- } svc_data = {
- GAP_INVALID_HANDLE,
- GAP_INVALID_HANDLE,
- {GAP_INVALID_HANDLE, GAP_INVALID_HANDLE},
- {GAP_INVALID_HANDLE, GAP_INVALID_HANDLE},
- GAP_INVALID_HANDLE,
- {GAP_INVALID_HANDLE, GAP_INVALID_HANDLE},
- };
-
- CsisInstance(uint16_t start_handle, uint16_t end_handle, const bluetooth::Uuid& uuid)
- : coordinated_service(uuid),
- group_id_(bluetooth::groups::kGroupUnknown),
- rank_(kUnknownRank),
- lock_state_(CsisLockState::CSIS_STATE_UNSET) {
- svc_data.start_handle = start_handle;
- svc_data.end_handle = end_handle;
- }
-
- void SetLockState(CsisLockState state) {
- DLOG(INFO) << __func__ << " current lock state: " << (int)(lock_state_)
- << " new lock state: " << (int)(state);
- lock_state_ = state;
- }
- CsisLockState GetLockState(void) const { return lock_state_; }
- uint8_t GetRank(void) const { return rank_; }
- void SetRank(uint8_t rank) {
- DLOG(INFO) << __func__ << " current rank state: " << loghex(rank_)
- << " new lock state: " << loghex(rank);
- rank_ = rank;
- }
-
- void SetGroupId(int group_id) {
- LOG(INFO) << __func__ << " set group id: " << group_id
- << " instance handle: " << loghex(svc_data.start_handle);
- group_id_ = group_id;
- }
-
- int GetGroupId(void) const { return group_id_; }
-
- bool HasSameUuid(const CsisInstance& csis_instance) const {
- return (csis_instance.coordinated_service == coordinated_service);
- }
-
- const bluetooth::Uuid& GetUuid(void) const { return coordinated_service; }
- bool IsForUuid(const bluetooth::Uuid& uuid) const { return coordinated_service == uuid; }
-
- private:
- int group_id_;
- uint8_t rank_;
- CsisLockState lock_state_;
-};
-
-/*
- * Csis Device represents remote device and its all CSIS instances.
- * It can happen that device can have more than one CSIS service instance
- * if those instances are included in other services. In this way, coordinated
- * set is within the context of the primary service which includes the instance.
- *
- * CsisDevice contains vector of the instances.
- */
-class CsisDevice : public GattServiceDevice {
- public:
- using GattServiceDevice::GattServiceDevice;
-
- void ClearSvcData() {
- GattServiceDevice::service_handle = GAP_INVALID_HANDLE;
- GattServiceDevice::is_gatt_service_valid = false;
-
- csis_instances_.clear();
- }
-
- std::shared_ptr<CsisInstance> GetCsisInstanceByOwningHandle(uint16_t handle) {
- uint16_t hdl = 0;
- for (const auto& [h, inst] : csis_instances_) {
- if (handle >= inst->svc_data.start_handle && handle <= inst->svc_data.end_handle) {
- hdl = h;
- DLOG(INFO) << __func__ << " found " << loghex(hdl);
- break;
- }
- }
- return (hdl > 0) ? csis_instances_.at(hdl) : nullptr;
- }
-
- std::shared_ptr<CsisInstance> GetCsisInstanceByGroupId(int group_id) {
- uint16_t hdl = 0;
- for (const auto& [handle, inst] : csis_instances_) {
- if (inst->GetGroupId() == group_id) {
- hdl = handle;
- break;
- }
- }
- return (hdl > 0) ? csis_instances_.at(hdl) : nullptr;
- }
-
- void SetCsisInstance(uint16_t handle, std::shared_ptr<CsisInstance> csis_instance) {
- if (csis_instances_.count(handle)) {
- DLOG(INFO) << __func__ << " instance is already here: " << csis_instance->GetUuid();
- return;
- }
-
- csis_instances_.insert({handle, csis_instance});
- DLOG(INFO) << __func__ << " instance added: " << loghex(handle) << "device: " << addr;
- }
-
- void RemoveCsisInstance(int group_id) {
- for (auto it = csis_instances_.begin(); it != csis_instances_.end(); it++) {
- if (it->second->GetGroupId() == group_id) {
- csis_instances_.erase(it);
- return;
- }
- }
- }
-
- int GetNumberOfCsisInstances(void) { return csis_instances_.size(); }
-
- void ForEachCsisInstance(std::function<void(const std::shared_ptr<CsisInstance>&)> cb) {
- for (auto const& kv_pair : csis_instances_) {
- cb(kv_pair.second);
- }
- }
-
- private:
- /* Instances per start handle */
- std::map<uint16_t, std::shared_ptr<CsisInstance>> csis_instances_;
-};
-
-/*
- * CSIS group gathers devices which belongs to specific group.
- * It also contains methond to decode encrypted SIRK and also to
- * resolve PRSI in order to find out if device belongs to given group
- */
-class CsisGroup {
- public:
- CsisGroup(int group_id, const bluetooth::Uuid& uuid)
- : group_id_(group_id),
- size_(kDefaultCsisSetSize),
- uuid_(uuid),
- member_discovery_state_(CsisDiscoveryState::CSIS_DISCOVERY_IDLE),
- lock_state_(CsisLockState::CSIS_STATE_UNSET),
- target_lock_state_(CsisLockState::CSIS_STATE_UNSET),
- lock_transition_cnt_(0) {
- devices_.clear();
- }
-
- void AddDevice(std::shared_ptr<CsisDevice> csis_device) {
- auto it =
- find_if(devices_.begin(), devices_.end(), CsisDevice::MatchAddress(csis_device->addr));
- if (it != devices_.end()) return;
-
- devices_.push_back(std::move(csis_device));
- }
-
- void RemoveDevice(const RawAddress& bd_addr) {
- auto it = find_if(devices_.begin(), devices_.end(), CsisDevice::MatchAddress(bd_addr));
- if (it != devices_.end()) devices_.erase(it);
- }
-
- int GetCurrentSize(void) const { return devices_.size(); }
- bluetooth::Uuid GetUuid() const { return uuid_; }
- void SetUuid(const bluetooth::Uuid& uuid) { uuid_ = uuid; }
- int GetGroupId(void) const { return group_id_; }
- int GetDesiredSize(void) const { return size_; }
- void SetDesiredSize(int size) { size_ = size; }
- bool IsGroupComplete(void) const { return size_ == (int)devices_.size(); }
- bool IsEmpty(void) const { return devices_.empty(); }
-
- bool IsDeviceInTheGroup(std::shared_ptr<CsisDevice>& csis_device) {
- auto it =
- find_if(devices_.begin(), devices_.end(), CsisDevice::MatchAddress(csis_device->addr));
- return (it != devices_.end());
- }
- bool IsRsiMatching(const RawAddress& rsi) const { return is_rsi_match_sirk(rsi, GetSirk()); }
- bool IsSirkBelongsToGroup(Octet16 sirk) const { return (sirk_available_ && sirk_ == sirk); }
- Octet16 GetSirk(void) const { return sirk_; }
- void SetSirk(Octet16& sirk) {
- if (sirk_available_) {
- DLOG(INFO) << __func__ << " Updating SIRK";
- }
- sirk_available_ = true;
- sirk_ = sirk;
- }
-
- int GetNumOfConnectedDevices(void) {
- return std::count_if(devices_.begin(), devices_.end(),
- [](auto& d) { return d->IsConnected(); });
- }
-
- CsisDiscoveryState GetDiscoveryState(void) const { return member_discovery_state_; }
- void SetDiscoveryState(CsisDiscoveryState state) {
- DLOG(INFO) << __func__ << " current discovery state: " << (int)(member_discovery_state_)
- << " new discovery state: " << (int)(state);
- member_discovery_state_ = state;
- }
-
- void SetCurrentLockState(CsisLockState state) { lock_state_ = state; }
-
- void SetTargetLockState(CsisLockState state, CsisLockCb cb = base::DoNothing()) {
- target_lock_state_ = state;
- cb_ = std::move(cb);
- switch (state) {
- case CsisLockState::CSIS_STATE_LOCKED:
- lock_transition_cnt_ = GetNumOfConnectedDevices();
- break;
- case CsisLockState::CSIS_STATE_UNLOCKED:
- case CsisLockState::CSIS_STATE_UNSET:
- lock_transition_cnt_ = 0;
- break;
- }
- }
-
- CsisLockCb GetLockCb(void) { return std::move(cb_); }
-
- CsisLockState GetCurrentLockState(void) const { return lock_state_; }
- CsisLockState GetTargetLockState(void) const { return target_lock_state_; }
-
- bool IsAvailableForCsisLockOperation(void) {
- int id = group_id_;
- auto iter = std::find_if(devices_.begin(), devices_.end(), [id](auto& d) {
- if (!d->IsConnected()) return false;
- auto inst = d->GetCsisInstanceByGroupId(id);
- LOG_ASSERT(inst);
- return inst->GetLockState() == CsisLockState::CSIS_STATE_LOCKED;
- });
-
- /* If there is no locked device, we are good to go */
- return iter == devices_.end();
- }
-
- void SortByCsisRank(void) {
- int id = group_id_;
- std::sort(devices_.begin(), devices_.end(), [id](auto& dev1, auto& dev2) {
- auto inst1 = dev1->GetCsisInstanceByGroupId(id);
- auto inst2 = dev2->GetCsisInstanceByGroupId(id);
- if (!inst1 || !inst2) {
- /* One of the device is not connected */
- DLOG(INFO) << __func__ << " one of the device is not connected: inst1: " << inst1
- << " inst2: " << inst2;
- return dev1->IsConnected();
- }
- return (inst1->GetRank() < inst2->GetRank());
- });
- }
-
- std::shared_ptr<CsisDevice> GetFirstDevice(void) { return (devices_.front()); }
- std::shared_ptr<CsisDevice> GetLastDevice(void) { return (devices_.back()); }
- std::shared_ptr<CsisDevice> GetNextDevice(std::shared_ptr<CsisDevice>& device) {
- auto iter =
- std::find_if(devices_.begin(), devices_.end(), CsisDevice::MatchAddress(device->addr));
-
- /* If reference device not found */
- if (iter == devices_.end()) return nullptr;
-
- iter++;
- /* If reference device is last in group */
- if (iter == devices_.end()) return nullptr;
-
- return (*iter);
- }
- std::shared_ptr<CsisDevice> GetPrevDevice(std::shared_ptr<CsisDevice>& device) {
- auto iter =
- std::find_if(devices_.rbegin(), devices_.rend(), CsisDevice::MatchAddress(device->addr));
-
- /* If reference device not found */
- if (iter == devices_.rend()) return nullptr;
-
- iter++;
-
- if (iter == devices_.rend()) return nullptr;
- return (*iter);
- }
-
- int GetLockTransitionCnt(void) const { return lock_transition_cnt_; }
- int UpdateLockTransitionCnt(int i) {
- lock_transition_cnt_ += i;
- return lock_transition_cnt_;
- }
-
- /* Return true if given Autoset Private Address |srpa| matches Set Identity
- * Resolving Key |sirk| */
- static bool is_rsi_match_sirk(const RawAddress& rsi, const Octet16& sirk) {
- /* use the 3 MSB of bd address as prand */
- uint8_t rand[3];
- rand[0] = rsi.address[2];
- rand[1] = rsi.address[1];
- rand[2] = rsi.address[0];
- DLOG(INFO) << "Prand " << base::HexEncode(rand, 3);
-
- DLOG(INFO) << "SIRK " << base::HexEncode(sirk.data(), 16);
- /* generate X = E irk(R0, R1, R2) and R is random address 3 LSO */
- Octet16 x = crypto_toolbox::aes_128(sirk, &rand[0], 3);
-
- DLOG(INFO) << "X" << base::HexEncode(x.data(), 16);
-
- rand[0] = rsi.address[5];
- rand[1] = rsi.address[4];
- rand[2] = rsi.address[3];
-
- DLOG(INFO) << "Hash " << base::HexEncode(rand, 3);
-
- if (memcmp(x.data(), &rand[0], 3) == 0) {
- // match
- return true;
- }
- // not a match
- return false;
- }
-
- private:
- int group_id_;
- Octet16 sirk_ = {0};
- bool sirk_available_ = false;
- int size_;
- bluetooth::Uuid uuid_;
-
- std::vector<std::shared_ptr<CsisDevice>> devices_;
- CsisDiscoveryState member_discovery_state_;
-
- CsisLockState lock_state_;
- CsisLockState target_lock_state_;
- int lock_transition_cnt_;
-
- CsisLockCb cb_;
-};
-
-} // namespace csis
-} // namespace bluetooth
diff --git a/bta/dm/bta_dm_act.cc b/bta/dm/bta_dm_act.cc
deleted file mode 100644
index 42fcdc7..0000000
--- a/bta/dm/bta_dm_act.cc
+++ /dev/null
@@ -1,4069 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2014 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains the action functions for device manager state
- * machine.
- *
- ******************************************************************************/
-
-#define LOG_TAG "bt_bta_dm"
-
-#include <cstdint>
-
-#include "bta/dm/bta_dm_int.h"
-#include "bta/gatt/bta_gattc_int.h"
-#include "bta/include/bta_dm_ci.h"
-#include "btif/include/btif_dm.h"
-#include "btif/include/btif_storage.h"
-#include "btif/include/stack_manager.h"
-#include "device/include/controller.h"
-#include "device/include/interop.h"
-#include "main/shim/acl_api.h"
-#include "main/shim/btm_api.h"
-#include "main/shim/dumpsys.h"
-#include "main/shim/shim.h"
-#include "osi/include/allocator.h"
-#include "osi/include/compat.h"
-#include "osi/include/fixed_queue.h"
-#include "osi/include/log.h"
-#include "osi/include/osi.h"
-#include "stack/btm/btm_sec.h"
-#include "stack/btm/neighbor_inquiry.h"
-#include "stack/gatt/connection_manager.h"
-#include "stack/include/acl_api.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/bt_octets.h"
-#include "stack/include/bt_types.h"
-#include "stack/include/btm_client_interface.h"
-#include "stack/include/btu.h" // do_in_main_thread
-#include "types/bluetooth/uuid.h"
-#include "types/raw_address.h"
-
-#include <base/logging.h>
-
-#if (GAP_INCLUDED == TRUE)
-#include "gap_api.h"
-#endif
-
-using bluetooth::Uuid;
-
-void BTIF_dm_disable();
-void BTIF_dm_enable();
-void btm_ble_adv_init(void);
-
-static void bta_dm_inq_results_cb(tBTM_INQ_RESULTS* p_inq, const uint8_t* p_eir,
- uint16_t eir_len);
-static void bta_dm_inq_cmpl_cb(void* p_result);
-static void bta_dm_service_search_remname_cback(const RawAddress& bd_addr,
- DEV_CLASS dc, BD_NAME bd_name);
-static void bta_dm_remname_cback(void* p);
-static void bta_dm_find_services(const RawAddress& bd_addr);
-static void bta_dm_discover_next_device(void);
-static void bta_dm_sdp_callback(tSDP_STATUS sdp_status);
-static uint8_t bta_dm_pin_cback(const RawAddress& bd_addr, DEV_CLASS dev_class,
- const BD_NAME bd_name, bool min_16_digit);
-static uint8_t bta_dm_new_link_key_cback(const RawAddress& bd_addr,
- DEV_CLASS dev_class, BD_NAME bd_name,
- const LinkKey& key, uint8_t key_type);
-static void bta_dm_authentication_complete_cback(const RawAddress& bd_addr,
- DEV_CLASS dev_class,
- BD_NAME bd_name,
- tHCI_REASON result);
-static void bta_dm_local_name_cback(void* p_name);
-static void bta_dm_check_av();
-
-void BTA_dm_update_policy(tBTA_SYS_CONN_STATUS status, uint8_t id,
- uint8_t app_id, const RawAddress& peer_addr);
-
-/* Extended Inquiry Response */
-static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, tBTM_SP_EVT_DATA* p_data);
-
-static void bta_dm_set_eir(char* local_name);
-
-static void bta_dm_search_timer_cback(void* data);
-static void bta_dm_disable_conn_down_timer_cback(void* data);
-void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id, uint8_t app_id,
- const RawAddress& peer_addr);
-static void bta_dm_adjust_roles(bool delay_role_switch);
-static char* bta_dm_get_remname(void);
-static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result);
-
-static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr,
- tBT_TRANSPORT transport);
-static void bta_dm_discover_device(const RawAddress& remote_bd_addr);
-
-static void bta_dm_disable_search_and_disc(void);
-
-static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, const RawAddress& bda,
- tBTM_LE_EVT_DATA* p_data);
-static void bta_dm_ble_id_key_cback(uint8_t key_type,
- tBTM_BLE_LOCAL_KEYS* p_key);
-static void bta_dm_gattc_register(void);
-static void btm_dm_start_gatt_discovery(const RawAddress& bd_addr);
-static void bta_dm_cancel_gatt_discovery(const RawAddress& bd_addr);
-static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data);
-extern tBTM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void);
-#if (BLE_VND_INCLUDED == TRUE)
-static void bta_dm_ctrl_features_rd_cmpl_cback(tHCI_STATUS result);
-#endif
-
-#ifndef BTA_DM_BLE_ADV_CHNL_MAP
-#define BTA_DM_BLE_ADV_CHNL_MAP \
- (BTM_BLE_ADV_CHNL_37 | BTM_BLE_ADV_CHNL_38 | BTM_BLE_ADV_CHNL_39)
-#endif
-
-/* Disable timer interval (in milliseconds) */
-#ifndef BTA_DM_DISABLE_TIMER_MS
-#define BTA_DM_DISABLE_TIMER_MS (2000)
-#endif
-
-/* Disable timer retrial interval (in milliseconds) */
-#ifndef BTA_DM_DISABLE_TIMER_RETRIAL_MS
-#define BTA_DM_DISABLE_TIMER_RETRIAL_MS 1500
-#endif
-
-/* Disable connection down timer (in milliseconds) */
-#ifndef BTA_DM_DISABLE_CONN_DOWN_TIMER_MS
-#define BTA_DM_DISABLE_CONN_DOWN_TIMER_MS 1000
-#endif
-
-/* Switch delay timer (in milliseconds) */
-#ifndef BTA_DM_SWITCH_DELAY_TIMER_MS
-#define BTA_DM_SWITCH_DELAY_TIMER_MS 500
-#endif
-
-namespace {
-
-// Time to wait after receiving shutdown request to delay the actual shutdown
-// process. This time may be zero which invokes immediate shutdown.
-#ifndef BTA_DISABLE_DELAY
-constexpr uint64_t kDisableDelayTimerInMs = 0;
-#else
-constexpr uint64_t kDisableDelayTimerInMs =
- static_cast<uint64_t>(BTA_DISABLE_DELAY);
-#endif
-
-struct WaitForAllAclConnectionsToDrain {
- uint64_t time_to_wait_in_ms;
- unsigned long TimeToWaitInMs() const {
- return static_cast<unsigned long>(time_to_wait_in_ms);
- }
- void* AlarmCallbackData() const {
- return const_cast<void*>(static_cast<const void*>(this));
- }
-
- static const WaitForAllAclConnectionsToDrain* FromAlarmCallbackData(
- void* data);
- static bool IsFirstPass(const WaitForAllAclConnectionsToDrain*);
-} first_pass =
- {
- .time_to_wait_in_ms = static_cast<uint64_t>(BTA_DM_DISABLE_TIMER_MS),
-},
- second_pass = {
- .time_to_wait_in_ms =
- static_cast<uint64_t>(BTA_DM_DISABLE_TIMER_RETRIAL_MS),
-};
-
-bool WaitForAllAclConnectionsToDrain::IsFirstPass(
- const WaitForAllAclConnectionsToDrain* pass) {
- return pass == &first_pass;
-}
-
-const WaitForAllAclConnectionsToDrain*
-WaitForAllAclConnectionsToDrain::FromAlarmCallbackData(void* data) {
- return const_cast<const WaitForAllAclConnectionsToDrain*>(
- static_cast<WaitForAllAclConnectionsToDrain*>(data));
-}
-
-} // namespace
-
-static void bta_dm_reset_sec_dev_pending(const RawAddress& remote_bd_addr);
-static void bta_dm_remove_sec_dev_entry(const RawAddress& remote_bd_addr);
-static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS* p_inq,
- const uint8_t* p_eir, uint16_t eir_len);
-static void bta_dm_observe_cmpl_cb(void* p_result);
-static void bta_dm_delay_role_switch_cback(void* data);
-static void bta_dm_wait_for_acl_to_drain_cback(void* data);
-
-const uint16_t bta_service_id_to_uuid_lkup_tbl[BTA_MAX_SERVICE_ID] = {
- UUID_SERVCLASS_PNP_INFORMATION, /* Reserved */
- UUID_SERVCLASS_SERIAL_PORT, /* BTA_SPP_SERVICE_ID */
- UUID_SERVCLASS_DIALUP_NETWORKING, /* BTA_DUN_SERVICE_ID */
- UUID_SERVCLASS_AUDIO_SOURCE, /* BTA_A2DP_SOURCE_SERVICE_ID */
- UUID_SERVCLASS_LAN_ACCESS_USING_PPP, /* BTA_LAP_SERVICE_ID */
- UUID_SERVCLASS_HEADSET, /* BTA_HSP_HS_SERVICE_ID */
- UUID_SERVCLASS_HF_HANDSFREE, /* BTA_HFP_HS_SERVICE_ID */
- UUID_SERVCLASS_OBEX_OBJECT_PUSH, /* BTA_OPP_SERVICE_ID */
- UUID_SERVCLASS_OBEX_FILE_TRANSFER, /* BTA_FTP_SERVICE_ID */
- UUID_SERVCLASS_CORDLESS_TELEPHONY, /* BTA_CTP_SERVICE_ID */
- UUID_SERVCLASS_INTERCOM, /* BTA_ICP_SERVICE_ID */
- UUID_SERVCLASS_IRMC_SYNC, /* BTA_SYNC_SERVICE_ID */
- UUID_SERVCLASS_DIRECT_PRINTING, /* BTA_BPP_SERVICE_ID */
- UUID_SERVCLASS_IMAGING_RESPONDER, /* BTA_BIP_SERVICE_ID */
- UUID_SERVCLASS_PANU, /* BTA_PANU_SERVICE_ID */
- UUID_SERVCLASS_NAP, /* BTA_NAP_SERVICE_ID */
- UUID_SERVCLASS_GN, /* BTA_GN_SERVICE_ID */
- UUID_SERVCLASS_SAP, /* BTA_SAP_SERVICE_ID */
- UUID_SERVCLASS_AUDIO_SINK, /* BTA_A2DP_SERVICE_ID */
- UUID_SERVCLASS_AV_REMOTE_CONTROL, /* BTA_AVRCP_SERVICE_ID */
- UUID_SERVCLASS_HUMAN_INTERFACE, /* BTA_HID_SERVICE_ID */
- UUID_SERVCLASS_VIDEO_SINK, /* BTA_VDP_SERVICE_ID */
- UUID_SERVCLASS_PBAP_PSE, /* BTA_PBAP_SERVICE_ID */
- UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, /* BTA_HSP_SERVICE_ID */
- UUID_SERVCLASS_AG_HANDSFREE, /* BTA_HFP_SERVICE_ID */
- UUID_SERVCLASS_MESSAGE_ACCESS, /* BTA_MAP_SERVICE_ID */
- UUID_SERVCLASS_MESSAGE_NOTIFICATION, /* BTA_MN_SERVICE_ID */
- UUID_SERVCLASS_HDP_PROFILE, /* BTA_HDP_SERVICE_ID */
- UUID_SERVCLASS_PBAP_PCE, /* BTA_PCE_SERVICE_ID */
- UUID_PROTOCOL_ATT /* BTA_GATT_SERVICE_ID */
-};
-
-/* bta security callback */
-const tBTM_APPL_INFO bta_security = {
- .p_pin_callback = &bta_dm_pin_cback,
- .p_link_key_callback = &bta_dm_new_link_key_cback,
- .p_auth_complete_callback = &bta_dm_authentication_complete_cback,
- .p_bond_cancel_cmpl_callback = &bta_dm_bond_cancel_complete_cback,
- .p_sp_callback = &bta_dm_sp_cback,
- .p_le_callback = &bta_dm_ble_smp_cback,
- .p_le_key_callback = &bta_dm_ble_id_key_cback};
-
-#define MAX_DISC_RAW_DATA_BUF (4096)
-uint8_t g_disc_raw_data_buf[MAX_DISC_RAW_DATA_BUF];
-
-extern DEV_CLASS local_device_default_class;
-
-// Stores the local Input/Output Capabilities of the Bluetooth device.
-static uint8_t btm_local_io_caps;
-
-/** Initialises the BT device manager */
-void bta_dm_enable(tBTA_DM_SEC_CBACK* p_sec_cback) {
- /* make sure security callback is saved - if no callback, do not erase the
- previous one,
- it could be an error recovery mechanism */
- if (p_sec_cback != NULL) bta_dm_cb.p_sec_cback = p_sec_cback;
- /* notify BTA DM is now active */
- bta_dm_cb.is_bta_dm_active = true;
-
- btm_local_io_caps = btif_storage_get_local_io_caps();
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_init_cb
- *
- * Description Initializes the bta_dm_cb control block
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_init_cb(void) {
- bta_dm_cb = {};
- bta_dm_cb.disable_timer = alarm_new("bta_dm.disable_timer");
- bta_dm_cb.switch_delay_timer = alarm_new("bta_dm.switch_delay_timer");
- for (size_t i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
- for (size_t j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
- bta_dm_cb.pm_timer[i].timer[j] = alarm_new("bta_dm.pm_timer");
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_deinit_cb
- *
- * Description De-initializes the bta_dm_cb control block
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_deinit_cb(void) {
- /*
- * TODO: Should alarm_free() the bta_dm_cb timers during graceful
- * shutdown.
- */
- alarm_free(bta_dm_cb.disable_timer);
- alarm_free(bta_dm_cb.switch_delay_timer);
- for (size_t i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
- for (size_t j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
- alarm_free(bta_dm_cb.pm_timer[i].timer[j]);
- }
- }
- bta_dm_cb = {};
-}
-
-void BTA_dm_on_hw_off() {
- BTIF_dm_disable();
-
- /* reinitialize the control block */
- bta_dm_deinit_cb();
-
- /* hw is ready, go on with BTA DM initialization */
- alarm_free(bta_dm_search_cb.search_timer);
- alarm_free(bta_dm_search_cb.gatt_close_timer);
- osi_free(bta_dm_search_cb.p_pending_search);
- fixed_queue_free(bta_dm_search_cb.pending_discovery_queue, osi_free);
- memset(&bta_dm_search_cb, 0, sizeof(bta_dm_search_cb));
-
- /* notify BTA DM is now unactive */
- bta_dm_cb.is_bta_dm_active = false;
-}
-
-void BTA_dm_on_hw_on() {
- DEV_CLASS dev_class;
- tBTA_DM_SEC_CBACK* temp_cback;
- uint8_t key_mask = 0;
- tBTA_BLE_LOCAL_ID_KEYS id_key;
-
- /* save security callback */
- temp_cback = bta_dm_cb.p_sec_cback;
- /* make sure the control block is properly initialized */
- bta_dm_init_cb();
- /* and retrieve the callback */
- bta_dm_cb.p_sec_cback = temp_cback;
- bta_dm_cb.is_bta_dm_active = true;
-
- /* hw is ready, go on with BTA DM initialization */
- alarm_free(bta_dm_search_cb.search_timer);
- alarm_free(bta_dm_search_cb.gatt_close_timer);
- osi_free(bta_dm_search_cb.p_pending_search);
- fixed_queue_free(bta_dm_search_cb.pending_discovery_queue, osi_free);
- memset(&bta_dm_search_cb, 0, sizeof(bta_dm_search_cb));
- /*
- * TODO: Should alarm_free() the bta_dm_search_cb timers during
- * graceful shutdown.
- */
- bta_dm_search_cb.search_timer = alarm_new("bta_dm_search.search_timer");
- bta_dm_search_cb.gatt_close_timer =
- alarm_new("bta_dm_search.gatt_close_timer");
- bta_dm_search_cb.pending_discovery_queue = fixed_queue_new(SIZE_MAX);
-
- memset(&bta_dm_conn_srvcs, 0, sizeof(bta_dm_conn_srvcs));
- memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB));
-
- memcpy(dev_class, p_bta_dm_cfg->dev_class, sizeof(dev_class));
- if (bluetooth::shim::is_gd_security_enabled()) {
- bluetooth::shim::BTM_SetDeviceClass(dev_class);
- } else {
- BTM_SetDeviceClass(dev_class);
- }
-
- /* load BLE local information: ID keys, ER if available */
- Octet16 er;
- btif_dm_get_ble_local_keys(&key_mask, &er, &id_key);
-
- if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ER) {
- get_btm_client_interface().ble.BTM_BleLoadLocalKeys(
- BTA_BLE_LOCAL_KEY_TYPE_ER, (tBTM_BLE_LOCAL_KEYS*)&er);
- }
- if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ID) {
- get_btm_client_interface().ble.BTM_BleLoadLocalKeys(
- BTA_BLE_LOCAL_KEY_TYPE_ID, (tBTM_BLE_LOCAL_KEYS*)&id_key);
- }
- bta_dm_search_cb.conn_id = GATT_INVALID_CONN_ID;
-
- if (bluetooth::shim::is_gd_security_enabled()) {
- bluetooth::shim::BTM_SecRegister(&bta_security);
- } else {
- get_btm_client_interface().security.BTM_SecRegister(&bta_security);
- }
-
- BTM_WritePageTimeout(p_bta_dm_cfg->page_timeout);
-
-#if (BLE_VND_INCLUDED == TRUE)
- BTM_BleReadControllerFeatures(bta_dm_ctrl_features_rd_cmpl_cback);
-#else
- /* If VSC multi adv commands are available, advertising will be initialized
- * when capabilities are read. If they are not available, initialize
- * advertising here */
- btm_ble_adv_init();
- /* Set controller features even if vendor support is not included */
- if (bta_dm_cb.p_sec_cback)
- bta_dm_cb.p_sec_cback(BTA_DM_LE_FEATURES_READ, NULL);
-#endif
-
- /* Earlier, we used to invoke BTM_ReadLocalAddr which was just copying the
- bd_addr
- from the control block and invoking the callback which was sending the
- DM_ENABLE_EVT.
- But then we have a few HCI commands being invoked above which were still
- in progress
- when the ENABLE_EVT was sent. So modified this to fetch the local name
- which forces
- the DM_ENABLE_EVT to be sent only after all the init steps are complete
- */
- get_btm_client_interface().local.BTM_ReadLocalDeviceNameFromController(
- bta_dm_local_name_cback);
-
- bta_sys_rm_register(bta_dm_rm_cback);
-
- /* initialize bluetooth low power manager */
- bta_dm_init_pm();
-
- bta_dm_gattc_register();
-}
-
-/** Disables the BT device manager */
-void bta_dm_disable() {
- /* Set l2cap idle timeout to 0 (so BTE immediately disconnects ACL link after
- * last channel is closed) */
- L2CA_SetIdleTimeoutByBdAddr(RawAddress::kAny, 0, BT_TRANSPORT_BR_EDR);
- L2CA_SetIdleTimeoutByBdAddr(RawAddress::kAny, 0, BT_TRANSPORT_LE);
-
- /* disable all active subsystems */
- bta_sys_disable();
-
- BTM_SetDiscoverability(BTM_NON_DISCOVERABLE);
- BTM_SetConnectability(BTM_NON_CONNECTABLE);
-
- bta_dm_disable_pm();
- bta_dm_disable_search_and_disc();
- bta_dm_cb.disabling = true;
-
- connection_manager::reset(false);
-
- if (BTM_GetNumAclLinks() == 0) {
- // We can shut down faster if there are no ACL links
- switch (kDisableDelayTimerInMs) {
- case 0:
- LOG_DEBUG("Immediately disabling device manager");
- bta_dm_disable_conn_down_timer_cback(nullptr);
- break;
- default:
- LOG_DEBUG("Set timer to delay disable initiation:%lu ms",
- static_cast<unsigned long>(kDisableDelayTimerInMs));
- alarm_set_on_mloop(bta_dm_cb.disable_timer, kDisableDelayTimerInMs,
- bta_dm_disable_conn_down_timer_cback, nullptr);
- }
- } else {
- LOG_DEBUG("Set timer to wait for all ACL connections to close:%lu ms",
- first_pass.TimeToWaitInMs());
- alarm_set_on_mloop(bta_dm_cb.disable_timer, first_pass.time_to_wait_in_ms,
- bta_dm_wait_for_acl_to_drain_cback,
- first_pass.AlarmCallbackData());
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_wait_for_all_acl_to_drain
- *
- * Description Called if the disable timer expires
- * Used to close ACL connections which are still active
- *
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static bool force_disconnect_all_acl_connections() {
- const bool is_force_disconnect_needed = (bta_dm_cb.device_list.count > 0);
-
- for (auto i = 0; i < bta_dm_cb.device_list.count; i++) {
- btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
- bta_dm_cb.device_list.peer_device[i].transport);
- }
- return is_force_disconnect_needed;
-}
-
-static void bta_dm_wait_for_acl_to_drain_cback(void* data) {
- ASSERT(data != nullptr);
- const WaitForAllAclConnectionsToDrain* pass =
- WaitForAllAclConnectionsToDrain::FromAlarmCallbackData(data);
-
- if (BTM_GetNumAclLinks() &&
- WaitForAllAclConnectionsToDrain::IsFirstPass(pass)) {
- /* DISABLE_EVT still need to be sent out to avoid java layer disable timeout
- */
- if (force_disconnect_all_acl_connections()) {
- LOG_DEBUG(
- "Set timer for second pass to wait for all ACL connections to "
- "close:%lu ms ",
- second_pass.TimeToWaitInMs());
- alarm_set_on_mloop(
- bta_dm_cb.disable_timer, second_pass.time_to_wait_in_ms,
- bta_dm_wait_for_acl_to_drain_cback, second_pass.AlarmCallbackData());
- }
- } else {
- // No ACL links were up or is second pass at ACL closure
- if (bluetooth::shim::is_gd_acl_enabled()) {
- LOG_INFO("Ensuring all ACL connections have been properly flushed");
- bluetooth::shim::ACL_Shutdown();
- }
-
- bta_dm_cb.disabling = false;
-
- bta_sys_remove_uuid(UUID_SERVCLASS_PNP_INFORMATION);
- BTIF_dm_disable();
- }
-}
-
-/** Sets local device name */
-void bta_dm_set_dev_name(const std::vector<uint8_t>& name) {
- BTM_SetLocalDeviceName((const char*)name.data());
- bta_dm_set_eir((char*)name.data());
-}
-
-/** Sets discoverability, connectability and pairability */
-bool BTA_DmSetVisibility(bt_scan_mode_t mode) {
- tBTA_DM_DISC disc_mode_param;
- tBTA_DM_CONN conn_mode_param;
-
- switch (mode) {
- case BT_SCAN_MODE_NONE:
- disc_mode_param = BTA_DM_NON_DISC;
- conn_mode_param = BTA_DM_NON_CONN;
- break;
-
- case BT_SCAN_MODE_CONNECTABLE:
- disc_mode_param = BTA_DM_NON_DISC;
- conn_mode_param = BTA_DM_CONN;
- break;
-
- case BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE:
- disc_mode_param = BTA_DM_GENERAL_DISC;
- conn_mode_param = BTA_DM_CONN;
- break;
-
- default:
- return false;
- }
-
- BTM_SetDiscoverability(disc_mode_param);
- BTM_SetConnectability(conn_mode_param);
- return true;
-}
-
-static void bta_dm_process_remove_device_no_callback(
- const RawAddress& bd_addr) {
- /* need to remove all pending background connection before unpair */
- BTA_GATTC_CancelOpen(0, bd_addr, false);
-
- if (bluetooth::shim::is_gd_security_enabled()) {
- bluetooth::shim::BTM_SecDeleteDevice(bd_addr);
- } else {
- BTM_SecDeleteDevice(bd_addr);
- }
-
- /* remove all cached GATT information */
- BTA_GATTC_Refresh(bd_addr);
-}
-
-void bta_dm_process_remove_device(const RawAddress& bd_addr) {
- bta_dm_process_remove_device_no_callback(bd_addr);
-
- if (bta_dm_cb.p_sec_cback) {
- tBTA_DM_SEC sec_event;
- sec_event.link_down.bd_addr = bd_addr;
- bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &sec_event);
- }
-}
-
-/** Removes device, disconnects ACL link if required */
-void bta_dm_remove_device(const RawAddress& bd_addr) {
- /* If ACL exists for the device in the remove_bond message*/
- bool is_bd_addr_connected =
- BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE) ||
- BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR);
-
- tBT_TRANSPORT other_transport = BT_TRANSPORT_AUTO;
- if (is_bd_addr_connected) {
- APPL_TRACE_DEBUG("%s: ACL Up count: %d", __func__,
- bta_dm_cb.device_list.count);
-
- /* Take the link down first, and mark the device for removal when
- * disconnected */
- for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
- auto& peer_device = bta_dm_cb.device_list.peer_device[i];
- if (peer_device.peer_bdaddr == bd_addr) {
- peer_device.conn_state = BTA_DM_UNPAIRING;
-
- /* Make sure device is not in acceptlist before we disconnect */
- GATT_CancelConnect(0, bd_addr, false);
-
- btm_remove_acl(bd_addr, peer_device.transport);
- APPL_TRACE_DEBUG("%s: transport: %d", __func__, peer_device.transport);
-
- /* save the other transport to check if device is connected on
- * other_transport */
- if (peer_device.transport == BT_TRANSPORT_LE)
- other_transport = BT_TRANSPORT_BR_EDR;
- else
- other_transport = BT_TRANSPORT_LE;
-
- break;
- }
- }
- }
-
- RawAddress other_address = bd_addr;
- RawAddress other_address2 = bd_addr;
-
- // If it is DUMO device and device is paired as different address, unpair that
- // device
- bool other_address_connected =
- (other_transport)
- ? BTM_ReadConnectedTransportAddress(&other_address, other_transport)
- : (BTM_ReadConnectedTransportAddress(&other_address,
- BT_TRANSPORT_BR_EDR) ||
- BTM_ReadConnectedTransportAddress(&other_address2,
- BT_TRANSPORT_LE));
- if (other_address == bd_addr) other_address = other_address2;
-
- if (other_address_connected) {
- /* Take the link down first, and mark the device for removal when
- * disconnected */
- for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
- auto& peer_device = bta_dm_cb.device_list.peer_device[i];
- if (peer_device.peer_bdaddr == other_address &&
- peer_device.transport == other_transport) {
- peer_device.conn_state = BTA_DM_UNPAIRING;
-
- /* Make sure device is not in acceptlist before we disconnect */
- GATT_CancelConnect(0, bd_addr, false);
-
- btm_remove_acl(other_address, peer_device.transport);
- break;
- }
- }
- }
-
- /* Delete the device mentioned in the msg */
- if (!is_bd_addr_connected) {
- bta_dm_process_remove_device(bd_addr);
- }
-
- /* Delete the other paired device too */
- if (!other_address_connected && !other_address.IsEmpty()) {
- bta_dm_process_remove_device(other_address);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_add_device
- *
- * Description This function adds a Link Key to an security database entry.
- * It is normally called during host startup to restore all
- * required information stored in the NVRAM.
- ******************************************************************************/
-void bta_dm_add_device(std::unique_ptr<tBTA_DM_API_ADD_DEVICE> msg) {
- uint8_t* p_dc = NULL;
- LinkKey* p_lc = NULL;
-
- /* If not all zeros, the device class has been specified */
- if (msg->dc_known) p_dc = (uint8_t*)msg->dc;
-
- if (msg->link_key_known) p_lc = &msg->link_key;
-
- if (bluetooth::shim::is_gd_security_enabled()) {
- bluetooth::shim::BTM_SecAddDevice(msg->bd_addr, p_dc, msg->bd_name, nullptr,
- p_lc, msg->key_type, msg->pin_length);
- } else {
- auto add_result =
- BTM_SecAddDevice(msg->bd_addr, p_dc, msg->bd_name, nullptr, p_lc,
- msg->key_type, msg->pin_length);
- if (!add_result) {
- LOG(ERROR) << "BTA_DM: Error adding device " << msg->bd_addr;
- }
- }
-}
-
-/** This function forces to close the connection to a remote device and
- * optionaly remove the device from security database if required. */
-void bta_dm_close_acl(const RawAddress& bd_addr, bool remove_dev,
- tBT_TRANSPORT transport) {
- uint8_t index;
-
- APPL_TRACE_DEBUG("bta_dm_close_acl");
-
- if (BTM_IsAclConnectionUp(bd_addr, transport)) {
- for (index = 0; index < bta_dm_cb.device_list.count; index++) {
- if (bta_dm_cb.device_list.peer_device[index].peer_bdaddr == bd_addr)
- break;
- }
- if (index != bta_dm_cb.device_list.count) {
- if (remove_dev)
- bta_dm_cb.device_list.peer_device[index].remove_dev_pending = true;
- } else {
- APPL_TRACE_ERROR("unknown device, remove ACL failed");
- }
-
- /* Make sure device is not in acceptlist before we disconnect */
- GATT_CancelConnect(0, bd_addr, false);
-
- /* Disconnect the ACL link */
- btm_remove_acl(bd_addr, transport);
- }
- /* if to remove the device from security database ? do it now */
- else if (remove_dev) {
- bta_dm_process_remove_device_no_callback(bd_addr);
- }
- /* otherwise, no action needed */
-}
-
-/** Bonds with peer device */
-void bta_dm_bond(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type,
- tBT_TRANSPORT transport, tBT_DEVICE_TYPE device_type) {
- LOG_DEBUG("Bonding with peer device:%s type:%s transport:%s type:%s",
- PRIVATE_ADDRESS(bd_addr), AddressTypeText(addr_type).c_str(),
- bt_transport_text(transport).c_str(),
- DeviceTypeText(device_type).c_str());
-
- tBTA_DM_SEC sec_event;
- char* p_name;
-
- tBTM_STATUS status =
- (bluetooth::shim::is_gd_security_enabled())
- ? bluetooth::shim::BTM_SecBond(bd_addr, addr_type, transport,
- device_type)
- : BTM_SecBond(bd_addr, addr_type, transport, device_type, 0, NULL);
-
- if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED)) {
- memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
- sec_event.auth_cmpl.bd_addr = bd_addr;
- p_name = (bluetooth::shim::is_gd_security_enabled())
- ? bluetooth::shim::BTM_SecReadDevName(bd_addr)
- : BTM_SecReadDevName(bd_addr);
- if (p_name != NULL) {
- memcpy(sec_event.auth_cmpl.bd_name, p_name, BD_NAME_LEN);
- sec_event.auth_cmpl.bd_name[BD_NAME_LEN] = 0;
- }
-
- /* taken care of by memset [above]
- sec_event.auth_cmpl.key_present = false;
- sec_event.auth_cmpl.success = false;
- */
- sec_event.auth_cmpl.fail_reason = HCI_ERR_ILLEGAL_COMMAND;
- if (status == BTM_SUCCESS) {
- sec_event.auth_cmpl.success = true;
- } else {
- /* delete this device entry from Sec Dev DB */
- bta_dm_remove_sec_dev_entry(bd_addr);
- }
- bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
- }
-}
-
-/** Cancels bonding with a peer device */
-void bta_dm_bond_cancel(const RawAddress& bd_addr) {
- tBTM_STATUS status;
- tBTA_DM_SEC sec_event;
-
- APPL_TRACE_EVENT(" bta_dm_bond_cancel ");
-
- status = (bluetooth::shim::is_gd_security_enabled())
- ? bluetooth::shim::BTM_SecBondCancel(bd_addr)
- : BTM_SecBondCancel(bd_addr);
-
- if (bta_dm_cb.p_sec_cback &&
- (status != BTM_CMD_STARTED && status != BTM_SUCCESS)) {
- sec_event.bond_cancel_cmpl.result = BTA_FAILURE;
-
- bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event);
- }
-}
-
-/** Send the pin_reply to a request from BTM */
-void bta_dm_pin_reply(std::unique_ptr<tBTA_DM_API_PIN_REPLY> msg) {
- if (msg->accept) {
- if (bluetooth::shim::is_gd_security_enabled()) {
- bluetooth::shim::BTM_PINCodeReply(msg->bd_addr, BTM_SUCCESS, msg->pin_len,
- msg->p_pin);
- } else {
- BTM_PINCodeReply(msg->bd_addr, BTM_SUCCESS, msg->pin_len, msg->p_pin);
- }
- } else {
- if (bluetooth::shim::is_gd_security_enabled()) {
- bluetooth::shim::BTM_PINCodeReply(msg->bd_addr, BTM_NOT_AUTHORIZED, 0,
- NULL);
- } else {
- BTM_PINCodeReply(msg->bd_addr, BTM_NOT_AUTHORIZED, 0, NULL);
- }
- }
-}
-
-/** Send the user confirm request reply in response to a request from BTM */
-void bta_dm_confirm(const RawAddress& bd_addr, bool accept) {
- if (bluetooth::shim::is_gd_security_enabled()) {
- bluetooth::shim::BTM_ConfirmReqReply(
- accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED, bd_addr);
- } else {
- BTM_ConfirmReqReply(accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED, bd_addr);
- }
-}
-
-/** respond to the OOB data request for the remote device from BTM */
-void bta_dm_ci_rmt_oob_act(std::unique_ptr<tBTA_DM_CI_RMT_OOB> msg) {
- if (bluetooth::shim::is_gd_security_enabled()) {
- bluetooth::shim::BTM_RemoteOobDataReply(
- msg->accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED, msg->bd_addr, msg->c,
- msg->r);
- } else {
- BTM_RemoteOobDataReply(msg->accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED,
- msg->bd_addr, msg->c, msg->r);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_search_start
- *
- * Description Starts an inquiry
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_search_start(tBTA_DM_MSG* p_data) {
- tBTM_INQUIRY_CMPL result = {};
-
- bta_dm_gattc_register();
-
- APPL_TRACE_DEBUG("%s avoid_scatter=%d", __func__,
- p_bta_dm_cfg->avoid_scatter);
-
- BTM_ClearInqDb(nullptr);
- /* save search params */
- bta_dm_search_cb.p_search_cback = p_data->search.p_cback;
- bta_dm_search_cb.services = p_data->search.services;
-
- result.status = BTM_StartInquiry(bta_dm_inq_results_cb, bta_dm_inq_cmpl_cb);
-
- APPL_TRACE_EVENT("%s status=%d", __func__, result.status);
- if (result.status != BTM_CMD_STARTED) {
- LOG(ERROR) << __func__ << ": BTM_StartInquiry returned "
- << std::to_string(result.status);
- result.num_resp = 0;
- bta_dm_inq_cmpl_cb((void*)&result);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_search_cancel
- *
- * Description Cancels an ongoing search for devices
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_search_cancel() {
- if (BTM_IsInquiryActive()) {
- BTM_CancelInquiry();
- bta_dm_search_cancel_notify();
- bta_dm_search_cmpl();
- }
- /* If no Service Search going on then issue cancel remote name in case it is
- active */
- else if (!bta_dm_search_cb.name_discover_done) {
- BTM_CancelRemoteDeviceName();
- bta_dm_search_cmpl();
- } else {
- bta_dm_inq_cmpl(0);
- }
-
- if (bta_dm_search_cb.gatt_disc_active) {
- bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_discover
- *
- * Description Discovers services on a remote device
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_discover(tBTA_DM_MSG* p_data) {
- /* save the search condition */
- bta_dm_search_cb.services = BTA_ALL_SERVICE_MASK;
-
- bta_dm_gattc_register();
-
- bta_dm_search_cb.p_search_cback = p_data->discover.p_cback;
- bta_dm_search_cb.services_to_search = bta_dm_search_cb.services;
- bta_dm_search_cb.service_index = 0;
- bta_dm_search_cb.services_found = 0;
- bta_dm_search_cb.peer_name[0] = 0;
- bta_dm_search_cb.p_btm_inq_info = BTM_InqDbRead(p_data->discover.bd_addr);
- bta_dm_search_cb.transport = p_data->discover.transport;
-
- bta_dm_search_cb.name_discover_done = false;
- bta_dm_discover_device(p_data->discover.bd_addr);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_disable_search_and_disc
- *
- * Description Cancels an ongoing search or discovery for devices in case
- * of a Bluetooth disable
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_disable_search_and_disc(void) {
- if (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) bta_dm_search_cancel();
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_read_remote_device_name
- *
- * Description Initiate to get remote device name
- *
- * Returns true if started to get remote name
- *
- ******************************************************************************/
-static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr,
- tBT_TRANSPORT transport) {
- tBTM_STATUS btm_status;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- bta_dm_search_cb.peer_bdaddr = bd_addr;
- bta_dm_search_cb.peer_name[0] = 0;
-
- btm_status =
- (bluetooth::shim::is_gd_security_enabled())
- ? bluetooth::shim::BTM_ReadRemoteDeviceName(
- bta_dm_search_cb.peer_bdaddr, bta_dm_remname_cback, transport)
- : BTM_ReadRemoteDeviceName(bta_dm_search_cb.peer_bdaddr,
- bta_dm_remname_cback, transport);
-
- if (btm_status == BTM_CMD_STARTED) {
- APPL_TRACE_DEBUG("%s: BTM_ReadRemoteDeviceName is started", __func__);
-
- return (true);
- } else if (btm_status == BTM_BUSY) {
- APPL_TRACE_DEBUG("%s: BTM_ReadRemoteDeviceName is busy", __func__);
-
- /* Remote name discovery is on going now so BTM cannot notify through
- * "bta_dm_remname_cback" */
- /* adding callback to get notified that current reading remore name done */
-
- if (bluetooth::shim::is_gd_security_enabled()) {
- bluetooth::shim::BTM_SecAddRmtNameNotifyCallback(
- &bta_dm_service_search_remname_cback);
- } else {
- BTM_SecAddRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
- }
-
- return (true);
- } else {
- APPL_TRACE_WARNING("%s: BTM_ReadRemoteDeviceName returns 0x%02X", __func__,
- btm_status);
-
- return (false);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_inq_cmpl
- *
- * Description Process the inquiry complete event from BTM
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_inq_cmpl(uint8_t num) {
- if (bta_dm_search_get_state() == BTA_DM_SEARCH_CANCELLING) {
- bta_dm_search_set_state(BTA_DM_SEARCH_IDLE);
- bta_dm_execute_queued_request();
- return;
- }
-
- if (bta_dm_search_get_state() != BTA_DM_SEARCH_ACTIVE) {
- return;
- }
-
- tBTA_DM_SEARCH data;
-
- APPL_TRACE_DEBUG("bta_dm_inq_cmpl");
-
- data.inq_cmpl.num_resps = num;
- bta_dm_search_cb.p_search_cback(BTA_DM_INQ_CMPL_EVT, &data);
-
- bta_dm_search_cb.p_btm_inq_info = BTM_InqDbFirst();
- if (bta_dm_search_cb.p_btm_inq_info != NULL) {
- /* start name and service discovery from the first device on inquiry result
- */
- bta_dm_search_cb.name_discover_done = false;
- bta_dm_search_cb.peer_name[0] = 0;
- bta_dm_discover_device(
- bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
- } else {
- bta_dm_search_cb.services = 0;
- bta_dm_search_cmpl();
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_rmt_name
- *
- * Description Process the remote name result from BTM
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_rmt_name(tBTA_DM_MSG* p_data) {
- APPL_TRACE_DEBUG("bta_dm_rmt_name");
-
- if (p_data->rem_name.result.disc_res.bd_name[0] &&
- bta_dm_search_cb.p_btm_inq_info) {
- bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name = true;
- }
-
- bta_dm_discover_device(bta_dm_search_cb.peer_bdaddr);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_disc_rmt_name
- *
- * Description Process the remote name result from BTM when application
- * wants to find the name for a bdaddr
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_disc_rmt_name(tBTA_DM_MSG* p_data) {
- tBTM_INQ_INFO* p_btm_inq_info;
-
- APPL_TRACE_DEBUG("bta_dm_disc_rmt_name");
-
- p_btm_inq_info = BTM_InqDbRead(p_data->rem_name.result.disc_res.bd_addr);
- if (p_btm_inq_info) {
- if (p_data->rem_name.result.disc_res.bd_name[0]) {
- p_btm_inq_info->appl_knows_rem_name = true;
- }
- }
-
- bta_dm_discover_device(p_data->rem_name.result.disc_res.bd_addr);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_sdp_result
- *
- * Description Process the discovery result from sdp
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_sdp_result(tBTA_DM_MSG* p_data) {
- tSDP_DISC_REC* p_sdp_rec = NULL;
- tBTA_DM_MSG* p_msg;
- bool scn_found = false;
- uint16_t service = 0xFFFF;
- tSDP_PROTOCOL_ELEM pe;
-
- std::vector<Uuid> uuid_list;
-
- if ((p_data->sdp_event.sdp_result == SDP_SUCCESS) ||
- (p_data->sdp_event.sdp_result == SDP_NO_RECS_MATCH) ||
- (p_data->sdp_event.sdp_result == SDP_DB_FULL)) {
- APPL_TRACE_DEBUG("sdp_result::0x%x", p_data->sdp_event.sdp_result);
- do {
- p_sdp_rec = NULL;
- if (bta_dm_search_cb.service_index == (BTA_USER_SERVICE_ID + 1)) {
- if (p_sdp_rec && SDP_FindProtocolListElemInRec(
- p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
- bta_dm_search_cb.peer_scn = (uint8_t)pe.params[0];
- scn_found = true;
- }
- } else {
- service =
- bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index - 1];
- p_sdp_rec =
- SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, service, p_sdp_rec);
- }
- /* finished with BR/EDR services, now we check the result for GATT based
- * service UUID */
- if (bta_dm_search_cb.service_index == BTA_MAX_SERVICE_ID) {
- /* all GATT based services */
-
- std::vector<Uuid> gatt_uuids;
-
- do {
- /* find a service record, report it */
- p_sdp_rec =
- SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, 0, p_sdp_rec);
- if (p_sdp_rec) {
- Uuid service_uuid;
- if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) {
- gatt_uuids.push_back(service_uuid);
- }
- }
- } while (p_sdp_rec);
-
- if (!gatt_uuids.empty()) {
- LOG_INFO("GATT services discovered using SDP");
-
- // send all result back to app
- tBTA_DM_SEARCH result;
- result.disc_ble_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
- strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(),
- BD_NAME_LEN + 1);
-
- result.disc_ble_res.services = &gatt_uuids;
- bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
- }
- } else {
- /* SDP_DB_FULL means some records with the
- required attributes were received */
- if (((p_data->sdp_event.sdp_result == SDP_DB_FULL) &&
- bta_dm_search_cb.services != BTA_ALL_SERVICE_MASK) ||
- (p_sdp_rec != NULL)) {
- if (service != UUID_SERVCLASS_PNP_INFORMATION) {
- bta_dm_search_cb.services_found |=
- (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(
- bta_dm_search_cb.service_index - 1));
- uint16_t tmp_svc =
- bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index -
- 1];
- /* Add to the list of UUIDs */
- uuid_list.push_back(Uuid::From16Bit(tmp_svc));
- }
- }
- }
-
- if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK &&
- bta_dm_search_cb.services_to_search == 0) {
- bta_dm_search_cb.service_index++;
- } else /* regular one service per search or PNP search */
- break;
-
- } while (bta_dm_search_cb.service_index <= BTA_MAX_SERVICE_ID);
-
- APPL_TRACE_DEBUG("%s services_found = %04x", __func__,
- bta_dm_search_cb.services_found);
-
- /* Collect the 128-bit services here and put them into the list */
- if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK) {
- p_sdp_rec = NULL;
- do {
- /* find a service record, report it */
- p_sdp_rec =
- SDP_FindServiceInDb_128bit(bta_dm_search_cb.p_sdp_db, p_sdp_rec);
- if (p_sdp_rec) {
- // SDP_FindServiceUUIDInRec_128bit is used only once, refactor?
- Uuid temp_uuid;
- if (SDP_FindServiceUUIDInRec_128bit(p_sdp_rec, &temp_uuid)) {
- uuid_list.push_back(temp_uuid);
- }
- }
- } while (p_sdp_rec);
- }
- /* if there are more services to search for */
- if (bta_dm_search_cb.services_to_search) {
- /* Free up the p_sdp_db before checking the next one */
- bta_dm_free_sdp_db();
- bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
- } else {
- /* callbacks */
- /* start next bd_addr if necessary */
-
- if (bluetooth::shim::is_gd_security_enabled()) {
- bluetooth::shim::BTM_SecDeleteRmtNameNotifyCallback(
- &bta_dm_service_search_remname_cback);
- } else {
- BTM_SecDeleteRmtNameNotifyCallback(
- &bta_dm_service_search_remname_cback);
- }
-
- p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
- p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
- p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
- p_msg->disc_result.result.disc_res.num_uuids = uuid_list.size();
- p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
- if (uuid_list.size() > 0) {
- // TODO(jpawlowski): make p_uuid_list into vector, and just copy
- // vectors, but first get rid of bta_sys_sendmsg below.
- p_msg->disc_result.result.disc_res.p_uuid_list =
- (Uuid*)osi_malloc(uuid_list.size() * sizeof(Uuid));
- memcpy(p_msg->disc_result.result.disc_res.p_uuid_list, uuid_list.data(),
- uuid_list.size() * sizeof(Uuid));
- }
- // Copy the raw_data to the discovery result structure
- if (bta_dm_search_cb.p_sdp_db != NULL &&
- bta_dm_search_cb.p_sdp_db->raw_used != 0 &&
- bta_dm_search_cb.p_sdp_db->raw_data != NULL) {
- APPL_TRACE_DEBUG("%s raw_data used = 0x%x raw_data_ptr = 0x%x",
- __func__, bta_dm_search_cb.p_sdp_db->raw_used,
- bta_dm_search_cb.p_sdp_db->raw_data);
-
- bta_dm_search_cb.p_sdp_db->raw_data =
- NULL; // no need to free this - it is a global assigned.
- bta_dm_search_cb.p_sdp_db->raw_used = 0;
- bta_dm_search_cb.p_sdp_db->raw_size = 0;
- } else {
- APPL_TRACE_DEBUG("%s raw data size is 0 or raw_data is null!!",
- __func__);
- }
- /* Done with p_sdp_db. Free it */
- bta_dm_free_sdp_db();
- p_msg->disc_result.result.disc_res.services =
- bta_dm_search_cb.services_found;
-
- // Piggy back the SCN over result field
- if (scn_found) {
- p_msg->disc_result.result.disc_res.result =
- static_cast<tBTA_STATUS>((3 + bta_dm_search_cb.peer_scn));
- p_msg->disc_result.result.disc_res.services |= BTA_USER_SERVICE_MASK;
-
- APPL_TRACE_EVENT(" Piggy back the SCN over result field SCN=%d",
- bta_dm_search_cb.peer_scn);
- }
- p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
- strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
- bta_dm_get_remname(), BD_NAME_LEN + 1);
-
- bta_sys_sendmsg(p_msg);
- }
- } else {
- /* conn failed. No need for timer */
- if (p_data->sdp_event.sdp_result == SDP_CONN_FAILED)
- bta_dm_search_cb.wait_disc = false;
-
- /* not able to connect go to next device */
- if (bta_dm_search_cb.p_sdp_db)
- osi_free_and_reset((void**)&bta_dm_search_cb.p_sdp_db);
-
- if (bluetooth::shim::is_gd_security_enabled()) {
- bluetooth::shim::BTM_SecDeleteRmtNameNotifyCallback(
- &bta_dm_service_search_remname_cback);
- } else {
- BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
- }
-
- p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
- p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
- p_msg->disc_result.result.disc_res.result = BTA_FAILURE;
- p_msg->disc_result.result.disc_res.services =
- bta_dm_search_cb.services_found;
- p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
- strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
- bta_dm_get_remname(), BD_NAME_LEN + 1);
-
- bta_sys_sendmsg(p_msg);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_search_cmpl
- *
- * Description Sends event to application
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_search_cmpl() {
- bta_dm_search_set_state(BTA_DM_SEARCH_IDLE);
-
- uint16_t conn_id = bta_dm_search_cb.conn_id;
-
- /* no BLE connection, i.e. Classic service discovery end */
- if (conn_id == GATT_INVALID_CONN_ID) {
- bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr);
- bta_dm_execute_queued_request();
- return;
- }
-
- btgatt_db_element_t* db = NULL;
- int count = 0;
- BTA_GATTC_GetGattDb(conn_id, 0x0000, 0xFFFF, &db, &count);
-
- if (count == 0) {
- LOG_INFO("Empty GATT database - no BLE services discovered");
- bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr);
- bta_dm_execute_queued_request();
- return;
- }
-
- std::vector<Uuid> gatt_services;
-
- for (int i = 0; i < count; i++) {
- // we process service entries only
- if (db[i].type == BTGATT_DB_PRIMARY_SERVICE) {
- gatt_services.push_back(db[i].uuid);
- }
- }
- osi_free(db);
-
- tBTA_DM_SEARCH result;
- result.disc_ble_res.services = &gatt_services;
- result.disc_ble_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
- strlcpy((char*)result.disc_ble_res.bd_name, (char*)bta_dm_search_cb.peer_name,
- BD_NAME_LEN + 1);
-
- LOG_INFO("GATT services discovered using LE Transport");
- // send all result back to app
- bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
-
- bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr);
-
- bta_dm_execute_queued_request();
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_disc_result
- *
- * Description Service discovery result when discovering services on a
- * device
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_disc_result(tBTA_DM_MSG* p_data) {
- APPL_TRACE_EVENT("%s", __func__);
-
- /* if any BR/EDR service discovery has been done, report the event */
- if ((bta_dm_search_cb.services &
- ((BTA_ALL_SERVICE_MASK | BTA_USER_SERVICE_MASK) &
- ~BTA_BLE_SERVICE_MASK)))
- bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT,
- &p_data->disc_result.result);
-
- bta_dm_search_cmpl();
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_search_result
- *
- * Description Service discovery result while searching for devices
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_search_result(tBTA_DM_MSG* p_data) {
- APPL_TRACE_DEBUG("%s searching:0x%04x, result:0x%04x", __func__,
- bta_dm_search_cb.services,
- p_data->disc_result.result.disc_res.services);
-
- /* call back if application wants name discovery or found services that
- * application is searching */
- if ((!bta_dm_search_cb.services) ||
- ((bta_dm_search_cb.services) &&
- (p_data->disc_result.result.disc_res.services))) {
- bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT,
- &p_data->disc_result.result);
- }
-
- /* if searching did not initiate to create link */
- if (!bta_dm_search_cb.wait_disc) {
- /* if service searching is done with EIR, don't search next device */
- if (bta_dm_search_cb.p_btm_inq_info) bta_dm_discover_next_device();
- } else {
- /* wait until link is disconnected or timeout */
- bta_dm_search_cb.sdp_results = true;
- alarm_set_on_mloop(bta_dm_search_cb.search_timer,
- 1000 * (L2CAP_LINK_INACTIVITY_TOUT + 1),
- bta_dm_search_timer_cback, NULL);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_search_timer_cback
- *
- * Description Called when ACL disconnect time is over
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_search_timer_cback(UNUSED_ATTR void* data) {
- APPL_TRACE_EVENT("%s", __func__);
- bta_dm_search_cb.wait_disc = false;
-
- /* proceed with next device */
- bta_dm_discover_next_device();
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_free_sdp_db
- *
- * Description Frees SDP data base
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_free_sdp_db() {
- osi_free_and_reset((void**)&bta_dm_search_cb.p_sdp_db);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_queue_search
- *
- * Description Queues search command
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_queue_search(tBTA_DM_MSG* p_data) {
- osi_free_and_reset((void**)&bta_dm_search_cb.p_pending_search);
- bta_dm_search_cb.p_pending_search =
- (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_API_SEARCH));
- memcpy(bta_dm_search_cb.p_pending_search, p_data, sizeof(tBTA_DM_API_SEARCH));
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_queue_disc
- *
- * Description Queues discovery command
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_queue_disc(tBTA_DM_MSG* p_data) {
- tBTA_DM_MSG* p_pending_discovery =
- (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_API_DISCOVER));
- memcpy(p_pending_discovery, p_data, sizeof(tBTA_DM_API_DISCOVER));
- fixed_queue_enqueue(bta_dm_search_cb.pending_discovery_queue,
- p_pending_discovery);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_execute_queued_request
- *
- * Description Executes queued request if one exists
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_execute_queued_request() {
- if (bta_dm_search_cb.p_pending_search) {
- // Updated queued event to search event to trigger start search
- if (bta_dm_search_cb.p_pending_search->hdr.event ==
- BTA_DM_API_QUEUE_SEARCH_EVT) {
- bta_dm_search_cb.p_pending_search->hdr.event = BTA_DM_API_SEARCH_EVT;
- }
- LOG_INFO("%s Start pending search", __func__);
- bta_sys_sendmsg(bta_dm_search_cb.p_pending_search);
- bta_dm_search_cb.p_pending_search = NULL;
- } else {
- tBTA_DM_MSG* p_pending_discovery = (tBTA_DM_MSG*)fixed_queue_try_dequeue(
- bta_dm_search_cb.pending_discovery_queue);
- if (p_pending_discovery) {
- if (p_pending_discovery->hdr.event == BTA_DM_API_QUEUE_DISCOVER_EVT) {
- p_pending_discovery->hdr.event = BTA_DM_API_DISCOVER_EVT;
- }
- LOG_INFO("%s Start pending discovery", __func__);
- bta_sys_sendmsg(p_pending_discovery);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_is_search_request_queued
- *
- * Description Checks if there is a queued search request
- *
- * Returns bool
- *
- ******************************************************************************/
-bool bta_dm_is_search_request_queued() {
- return bta_dm_search_cb.p_pending_search != NULL;
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_search_clear_queue
- *
- * Description Clears the queue if API search cancel is called
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_search_clear_queue() {
- osi_free_and_reset((void**)&bta_dm_search_cb.p_pending_search);
- fixed_queue_flush(bta_dm_search_cb.pending_discovery_queue, osi_free);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_search_cancel_notify
- *
- * Description Notify application that search has been cancelled
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_search_cancel_notify() {
- if (bta_dm_search_cb.p_search_cback) {
- bta_dm_search_cb.p_search_cback(BTA_DM_SEARCH_CANCEL_CMPL_EVT, NULL);
- }
- if (!bta_dm_search_cb.name_discover_done &&
- (bta_dm_search_cb.state == BTA_DM_SEARCH_ACTIVE ||
- bta_dm_search_cb.state == BTA_DM_SEARCH_CANCELLING)) {
- BTM_CancelRemoteDeviceName();
- }
- if (bta_dm_search_cb.gatt_disc_active) {
- bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_find_services
- *
- * Description Starts discovery on a device
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_find_services(const RawAddress& bd_addr) {
- while (bta_dm_search_cb.service_index < BTA_MAX_SERVICE_ID) {
- Uuid uuid = Uuid::kEmpty;
- if (bta_dm_search_cb.services_to_search &
- (tBTA_SERVICE_MASK)(
- BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index))) {
- bta_dm_search_cb.p_sdp_db =
- (tSDP_DISCOVERY_DB*)osi_malloc(BTA_DM_SDP_DB_SIZE);
- APPL_TRACE_DEBUG("bta_dm_search_cb.services = %04x***********",
- bta_dm_search_cb.services);
- /* try to search all services by search based on L2CAP UUID */
- if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK) {
- LOG_INFO("%s services_to_search=%08x", __func__,
- bta_dm_search_cb.services_to_search);
- if (bta_dm_search_cb.services_to_search & BTA_RES_SERVICE_MASK) {
- uuid = Uuid::From16Bit(bta_service_id_to_uuid_lkup_tbl[0]);
- bta_dm_search_cb.services_to_search &= ~BTA_RES_SERVICE_MASK;
- } else {
- uuid = Uuid::From16Bit(UUID_PROTOCOL_L2CAP);
- bta_dm_search_cb.services_to_search = 0;
- }
- } else {
- /* for LE only profile */
- if (bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID) {
- uuid = Uuid::From16Bit(
- bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index]);
-
- bta_dm_search_cb.services_to_search &= (tBTA_SERVICE_MASK)(~(
- BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)));
- } else {
- /* remove the service from services to be searched */
- bta_dm_search_cb.services_to_search &= (tBTA_SERVICE_MASK)(~(
- BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)));
- uuid = Uuid::From16Bit(
- bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index]);
- }
- }
-
- LOG_INFO("%s search UUID = %s", __func__, uuid.ToString().c_str());
- SDP_InitDiscoveryDb(bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE, 1,
- &uuid, 0, NULL);
-
- memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
- bta_dm_search_cb.p_sdp_db->raw_data = g_disc_raw_data_buf;
-
- bta_dm_search_cb.p_sdp_db->raw_size = MAX_DISC_RAW_DATA_BUF;
-
- if (!SDP_ServiceSearchAttributeRequest(bd_addr, bta_dm_search_cb.p_sdp_db,
- &bta_dm_sdp_callback)) {
- /*
- * If discovery is not successful with this device, then
- * proceed with the next one.
- */
- osi_free_and_reset((void**)&bta_dm_search_cb.p_sdp_db);
- bta_dm_search_cb.service_index = BTA_MAX_SERVICE_ID;
-
- } else {
- bta_dm_search_cb.service_index++;
- return;
- }
- }
-
- bta_dm_search_cb.service_index++;
- }
-
- /* no more services to be discovered */
- if (bta_dm_search_cb.service_index >= BTA_MAX_SERVICE_ID) {
- tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
- /* initialize the data structure */
- memset(&(p_msg->disc_result.result), 0, sizeof(tBTA_DM_DISC_RES));
- p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
- p_msg->disc_result.result.disc_res.services =
- bta_dm_search_cb.services_found;
- p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
- strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
- bta_dm_get_remname(), BD_NAME_LEN + 1);
-
- bta_sys_sendmsg(p_msg);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_discover_next_device
- *
- * Description Starts discovery on the next device in Inquiry data base
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_discover_next_device(void) {
- APPL_TRACE_DEBUG("bta_dm_discover_next_device");
-
- /* searching next device on inquiry result */
- bta_dm_search_cb.p_btm_inq_info =
- BTM_InqDbNext(bta_dm_search_cb.p_btm_inq_info);
- if (bta_dm_search_cb.p_btm_inq_info != NULL) {
- bta_dm_search_cb.name_discover_done = false;
- bta_dm_search_cb.peer_name[0] = 0;
- bta_dm_discover_device(
- bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
- } else {
- tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
-
- /* no devices, search complete */
- bta_dm_search_cb.services = 0;
-
- p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
- bta_sys_sendmsg(p_msg);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_discover_device
- *
- * Description Starts name and service discovery on the device
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_discover_device(const RawAddress& remote_bd_addr) {
- tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
- if (bta_dm_search_cb.transport == BT_TRANSPORT_AUTO) {
- tBT_DEVICE_TYPE dev_type;
- tBLE_ADDR_TYPE addr_type;
-
- BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type);
- if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM)
- transport = BT_TRANSPORT_LE;
- } else {
- transport = bta_dm_search_cb.transport;
- }
-
- VLOG(1) << __func__ << " BDA: " << remote_bd_addr;
-
- bta_dm_search_cb.peer_bdaddr = remote_bd_addr;
-
- APPL_TRACE_DEBUG(
- "%s name_discover_done = %d p_btm_inq_info 0x%x state = %d, transport=%d",
- __func__, bta_dm_search_cb.name_discover_done,
- bta_dm_search_cb.p_btm_inq_info, bta_dm_search_cb.state, transport);
-
- if (bta_dm_search_cb.p_btm_inq_info) {
- APPL_TRACE_DEBUG("%s appl_knows_rem_name %d", __func__,
- bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name);
- }
- if (((bta_dm_search_cb.p_btm_inq_info) &&
- (bta_dm_search_cb.p_btm_inq_info->results.device_type ==
- BT_DEVICE_TYPE_BLE) &&
- (bta_dm_search_cb.state == BTA_DM_SEARCH_ACTIVE)) ||
- (transport == BT_TRANSPORT_LE &&
- interop_match_addr(INTEROP_DISABLE_NAME_REQUEST,
- &bta_dm_search_cb.peer_bdaddr))) {
- /* Do not perform RNR for LE devices at inquiry complete*/
- bta_dm_search_cb.name_discover_done = true;
- }
- /* if name discovery is not done and application needs remote name */
- if ((!bta_dm_search_cb.name_discover_done) &&
- ((bta_dm_search_cb.p_btm_inq_info == NULL) ||
- (bta_dm_search_cb.p_btm_inq_info &&
- (!bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name)))) {
- if (bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr,
- transport)) {
- if (bta_dm_search_cb.state != BTA_DM_DISCOVER_ACTIVE) {
- /* Reset transport state for next discovery */
- bta_dm_search_cb.transport = BT_TRANSPORT_AUTO;
- }
- return;
- }
-
- /* starting name discovery failed */
- bta_dm_search_cb.name_discover_done = true;
- }
-
- /* Reset transport state for next discovery */
- bta_dm_search_cb.transport = BT_TRANSPORT_AUTO;
-
- /* if application wants to discover service */
- if (bta_dm_search_cb.services) {
- /* initialize variables */
- bta_dm_search_cb.service_index = 0;
- bta_dm_search_cb.services_found = 0;
- bta_dm_search_cb.services_to_search = bta_dm_search_cb.services;
-
- /* if seaching with EIR is not completed */
- if (bta_dm_search_cb.services_to_search) {
- /* check whether connection already exists to the device
- if connection exists, we don't have to wait for ACL
- link to go down to start search on next device */
- if (transport == BT_TRANSPORT_BR_EDR) {
- if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr,
- BT_TRANSPORT_BR_EDR))
- bta_dm_search_cb.wait_disc = false;
- else
- bta_dm_search_cb.wait_disc = true;
- }
- if (bta_dm_search_cb.p_btm_inq_info) {
- APPL_TRACE_DEBUG(
- "%s p_btm_inq_info 0x%x results.device_type 0x%x "
- "services_to_search 0x%x",
- __func__, bta_dm_search_cb.p_btm_inq_info,
- bta_dm_search_cb.p_btm_inq_info->results.device_type,
- bta_dm_search_cb.services_to_search);
- }
-
- if (transport == BT_TRANSPORT_LE) {
- if (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK) {
- // set the raw data buffer here
- memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
- /* start GATT for service discovery */
- btm_dm_start_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
- return;
- }
- } else {
- bta_dm_search_cb.sdp_results = false;
- bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
- return;
- }
- }
- }
-
- /* name discovery and service discovery are done for this device */
- tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
- p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
- /* initialize the data structure */
- memset(&(p_msg->disc_result.result), 0, sizeof(tBTA_DM_DISC_RES));
- p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
- p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
- p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
- strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
- (char*)bta_dm_search_cb.peer_name, BD_NAME_LEN + 1);
-
- bta_sys_sendmsg(p_msg);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_sdp_callback
- *
- * Description Callback from sdp with discovery status
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_sdp_callback(tSDP_STATUS sdp_status) {
- tBTA_DM_SDP_RESULT* p_msg =
- (tBTA_DM_SDP_RESULT*)osi_malloc(sizeof(tBTA_DM_SDP_RESULT));
-
- p_msg->hdr.event = BTA_DM_SDP_RESULT_EVT;
- p_msg->sdp_result = static_cast<uint16_t>(sdp_status);
-
- bta_sys_sendmsg(p_msg);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_inq_results_cb
- *
- * Description Inquiry results callback from BTM
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_inq_results_cb(tBTM_INQ_RESULTS* p_inq, const uint8_t* p_eir,
- uint16_t eir_len) {
- tBTA_DM_SEARCH result;
- tBTM_INQ_INFO* p_inq_info;
- uint16_t service_class;
-
- result.inq_res.bd_addr = p_inq->remote_bd_addr;
- memcpy(result.inq_res.dev_class, p_inq->dev_class, DEV_CLASS_LEN);
- BTM_COD_SERVICE_CLASS(service_class, p_inq->dev_class);
- result.inq_res.is_limited =
- (service_class & BTM_COD_SERVICE_LMTD_DISCOVER) ? true : false;
- result.inq_res.rssi = p_inq->rssi;
-
- result.inq_res.ble_addr_type = p_inq->ble_addr_type;
- result.inq_res.inq_result_type = p_inq->inq_result_type;
- result.inq_res.device_type = p_inq->device_type;
- result.inq_res.flag = p_inq->flag;
- result.inq_res.include_rsi = p_inq->include_rsi;
-
- /* application will parse EIR to find out remote device name */
- result.inq_res.p_eir = const_cast<uint8_t*>(p_eir);
- result.inq_res.eir_len = eir_len;
-
- p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr);
- if (p_inq_info != NULL) {
- /* initialize remt_name_not_required to false so that we get the name by
- * default */
- result.inq_res.remt_name_not_required = false;
- }
-
- if (bta_dm_search_cb.p_search_cback)
- bta_dm_search_cb.p_search_cback(BTA_DM_INQ_RES_EVT, &result);
-
- if (p_inq_info) {
- /* application indicates if it knows the remote name, inside the callback
- copy that to the inquiry data base*/
- if (result.inq_res.remt_name_not_required)
- p_inq_info->appl_knows_rem_name = true;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_inq_cmpl_cb
- *
- * Description Inquiry complete callback from BTM
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_inq_cmpl_cb(void* p_result) {
- APPL_TRACE_DEBUG("%s", __func__);
-
- bta_dm_inq_cmpl(((tBTM_INQUIRY_CMPL*)p_result)->num_resp);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_service_search_remname_cback
- *
- * Description Remote name call back from BTM during service discovery
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_service_search_remname_cback(const RawAddress& bd_addr,
- UNUSED_ATTR DEV_CLASS dc,
- BD_NAME bd_name) {
- tBTM_REMOTE_DEV_NAME rem_name;
- tBTM_STATUS btm_status;
-
- APPL_TRACE_DEBUG("%s name=<%s>", __func__, bd_name);
-
- /* if this is what we are looking for */
- if (bta_dm_search_cb.peer_bdaddr == bd_addr) {
- rem_name.length = strlcpy((char*)rem_name.remote_bd_name, (char*)bd_name,
- BD_NAME_LEN + 1);
- if (rem_name.length > BD_NAME_LEN) {
- rem_name.length = BD_NAME_LEN;
- }
- rem_name.status = BTM_SUCCESS;
-
- bta_dm_remname_cback(&rem_name);
- } else {
- /* get name of device */
- btm_status =
- BTM_ReadRemoteDeviceName(bta_dm_search_cb.peer_bdaddr,
- bta_dm_remname_cback, BT_TRANSPORT_BR_EDR);
- if (btm_status == BTM_BUSY) {
- /* wait for next chance(notification of remote name discovery done) */
- APPL_TRACE_DEBUG("%s: BTM_ReadRemoteDeviceName is busy", __func__);
- } else if (btm_status != BTM_CMD_STARTED) {
- /* if failed to start getting remote name then continue */
- APPL_TRACE_WARNING("%s: BTM_ReadRemoteDeviceName returns 0x%02X",
- __func__, btm_status);
-
- rem_name.length = 0;
- rem_name.remote_bd_name[0] = 0;
- rem_name.status = btm_status;
- bta_dm_remname_cback(&rem_name);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_remname_cback
- *
- * Description Remote name complete call back from BTM
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_remname_cback(void* p) {
- tBTM_REMOTE_DEV_NAME* p_remote_name = (tBTM_REMOTE_DEV_NAME*)p;
- APPL_TRACE_DEBUG("bta_dm_remname_cback len = %d name=<%s>",
- p_remote_name->length, p_remote_name->remote_bd_name);
-
- /* remote name discovery is done but it could be failed */
- bta_dm_search_cb.name_discover_done = true;
- strlcpy((char*)bta_dm_search_cb.peer_name,
- (char*)p_remote_name->remote_bd_name, BD_NAME_LEN + 1);
-
- if (bluetooth::shim::is_gd_security_enabled()) {
- bluetooth::shim::BTM_SecDeleteRmtNameNotifyCallback(
- &bta_dm_service_search_remname_cback);
- } else {
- BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
- }
-
- if (bta_dm_search_cb.transport == BT_TRANSPORT_LE) {
- GAP_BleReadPeerPrefConnParams(bta_dm_search_cb.peer_bdaddr);
- }
-
- tBTA_DM_REM_NAME* p_msg =
- (tBTA_DM_REM_NAME*)osi_malloc(sizeof(tBTA_DM_REM_NAME));
- p_msg->result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
- strlcpy((char*)p_msg->result.disc_res.bd_name,
- (char*)p_remote_name->remote_bd_name, BD_NAME_LEN + 1);
- p_msg->hdr.event = BTA_DM_REMT_NAME_EVT;
-
- bta_sys_sendmsg(p_msg);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_pinname_cback
- *
- * Description Callback requesting pin_key
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_pinname_cback(void* p_data) {
- tBTM_REMOTE_DEV_NAME* p_result = (tBTM_REMOTE_DEV_NAME*)p_data;
- tBTA_DM_SEC sec_event;
- uint32_t bytes_to_copy;
- tBTA_DM_SEC_EVT event = bta_dm_cb.pin_evt;
-
- if (BTA_DM_SP_CFM_REQ_EVT == event) {
- /* Retrieved saved device class and bd_addr */
- sec_event.cfm_req.bd_addr = bta_dm_cb.pin_bd_addr;
- BTA_COPY_DEVICE_CLASS(sec_event.cfm_req.dev_class, bta_dm_cb.pin_dev_class);
-
- if (p_result && p_result->status == BTM_SUCCESS) {
- bytes_to_copy =
- (p_result->length < BD_NAME_LEN) ? p_result->length : BD_NAME_LEN;
- memcpy(sec_event.cfm_req.bd_name, p_result->remote_bd_name,
- bytes_to_copy);
- sec_event.pin_req.bd_name[BD_NAME_LEN] = 0;
- } else /* No name found */
- sec_event.cfm_req.bd_name[0] = 0;
-
- sec_event.key_notif.passkey =
- bta_dm_cb.num_val; /* get PIN code numeric number */
-
- /* 1 additional event data fields for this event */
- sec_event.cfm_req.just_works = bta_dm_cb.just_works;
- /* retrieve the loc and rmt caps */
- sec_event.cfm_req.loc_io_caps = bta_dm_cb.loc_io_caps;
- sec_event.cfm_req.rmt_io_caps = bta_dm_cb.rmt_io_caps;
- sec_event.cfm_req.loc_auth_req = bta_dm_cb.loc_auth_req;
- sec_event.cfm_req.rmt_auth_req = bta_dm_cb.rmt_auth_req;
-
- } else {
- /* Retrieved saved device class and bd_addr */
- sec_event.pin_req.bd_addr = bta_dm_cb.pin_bd_addr;
- BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, bta_dm_cb.pin_dev_class);
-
- if (p_result && p_result->status == BTM_SUCCESS) {
- bytes_to_copy = (p_result->length < BD_NAME_LEN) ? p_result->length
- : (BD_NAME_LEN - 1);
- memcpy(sec_event.pin_req.bd_name, p_result->remote_bd_name,
- bytes_to_copy);
- sec_event.pin_req.bd_name[BD_NAME_LEN] = 0;
- } else /* No name found */
- sec_event.pin_req.bd_name[0] = 0;
-
- event = bta_dm_cb.pin_evt;
- sec_event.key_notif.passkey =
- bta_dm_cb.num_val; /* get PIN code numeric number */
- }
-
- if (bta_dm_cb.p_sec_cback) bta_dm_cb.p_sec_cback(event, &sec_event);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_pin_cback
- *
- * Description Callback requesting pin_key
- *
- * Returns void
- *
- ******************************************************************************/
-static uint8_t bta_dm_pin_cback(const RawAddress& bd_addr, DEV_CLASS dev_class,
- const BD_NAME bd_name, bool min_16_digit) {
- if (!bta_dm_cb.p_sec_cback) return BTM_NOT_AUTHORIZED;
-
- /* If the device name is not known, save bdaddr and devclass and initiate a
- * name request */
- if (bd_name[0] == 0) {
- bta_dm_cb.pin_evt = BTA_DM_PIN_REQ_EVT;
- bta_dm_cb.pin_bd_addr = bd_addr;
- BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, dev_class);
- if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback,
- BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
- return BTM_CMD_STARTED;
-
- APPL_TRACE_WARNING(
- " bta_dm_pin_cback() -> Failed to start Remote Name Request ");
- }
-
- tBTA_DM_SEC sec_event = {.pin_req = {
- .bd_addr = bd_addr,
- }};
- BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, dev_class);
- strlcpy((char*)sec_event.pin_req.bd_name, (char*)bd_name, BD_NAME_LEN + 1);
- sec_event.pin_req.min_16_digit = min_16_digit;
-
- bta_dm_cb.p_sec_cback(BTA_DM_PIN_REQ_EVT, &sec_event);
- return BTM_CMD_STARTED;
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_new_link_key_cback
- *
- * Description Callback from BTM to notify new link key
- *
- * Returns void
- *
- ******************************************************************************/
-static uint8_t bta_dm_new_link_key_cback(const RawAddress& bd_addr,
- UNUSED_ATTR DEV_CLASS dev_class,
- BD_NAME bd_name, const LinkKey& key,
- uint8_t key_type) {
- tBTA_DM_SEC sec_event;
- tBTA_DM_AUTH_CMPL* p_auth_cmpl;
- uint8_t event;
-
- memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
-
- event = BTA_DM_AUTH_CMPL_EVT;
- p_auth_cmpl = &sec_event.auth_cmpl;
-
- p_auth_cmpl->bd_addr = bd_addr;
-
- memcpy(p_auth_cmpl->bd_name, bd_name, BD_NAME_LEN);
- p_auth_cmpl->bd_name[BD_NAME_LEN] = 0;
- p_auth_cmpl->key_present = true;
- p_auth_cmpl->key_type = key_type;
- p_auth_cmpl->success = true;
- p_auth_cmpl->key = key;
- sec_event.auth_cmpl.fail_reason = HCI_SUCCESS;
-
- // Report the BR link key based on the BR/EDR address and type
- BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type,
- &sec_event.auth_cmpl.addr_type);
- if (bta_dm_cb.p_sec_cback) bta_dm_cb.p_sec_cback(event, &sec_event);
-
- // Setting remove_dev_pending flag to false, where it will avoid deleting
- // the
- // security device record when the ACL connection link goes down in case of
- // reconnection.
- if (bta_dm_cb.device_list.count)
- bta_dm_reset_sec_dev_pending(p_auth_cmpl->bd_addr);
-
- return BTM_CMD_STARTED;
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_authentication_complete_cback
- *
- * Description Authentication complete callback from BTM
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_authentication_complete_cback(
- const RawAddress& bd_addr, UNUSED_ATTR DEV_CLASS dev_class, BD_NAME bd_name,
- tHCI_REASON reason) {
- if (reason != HCI_SUCCESS) {
- if (bta_dm_cb.p_sec_cback) {
- // Build out the security event data structure
- tBTA_DM_SEC sec_event = {
- .auth_cmpl =
- {
- .bd_addr = bd_addr,
- },
- };
- memcpy(sec_event.auth_cmpl.bd_name, bd_name, BD_NAME_LEN);
- sec_event.auth_cmpl.bd_name[BD_NAME_LEN] = 0;
-
- // Report the BR link key based on the BR/EDR address and type
- BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type,
- &sec_event.auth_cmpl.addr_type);
- sec_event.auth_cmpl.fail_reason = reason;
-
- bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
- }
-
- switch (reason) {
- case HCI_ERR_AUTH_FAILURE:
- case HCI_ERR_KEY_MISSING:
- case HCI_ERR_HOST_REJECT_SECURITY:
- case HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE:
- LOG_WARN(
- "Deleting device record as authentication failed entry:%s "
- "reason:%s",
- PRIVATE_ADDRESS(bd_addr), hci_reason_code_text(reason).c_str());
- break;
-
- default:
- break;
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_sp_cback
- *
- * Description simple pairing callback from BTM
- *
- * Returns void
- *
- ******************************************************************************/
-static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event,
- tBTM_SP_EVT_DATA* p_data) {
- tBTM_STATUS status = BTM_CMD_STARTED;
- tBTA_DM_SEC sec_event;
- tBTA_DM_SEC_EVT pin_evt = BTA_DM_SP_KEY_NOTIF_EVT;
-
- APPL_TRACE_EVENT("bta_dm_sp_cback: %d", event);
- if (!bta_dm_cb.p_sec_cback) return BTM_NOT_AUTHORIZED;
-
- bool sp_rmt_result = false;
- /* TODO_SP */
- switch (event) {
- case BTM_SP_IO_REQ_EVT:
- if (btm_local_io_caps != BTM_IO_CAP_NONE) {
- /* translate auth_req */
- btif_dm_set_oob_for_io_req(&p_data->io_req.oob_data);
- btif_dm_proc_io_req(&p_data->io_req.auth_req, p_data->io_req.is_orig);
- }
- APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req,
- p_data->io_req.oob_data);
- break;
- case BTM_SP_IO_RSP_EVT:
- if (btm_local_io_caps != BTM_IO_CAP_NONE) {
- btif_dm_proc_io_rsp(p_data->io_rsp.bd_addr, p_data->io_rsp.io_cap,
- p_data->io_rsp.oob_data, p_data->io_rsp.auth_req);
- }
- break;
-
- case BTM_SP_CFM_REQ_EVT:
- pin_evt = BTA_DM_SP_CFM_REQ_EVT;
- bta_dm_cb.just_works = sec_event.cfm_req.just_works =
- p_data->cfm_req.just_works;
- sec_event.cfm_req.loc_auth_req = p_data->cfm_req.loc_auth_req;
- sec_event.cfm_req.rmt_auth_req = p_data->cfm_req.rmt_auth_req;
- sec_event.cfm_req.loc_io_caps = p_data->cfm_req.loc_io_caps;
- sec_event.cfm_req.rmt_io_caps = p_data->cfm_req.rmt_io_caps;
-
- [[fallthrough]];
- /* Passkey entry mode, mobile device with output capability is very
- unlikely to receive key request, so skip this event */
- /*case BTM_SP_KEY_REQ_EVT: */
- case BTM_SP_KEY_NOTIF_EVT:
- if (btm_local_io_caps == BTM_IO_CAP_NONE &&
- BTM_SP_KEY_NOTIF_EVT == event) {
- status = BTM_NOT_AUTHORIZED;
- break;
- }
-
- bta_dm_cb.num_val = sec_event.key_notif.passkey =
- p_data->key_notif.passkey;
-
- if (BTM_SP_CFM_REQ_EVT == event) {
- /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
- call remote name request using values from cfm_req */
- if (p_data->cfm_req.bd_name[0] == 0) {
- bta_dm_cb.pin_evt = pin_evt;
- bta_dm_cb.pin_bd_addr = p_data->cfm_req.bd_addr;
- bta_dm_cb.rmt_io_caps = sec_event.cfm_req.rmt_io_caps;
- bta_dm_cb.loc_io_caps = sec_event.cfm_req.loc_io_caps;
- bta_dm_cb.rmt_auth_req = sec_event.cfm_req.rmt_auth_req;
- bta_dm_cb.loc_auth_req = sec_event.cfm_req.loc_auth_req;
-
- BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class,
- p_data->cfm_req.dev_class);
- if ((BTM_ReadRemoteDeviceName(
- p_data->cfm_req.bd_addr, bta_dm_pinname_cback,
- BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
- return BTM_CMD_STARTED;
- APPL_TRACE_WARNING(
- " bta_dm_sp_cback() -> Failed to start Remote Name Request ");
- } else {
- /* Due to the switch case falling through below to
- BTM_SP_KEY_NOTIF_EVT,
- copy these values into key_notif from cfm_req */
- sec_event.key_notif.bd_addr = p_data->cfm_req.bd_addr;
- BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class,
- p_data->cfm_req.dev_class);
- strlcpy((char*)sec_event.key_notif.bd_name,
- (char*)p_data->cfm_req.bd_name, BD_NAME_LEN + 1);
- }
- }
-
- if (BTM_SP_KEY_NOTIF_EVT == event) {
- /* If the device name is not known, save bdaddr and devclass
- and initiate a name request with values from key_notif */
- if (p_data->key_notif.bd_name[0] == 0) {
- bta_dm_cb.pin_evt = pin_evt;
- bta_dm_cb.pin_bd_addr = p_data->key_notif.bd_addr;
- BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class,
- p_data->key_notif.dev_class);
- if ((BTM_ReadRemoteDeviceName(
- p_data->key_notif.bd_addr, bta_dm_pinname_cback,
- BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
- return BTM_CMD_STARTED;
- APPL_TRACE_WARNING(
- " bta_dm_sp_cback() -> Failed to start Remote Name Request ");
- } else {
- sec_event.key_notif.bd_addr = p_data->key_notif.bd_addr;
- BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class,
- p_data->key_notif.dev_class);
- strlcpy((char*)sec_event.key_notif.bd_name,
- (char*)p_data->key_notif.bd_name, BD_NAME_LEN + 1);
- sec_event.key_notif.bd_name[BD_NAME_LEN] = 0;
- }
- }
-
- bta_dm_cb.p_sec_cback(pin_evt, &sec_event);
-
- break;
-
- case BTM_SP_LOC_OOB_EVT:
-#ifdef BTIF_DM_OOB_TEST
- btif_dm_proc_loc_oob(BT_TRANSPORT_BR_EDR,
- (bool)(p_data->loc_oob.status == BTM_SUCCESS),
- p_data->loc_oob.c, p_data->loc_oob.r);
-#endif
- break;
-
- case BTM_SP_RMT_OOB_EVT: {
- Octet16 c;
- Octet16 r;
- sp_rmt_result = false;
-#ifdef BTIF_DM_OOB_TEST
- sp_rmt_result = btif_dm_proc_rmt_oob(p_data->rmt_oob.bd_addr, &c, &r);
-#endif
- BTIF_TRACE_DEBUG("bta_dm_ci_rmt_oob: result=%d", sp_rmt_result);
- bta_dm_ci_rmt_oob(sp_rmt_result, p_data->rmt_oob.bd_addr, c, r);
- break;
- }
-
- default:
- status = BTM_NOT_AUTHORIZED;
- break;
- }
- APPL_TRACE_EVENT("dm status: %d", status);
- return status;
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_local_name_cback
- *
- * Description Callback from btm after local name is read
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_local_name_cback(UNUSED_ATTR void* p_name) {
- BTIF_dm_enable();
-}
-
-static void handle_role_change(const RawAddress& bd_addr, tHCI_ROLE new_role,
- tHCI_STATUS hci_status) {
- tBTA_DM_PEER_DEVICE* p_dev = bta_dm_find_peer_device(bd_addr);
- if (!p_dev) {
- LOG_WARN(
- "Unable to find device for role change peer:%s new_role:%s "
- "hci_status:%s",
- PRIVATE_ADDRESS(bd_addr), RoleText(new_role).c_str(),
- hci_error_code_text(hci_status).c_str());
- return;
- }
-
- LOG_INFO(
- "Role change callback peer:%s info:0x%x new_role:%s dev count:%d "
- "hci_status:%s",
- PRIVATE_ADDRESS(bd_addr), p_dev->Info(), RoleText(new_role).c_str(),
- bta_dm_cb.device_list.count, hci_error_code_text(hci_status).c_str());
-
- if (p_dev->Info() & BTA_DM_DI_AV_ACTIVE) {
- bool need_policy_change = false;
-
- /* there's AV activity on this link */
- if (new_role == HCI_ROLE_PERIPHERAL && bta_dm_cb.device_list.count > 1 &&
- hci_status == HCI_SUCCESS) {
- /* more than one connections and the AV connection is role switched
- * to peripheral
- * switch it back to central and remove the switch policy */
- BTM_SwitchRoleToCentral(bd_addr);
- need_policy_change = true;
- } else if (p_bta_dm_cfg->avoid_scatter && (new_role == HCI_ROLE_CENTRAL)) {
- /* if the link updated to be central include AV activities, remove
- * the switch policy */
- need_policy_change = true;
- }
-
- if (need_policy_change) {
- BTM_block_role_switch_for(p_dev->peer_bdaddr);
- }
- } else {
- /* there's AV no activity on this link and role switch happened
- * check if AV is active
- * if so, make sure the AV link is central */
- bta_dm_check_av();
- }
- bta_sys_notify_role_chg(bd_addr, new_role, hci_status);
-}
-
-void BTA_dm_report_role_change(const RawAddress bd_addr, tHCI_ROLE new_role,
- tHCI_STATUS hci_status) {
- do_in_main_thread(
- FROM_HERE, base::Bind(handle_role_change, bd_addr, new_role, hci_status));
-}
-
-void handle_remote_features_complete(const RawAddress& bd_addr) {
- tBTA_DM_PEER_DEVICE* p_dev = bta_dm_find_peer_device(bd_addr);
- if (!p_dev) {
- LOG_WARN("Unable to find device peer:%s", PRIVATE_ADDRESS(bd_addr));
- return;
- }
-
- if (controller_get_interface()->supports_sniff_subrating() &&
- acl_peer_supports_sniff_subrating(bd_addr)) {
- LOG_DEBUG("Device supports sniff subrating peer:%s",
- PRIVATE_ADDRESS(bd_addr));
- p_dev->info = BTA_DM_DI_USE_SSR;
- } else {
- LOG_DEBUG("Device does NOT support sniff subrating peer:%s",
- PRIVATE_ADDRESS(bd_addr));
- }
-}
-
-void BTA_dm_notify_remote_features_complete(const RawAddress bd_addr) {
- do_in_main_thread(FROM_HERE,
- base::Bind(handle_remote_features_complete, bd_addr));
-}
-
-static tBTA_DM_PEER_DEVICE* allocate_device_for(const RawAddress& bd_addr,
- tBT_TRANSPORT transport) {
- for (uint8_t i = 0; i < bta_dm_cb.device_list.count; i++) {
- auto device = &bta_dm_cb.device_list.peer_device[i];
- if (device->peer_bdaddr == bd_addr && device->transport == transport) {
- return device;
- }
- }
-
- if (bta_dm_cb.device_list.count < BTA_DM_NUM_PEER_DEVICE) {
- auto device =
- &bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count];
- device->peer_bdaddr = bd_addr;
- bta_dm_cb.device_list.count++;
- if (transport == BT_TRANSPORT_LE) {
- bta_dm_cb.device_list.le_count++;
- }
- return device;
- }
- return nullptr;
-}
-
-void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
- auto device = allocate_device_for(bd_addr, transport);
- if (device == nullptr) {
- LOG_WARN("Unable to allocate device resources for new connection");
- return;
- }
- device->conn_state = BTA_DM_CONNECTED;
- device->pref_role = BTA_ANY_ROLE;
- device->info = BTA_DM_DI_NONE;
- device->transport = transport;
-
- if (controller_get_interface()->supports_sniff_subrating() &&
- acl_peer_supports_sniff_subrating(bd_addr)) {
- // NOTE: This callback assumes upon ACL connection that
- // the read remote features has completed and is valid.
- // The only guaranteed contract for valid read remote features
- // data is when the BTA_dm_notify_remote_features_complete()
- // callback has completed. The below assignment is kept for
- // transitional informational purposes only.
- device->info = BTA_DM_DI_USE_SSR;
- }
-
- if (bta_dm_cb.p_sec_cback) {
- tBTA_DM_SEC conn;
- memset(&conn, 0, sizeof(tBTA_DM_SEC));
- conn.link_up.bd_addr = bd_addr;
- conn.link_up.transport_link_type = transport;
-
- bta_dm_cb.p_sec_cback(BTA_DM_LINK_UP_EVT, &conn);
- LOG_DEBUG("Executed security callback for new connection available");
- }
- bta_dm_adjust_roles(true);
-}
-
-void BTA_dm_acl_up(const RawAddress bd_addr, tBT_TRANSPORT transport) {
- do_in_main_thread(FROM_HERE, base::Bind(bta_dm_acl_up, bd_addr, transport));
-}
-
-static void bta_dm_acl_down(const RawAddress& bd_addr,
- tBT_TRANSPORT transport) {
- bool issue_unpair_cb = false;
- bool remove_device = false;
-
- for (uint8_t i = 0; i < bta_dm_cb.device_list.count; i++) {
- auto device = &bta_dm_cb.device_list.peer_device[i];
- if (device->peer_bdaddr != bd_addr || device->transport != transport)
- continue;
-
- if (device->conn_state == BTA_DM_UNPAIRING) {
- issue_unpair_cb =
- (bluetooth::shim::is_gd_security_enabled())
- ? bluetooth::shim::BTM_SecDeleteDevice(device->peer_bdaddr)
- : BTM_SecDeleteDevice(device->peer_bdaddr);
-
- /* remove all cached GATT information */
- BTA_GATTC_Refresh(bd_addr);
-
- APPL_TRACE_DEBUG("%s: Unpairing: issue unpair CB = %d ", __func__,
- issue_unpair_cb);
- }
-
- remove_device = device->remove_dev_pending;
-
- // Iterate to the one before the last when shrinking the list,
- // otherwise we memcpy garbage data into the record.
- // Then clear out the last item in the list since we are shrinking.
- for (; i < bta_dm_cb.device_list.count - 1; i++) {
- memcpy(&bta_dm_cb.device_list.peer_device[i],
- &bta_dm_cb.device_list.peer_device[i + 1],
- sizeof(bta_dm_cb.device_list.peer_device[i]));
- }
- if (bta_dm_cb.device_list.count > 0) {
- int clear_index = bta_dm_cb.device_list.count - 1;
- memset(&bta_dm_cb.device_list.peer_device[clear_index], 0,
- sizeof(bta_dm_cb.device_list.peer_device[clear_index]));
- }
- break;
- }
- if (bta_dm_cb.device_list.count) bta_dm_cb.device_list.count--;
- if ((transport == BT_TRANSPORT_LE) && (bta_dm_cb.device_list.le_count)) {
- bta_dm_cb.device_list.le_count--;
- }
-
- if ((transport == BT_TRANSPORT_BR_EDR) &&
- (bta_dm_search_cb.wait_disc && bta_dm_search_cb.peer_bdaddr == bd_addr)) {
- bta_dm_search_cb.wait_disc = false;
-
- if (bta_dm_search_cb.sdp_results) {
- APPL_TRACE_EVENT(" timer stopped ");
- alarm_cancel(bta_dm_search_cb.search_timer);
- bta_dm_discover_next_device();
- }
- }
-
- if (bta_dm_cb.disabling) {
- if (!BTM_GetNumAclLinks()) {
- /*
- * Start a timer to make sure that the profiles
- * get the disconnect event.
- */
- alarm_set_on_mloop(bta_dm_cb.disable_timer,
- BTA_DM_DISABLE_CONN_DOWN_TIMER_MS,
- bta_dm_disable_conn_down_timer_cback, NULL);
- }
- }
- if (remove_device) {
- bta_dm_process_remove_device_no_callback(bd_addr);
- }
-
- if (bta_dm_cb.p_sec_cback) {
- tBTA_DM_SEC conn;
- memset(&conn, 0, sizeof(tBTA_DM_SEC));
- conn.link_down.bd_addr = bd_addr;
- conn.link_down.transport_link_type = transport;
-
- bta_dm_cb.p_sec_cback(BTA_DM_LINK_DOWN_EVT, &conn);
- if (issue_unpair_cb) bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &conn);
- }
-
- bta_dm_adjust_roles(true);
-}
-
-void BTA_dm_acl_down(const RawAddress bd_addr, tBT_TRANSPORT transport) {
- do_in_main_thread(FROM_HERE, base::Bind(bta_dm_acl_down, bd_addr, transport));
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_check_av
- *
- * Description This function checks if AV is active
- * if yes, make sure the AV link is central
- *
- ******************************************************************************/
-static void bta_dm_check_av() {
- uint8_t i;
- tBTA_DM_PEER_DEVICE* p_dev;
-
- if (bta_dm_cb.cur_av_count) {
- LOG_INFO("av_count:%d", bta_dm_cb.cur_av_count);
- for (i = 0; i < bta_dm_cb.device_list.count; i++) {
- p_dev = &bta_dm_cb.device_list.peer_device[i];
- APPL_TRACE_WARNING("[%d]: state:%d, info:x%x", i, p_dev->conn_state,
- p_dev->Info());
- if ((p_dev->conn_state == BTA_DM_CONNECTED) &&
- (p_dev->Info() & BTA_DM_DI_AV_ACTIVE)) {
- /* make central and take away the role switch policy */
- BTM_SwitchRoleToCentral(p_dev->peer_bdaddr);
- /* else either already central or can not switch for some reasons */
- BTM_block_role_switch_for(p_dev->peer_bdaddr);
- break;
- }
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_disable_conn_down_timer_cback
- *
- * Description Sends disable event to application
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_disable_conn_down_timer_cback(UNUSED_ATTR void* data) {
- /* disable the power managment module */
- bta_dm_disable_pm();
-
- bta_dm_cb.disabling = false;
- LOG_INFO("Stack device manager shutdown completed");
- future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_rm_cback
- *
- * Description Role management callback from sys
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id, uint8_t app_id,
- const RawAddress& peer_addr) {
- uint8_t j;
- tBTA_PREF_ROLES role;
- tBTA_DM_PEER_DEVICE* p_dev;
-
- LOG_DEBUG("BTA Role management callback count:%d status:%s peer:%s",
- bta_dm_cb.cur_av_count, bta_sys_conn_status_text(status).c_str(),
- PRIVATE_ADDRESS(peer_addr));
-
- p_dev = bta_dm_find_peer_device(peer_addr);
- if (status == BTA_SYS_CONN_OPEN) {
- if (p_dev) {
- /* Do not set to connected if we are in the middle of unpairing. When AV
- * stream is
- * started it fakes out a SYS_CONN_OPEN to potentially trigger a role
- * switch command.
- * But this should not be done if we are in the middle of unpairing.
- */
- if (p_dev->conn_state != BTA_DM_UNPAIRING)
- p_dev->conn_state = BTA_DM_CONNECTED;
-
- for (j = 1; j <= p_bta_dm_rm_cfg[0].app_id; j++) {
- if (((p_bta_dm_rm_cfg[j].app_id == app_id) ||
- (p_bta_dm_rm_cfg[j].app_id == BTA_ALL_APP_ID)) &&
- (p_bta_dm_rm_cfg[j].id == id)) {
- ASSERT_LOG(p_bta_dm_rm_cfg[j].cfg <= BTA_PERIPHERAL_ROLE_ONLY,
- "Passing illegal preferred role:0x%02x [0x%02x<=>0x%02x]",
- p_bta_dm_rm_cfg[j].cfg, BTA_ANY_ROLE,
- BTA_PERIPHERAL_ROLE_ONLY);
- role = static_cast<tBTA_PREF_ROLES>(p_bta_dm_rm_cfg[j].cfg);
- if (role > p_dev->pref_role) p_dev->pref_role = role;
- break;
- }
- }
- }
- }
-
- if (BTA_ID_AV == id) {
- if (status == BTA_SYS_CONN_BUSY) {
- if (p_dev) p_dev->info |= BTA_DM_DI_AV_ACTIVE;
- /* AV calls bta_sys_conn_open with the A2DP stream count as app_id */
- if (BTA_ID_AV == id) bta_dm_cb.cur_av_count = bta_dm_get_av_count();
- } else if (status == BTA_SYS_CONN_IDLE) {
- if (p_dev) p_dev->info &= ~BTA_DM_DI_AV_ACTIVE;
-
- /* get cur_av_count from connected services */
- if (BTA_ID_AV == id) bta_dm_cb.cur_av_count = bta_dm_get_av_count();
- }
- }
-
- /* Don't adjust roles for each busy/idle state transition to avoid
- excessive switch requests when individual profile busy/idle status
- changes */
- if ((status != BTA_SYS_CONN_BUSY) && (status != BTA_SYS_CONN_IDLE))
- bta_dm_adjust_roles(false);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_delay_role_switch_cback
- *
- * Description Callback from btm to delay a role switch
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_delay_role_switch_cback(UNUSED_ATTR void* data) {
- APPL_TRACE_EVENT("%s: initiating Delayed RS", __func__);
- bta_dm_adjust_roles(false);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_reset_sec_dev_pending
- *
- * Description Setting the remove device pending status to false from
- * security device DB, when the link key notification
- * event comes.
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_reset_sec_dev_pending(const RawAddress& remote_bd_addr) {
- for (size_t i = 0; i < bta_dm_cb.device_list.count; i++) {
- if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == remote_bd_addr) {
- bta_dm_cb.device_list.peer_device[i].remove_dev_pending = false;
- return;
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_remove_sec_dev_entry
- *
- * Description Removes device entry from Security device DB if ACL
- connection with
- * remtoe device does not exist, else schedule for dev entry
- removal upon
- ACL close
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_remove_sec_dev_entry(const RawAddress& remote_bd_addr) {
- if (BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) ||
- BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR)) {
- APPL_TRACE_DEBUG(
- "%s ACL is not down. Schedule for Dev Removal when ACL closes",
- __func__);
- if (bluetooth::shim::is_gd_security_enabled()) {
- bluetooth::shim::BTM_SecClearSecurityFlags(remote_bd_addr);
- } else {
- BTM_SecClearSecurityFlags(remote_bd_addr);
- }
- for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
- if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == remote_bd_addr) {
- bta_dm_cb.device_list.peer_device[i].remove_dev_pending = TRUE;
- break;
- }
- }
- } else {
- // remote_bd_addr comes from security record, which is removed in
- // BTM_SecDeleteDevice.
- RawAddress addr_copy = remote_bd_addr;
- bta_dm_process_remove_device_no_callback(addr_copy);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_adjust_roles
- *
- * Description Adjust roles
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_adjust_roles(bool delay_role_switch) {
- uint8_t i;
- uint8_t link_count = bta_dm_cb.device_list.count;
- if (link_count) {
- for (i = 0; i < bta_dm_cb.device_list.count; i++) {
- if (bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED &&
- bta_dm_cb.device_list.peer_device[i].transport ==
- BT_TRANSPORT_BR_EDR) {
- if ((bta_dm_cb.device_list.peer_device[i].pref_role ==
- BTA_CENTRAL_ROLE_ONLY) ||
- (link_count > 1)) {
- /* Initiating immediate role switch with certain remote devices
- has caused issues due to role switch colliding with link encryption
- setup and
- causing encryption (and in turn the link) to fail . These device .
- Firmware
- versions are stored in a rejectlist and role switch with these
- devices are
- delayed to avoid the collision with link encryption setup */
-
- if (bta_dm_cb.device_list.peer_device[i].pref_role !=
- BTA_PERIPHERAL_ROLE_ONLY &&
- !delay_role_switch) {
- BTM_SwitchRoleToCentral(
- bta_dm_cb.device_list.peer_device[i].peer_bdaddr);
- } else {
- alarm_set_on_mloop(bta_dm_cb.switch_delay_timer,
- BTA_DM_SWITCH_DELAY_TIMER_MS,
- bta_dm_delay_role_switch_cback, NULL);
- }
- }
- }
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_get_remname
- *
- * Description Returns a pointer to the remote name stored in the DM
- * control block if it exists, or from the BTM memory.
- *
- * Returns char * - Pointer to the remote device name
- ******************************************************************************/
-static char* bta_dm_get_remname(void) {
- char* p_name = (char*)bta_dm_search_cb.peer_name;
- char* p_temp;
-
- /* If the name isn't already stored, try retrieving from BTM */
- if (*p_name == '\0') {
- p_temp =
- (bluetooth::shim::is_gd_security_enabled())
- ? bluetooth::shim::BTM_SecReadDevName(bta_dm_search_cb.peer_bdaddr)
- : BTM_SecReadDevName(bta_dm_search_cb.peer_bdaddr);
- if (p_temp != NULL) p_name = p_temp;
- }
-
- return p_name;
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_bond_cancel_complete_cback
- *
- * Description Authentication complete callback from BTM
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result) {
- tBTA_DM_SEC sec_event;
-
- if (result == BTM_SUCCESS)
- sec_event.bond_cancel_cmpl.result = BTA_SUCCESS;
- else
- sec_event.bond_cancel_cmpl.result = BTA_FAILURE;
-
- if (bta_dm_cb.p_sec_cback) {
- bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event);
- }
-}
-
-/*******************************************************************************
- *
- * Function find_utf8_char_boundary
- *
- * Description This function checks a UTF8 string |utf8str| starting at
- * |offset|, moving backwards and returns the offset of the
- * next valid UTF8 character boundary found.
- *
- * Returns Offset of UTF8 character boundary
- *
- ******************************************************************************/
-static size_t find_utf8_char_boundary(const char* utf8str, size_t offset) {
- CHECK(utf8str);
- CHECK(offset > 0);
-
- while (--offset) {
- uint8_t ch = (uint8_t)utf8str[offset];
- if ((ch & 0x80) == 0x00) // ASCII
- return offset + 1;
- if ((ch & 0xC0) == 0xC0) // Multi-byte sequence start
- return offset;
- }
-
- return 0;
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_set_eir
- *
- * Description This function creates EIR tagged data and writes it to
- * controller.
- *
- * Returns None
- *
- ******************************************************************************/
-static void bta_dm_set_eir(char* local_name) {
- uint8_t* p;
- uint8_t* p_length;
-#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
- uint8_t* p_type;
- uint8_t max_num_uuid;
-#if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
- uint8_t custom_uuid_idx;
-#endif // BTA_EIR_SERVER_NUM_CUSTOM_UUID
-#endif // BTA_EIR_CANNED_UUID_LIST
-#if (BTM_EIR_DEFAULT_FEC_REQUIRED == FALSE)
- uint8_t free_eir_length = HCI_EXT_INQ_RESPONSE_LEN;
-#else // BTM_EIR_DEFAULT_FEC_REQUIRED
- uint8_t free_eir_length = HCI_DM5_PACKET_SIZE;
-#endif // BTM_EIR_DEFAULT_FEC_REQUIRED
- uint8_t num_uuid;
- uint8_t data_type;
- uint8_t local_name_len;
-
- /* wait until complete to disable */
- if (alarm_is_scheduled(bta_dm_cb.disable_timer)) return;
-
-#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
- /* if local name is not provided, get it from controller */
- if (local_name == NULL) {
- if (BTM_ReadLocalDeviceName(&local_name) != BTM_SUCCESS) {
- APPL_TRACE_ERROR("Fail to read local device name for EIR");
- }
- }
-#endif // BTA_EIR_CANNED_UUID_LIST
-
- /* Allocate a buffer to hold HCI command */
- BT_HDR* p_buf = (BT_HDR*)osi_malloc(BTM_CMD_BUF_SIZE);
- ASSERT(p_buf != nullptr);
- p = (uint8_t*)p_buf + BTM_HCI_EIR_OFFSET;
-
- memset(p, 0x00, HCI_EXT_INQ_RESPONSE_LEN);
-
- LOG_INFO("Generating extended inquiry response packet EIR");
-
- if (local_name)
- local_name_len = strlen(local_name);
- else
- local_name_len = 0;
-
- data_type = HCI_EIR_COMPLETE_LOCAL_NAME_TYPE;
- /* if local name is longer than minimum length of shortened name */
- /* check whether it needs to be shortened or not */
- if (local_name_len > p_bta_dm_eir_cfg->bta_dm_eir_min_name_len) {
-/* get number of UUID 16-bit list */
-#if (BTA_EIR_CANNED_UUID_LIST == TRUE)
- num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / Uuid::kNumBytes16;
-#else // BTA_EIR_CANNED_UUID_LIST
- max_num_uuid = (free_eir_length - 2) / Uuid::kNumBytes16;
- data_type = get_btm_client_interface().eir.BTM_GetEirSupportedServices(
- bta_dm_cb.eir_uuid, &p, max_num_uuid, &num_uuid);
- p = (uint8_t*)p_buf + BTM_HCI_EIR_OFFSET; /* reset p */
-#endif // BTA_EIR_CANNED_UUID_LIST
-
- /* if UUID doesn't fit remaing space, shorten local name */
- if (local_name_len > (free_eir_length - 4 - num_uuid * Uuid::kNumBytes16)) {
- local_name_len = find_utf8_char_boundary(
- local_name, p_bta_dm_eir_cfg->bta_dm_eir_min_name_len);
- APPL_TRACE_WARNING("%s local name is shortened (%d)", __func__,
- local_name_len);
- data_type = HCI_EIR_SHORTENED_LOCAL_NAME_TYPE;
- } else {
- data_type = HCI_EIR_COMPLETE_LOCAL_NAME_TYPE;
- }
- }
-
- UINT8_TO_STREAM(p, local_name_len + 1);
- UINT8_TO_STREAM(p, data_type);
-
- if (local_name != NULL) {
- memcpy(p, local_name, local_name_len);
- p += local_name_len;
- }
- free_eir_length -= local_name_len + 2;
-
-#if (BTA_EIR_CANNED_UUID_LIST == TRUE)
- /* if UUID list is provided as static data in configuration */
- if ((p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len > 0) &&
- (p_bta_dm_eir_cfg->bta_dm_eir_uuid16)) {
- if (free_eir_length > Uuid::kNumBytes16 + 2) {
- free_eir_length -= 2;
-
- if (free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len) {
- num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / Uuid::kNumBytes16;
- data_type = HCI_EIR_COMPLETE_16BITS_UUID_TYPE;
- } else /* not enough room for all UUIDs */
- {
- APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
- num_uuid = free_eir_length / Uuid::kNumBytes16;
- data_type = HCI_EIR_MORE_16BITS_UUID_TYPE;
- }
- UINT8_TO_STREAM(p, num_uuid * Uuid::kNumBytes16 + 1);
- UINT8_TO_STREAM(p, data_type);
- memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_uuid16,
- num_uuid * Uuid::kNumBytes16);
- p += num_uuid * Uuid::kNumBytes16;
- free_eir_length -= num_uuid * Uuid::kNumBytes16;
- }
- }
-#else /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
- /* if UUID list is dynamic */
- if (free_eir_length >= 2) {
- p_length = p++;
- p_type = p++;
- num_uuid = 0;
-
- max_num_uuid = (free_eir_length - 2) / Uuid::kNumBytes16;
- data_type = get_btm_client_interface().eir.BTM_GetEirSupportedServices(
- bta_dm_cb.eir_uuid, &p, max_num_uuid, &num_uuid);
-
- if (data_type == HCI_EIR_MORE_16BITS_UUID_TYPE) {
- APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
- }
-#if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
- else {
- for (custom_uuid_idx = 0;
- custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID;
- custom_uuid_idx++) {
- const Uuid& curr = bta_dm_cb.bta_custom_uuid[custom_uuid_idx].custom_uuid;
- if (curr.GetShortestRepresentationSize() == Uuid::kNumBytes16) {
- if (num_uuid < max_num_uuid) {
- UINT16_TO_STREAM(p, curr.As16Bit());
- num_uuid++;
- } else {
- data_type = HCI_EIR_MORE_16BITS_UUID_TYPE;
- APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
- break;
- }
- }
- }
- }
-#endif /* (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
-
- UINT8_TO_STREAM(p_length, num_uuid * Uuid::kNumBytes16 + 1);
- UINT8_TO_STREAM(p_type, data_type);
- free_eir_length -= num_uuid * Uuid::kNumBytes16 + 2;
- }
-#endif /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
-
-#if (BTA_EIR_CANNED_UUID_LIST != TRUE && BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
- /* Adding 32-bit UUID list */
- if (free_eir_length >= 2) {
- p_length = p++;
- p_type = p++;
- num_uuid = 0;
- data_type = HCI_EIR_COMPLETE_32BITS_UUID_TYPE;
-
- max_num_uuid = (free_eir_length - 2) / Uuid::kNumBytes32;
-
- for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID;
- custom_uuid_idx++) {
- const Uuid& curr = bta_dm_cb.bta_custom_uuid[custom_uuid_idx].custom_uuid;
- if (curr.GetShortestRepresentationSize() == Uuid::kNumBytes32) {
- if (num_uuid < max_num_uuid) {
- UINT32_TO_STREAM(p, curr.As32Bit());
- num_uuid++;
- } else {
- data_type = HCI_EIR_MORE_32BITS_UUID_TYPE;
- APPL_TRACE_WARNING("BTA EIR: UUID 32-bit list is truncated");
- break;
- }
- }
- }
-
- UINT8_TO_STREAM(p_length, num_uuid * Uuid::kNumBytes32 + 1);
- UINT8_TO_STREAM(p_type, data_type);
- free_eir_length -= num_uuid * Uuid::kNumBytes32 + 2;
- }
-
- /* Adding 128-bit UUID list */
- if (free_eir_length >= 2) {
- p_length = p++;
- p_type = p++;
- num_uuid = 0;
- data_type = HCI_EIR_COMPLETE_128BITS_UUID_TYPE;
-
- max_num_uuid = (free_eir_length - 2) / Uuid::kNumBytes128;
-
- for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID;
- custom_uuid_idx++) {
- const Uuid& curr = bta_dm_cb.bta_custom_uuid[custom_uuid_idx].custom_uuid;
- if (curr.GetShortestRepresentationSize() == Uuid::kNumBytes128) {
- if (num_uuid < max_num_uuid) {
- ARRAY16_TO_STREAM(p, curr.To128BitBE().data());
- num_uuid++;
- } else {
- data_type = HCI_EIR_MORE_128BITS_UUID_TYPE;
- APPL_TRACE_WARNING("BTA EIR: UUID 128-bit list is truncated");
- break;
- }
- }
- }
-
- UINT8_TO_STREAM(p_length, num_uuid * Uuid::kNumBytes128 + 1);
- UINT8_TO_STREAM(p_type, data_type);
- free_eir_length -= num_uuid * Uuid::kNumBytes128 + 2;
- }
-#endif /* ( BTA_EIR_CANNED_UUID_LIST != TRUE \
- )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
-
- /* if Flags are provided in configuration */
- if ((p_bta_dm_eir_cfg->bta_dm_eir_flag_len > 0) &&
- (p_bta_dm_eir_cfg->bta_dm_eir_flags) &&
- (free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2)) {
- UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 1);
- UINT8_TO_STREAM(p, HCI_EIR_FLAGS_TYPE);
- memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_flags,
- p_bta_dm_eir_cfg->bta_dm_eir_flag_len);
- p += p_bta_dm_eir_cfg->bta_dm_eir_flag_len;
- free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2;
- }
-
- /* if Manufacturer Specific are provided in configuration */
- if ((p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len > 0) &&
- (p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec) &&
- (free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2)) {
- p_length = p;
-
- UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 1);
- UINT8_TO_STREAM(p, HCI_EIR_MANUFACTURER_SPECIFIC_TYPE);
- memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec,
- p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len);
- p += p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len;
- free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2;
-
- } else {
- p_length = NULL;
- }
-
- /* if Inquiry Tx Resp Power compiled */
- if ((p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power) && (free_eir_length >= 3)) {
- UINT8_TO_STREAM(p, 2); /* Length field */
- UINT8_TO_STREAM(p, HCI_EIR_TX_POWER_LEVEL_TYPE);
- UINT8_TO_STREAM(p, *(p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power));
- free_eir_length -= 3;
- }
-
- if (free_eir_length)
- UINT8_TO_STREAM(p, 0); /* terminator of significant part */
-
- BTM_WriteEIR(p_buf);
-}
-
-#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
-/*******************************************************************************
- *
- * Function bta_dm_get_cust_uuid_index
- *
- * Description Get index of custom uuid from list
- * Note, handle equals to 0 means to find a vacant
- * from list.
- *
- * Returns Index of array
- * bta_dm_cb.bta_custom_uuid[BTA_EIR_SERVER_NUM_CUSTOM_UUID]
- *
- ******************************************************************************/
-static uint8_t bta_dm_get_cust_uuid_index(uint32_t handle) {
-#if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
- uint8_t c_uu_idx = 0;
-
- while(c_uu_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID &&
- bta_dm_cb.bta_custom_uuid[c_uu_idx].handle != handle) {
- c_uu_idx++;
- }
-
- return c_uu_idx;
-#else
- return 0;
-#endif
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_update_cust_uuid
- *
- * Description Update custom uuid with given value
- *
- * Returns None
- *
- ******************************************************************************/
-static void bta_dm_update_cust_uuid(uint8_t c_uu_idx, const Uuid& uuid, uint32_t handle) {
-#if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
- if (c_uu_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID) {
- tBTA_CUSTOM_UUID& curr = bta_dm_cb.bta_custom_uuid[c_uu_idx];
- curr.custom_uuid.UpdateUuid(uuid);
- curr.handle = handle;
- } else {
- APPL_TRACE_ERROR("%s invalid uuid index %d", __func__, c_uu_idx);
- }
-#endif
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_eir_update_cust_uuid
- *
- * Description This function adds or removes custom service UUID in EIR database.
- *
- * Returns None
- *
- ******************************************************************************/
-void bta_dm_eir_update_cust_uuid(const tBTA_CUSTOM_UUID& curr, bool adding) {
- APPL_TRACE_DEBUG("%s", __func__);
-#if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
- uint8_t c_uu_idx = 0;
- if (adding) {
- c_uu_idx = bta_dm_get_cust_uuid_index(0); /* find a vacant from uuid list */
- bta_dm_update_cust_uuid(c_uu_idx, curr.custom_uuid, curr.handle);
- } else {
- c_uu_idx = bta_dm_get_cust_uuid_index(curr.handle); /* find the uuid from uuid list */
- bta_dm_update_cust_uuid(c_uu_idx, curr.custom_uuid, 0);
- }
-
- /* Update EIR when UUIDs are changed */
- if (c_uu_idx <= BTA_EIR_SERVER_NUM_CUSTOM_UUID) {
- bta_dm_set_eir(NULL);
- }
-#endif
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_eir_update_uuid
- *
- * Description This function adds or removes service UUID in EIR database.
- *
- * Returns None
- *
- ******************************************************************************/
-void bta_dm_eir_update_uuid(uint16_t uuid16, bool adding) {
- /* if this UUID is not advertised in EIR */
- if (!BTM_HasEirService(p_bta_dm_eir_cfg->uuid_mask, uuid16)) return;
-
- if (adding) {
- LOG_INFO("EIR Adding UUID=0x%04X into extended inquiry response", uuid16);
-
- BTM_AddEirService(bta_dm_cb.eir_uuid, uuid16);
- } else {
- LOG_INFO("EIR Removing UUID=0x%04X from extended inquiry response", uuid16);
-
- BTM_RemoveEirService(bta_dm_cb.eir_uuid, uuid16);
- }
-
- bta_dm_set_eir(NULL);
-}
-#endif
-
-/*******************************************************************************
- *
- * Function bta_dm_encrypt_cback
- *
- * Description link encryption complete callback.
- *
- * Returns None
- *
- ******************************************************************************/
-void bta_dm_encrypt_cback(const RawAddress* bd_addr, tBT_TRANSPORT transport,
- UNUSED_ATTR void* p_ref_data, tBTM_STATUS result) {
- tBTA_STATUS bta_status = BTA_SUCCESS;
- tBTA_DM_ENCRYPT_CBACK* p_callback = NULL;
- uint8_t i;
-
- for (i = 0; i < bta_dm_cb.device_list.count; i++) {
- if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == *bd_addr &&
- bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
- break;
- }
-
- if (i < bta_dm_cb.device_list.count) {
- p_callback = bta_dm_cb.device_list.peer_device[i].p_encrypt_cback;
- bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = NULL;
- }
-
- switch (result) {
- case BTM_SUCCESS:
- break;
- case BTM_WRONG_MODE:
- bta_status = BTA_WRONG_MODE;
- break;
- case BTM_NO_RESOURCES:
- bta_status = BTA_NO_RESOURCES;
- break;
- case BTM_BUSY:
- bta_status = BTA_BUSY;
- break;
- default:
- bta_status = BTA_FAILURE;
- break;
- }
-
- APPL_TRACE_DEBUG("bta_dm_encrypt_cback status =%d p_callback=0x%x",
- bta_status, p_callback);
-
- if (p_callback) {
- (*p_callback)(*bd_addr, transport, bta_status);
- }
-}
-
-/**This function to encrypt the link */
-void bta_dm_set_encryption(const RawAddress& bd_addr, tBT_TRANSPORT transport,
- tBTA_DM_ENCRYPT_CBACK* p_callback,
- tBTM_BLE_SEC_ACT sec_act) {
- uint8_t i;
-
- APPL_TRACE_DEBUG("bta_dm_set_encryption"); // todo
- if (!p_callback) {
- APPL_TRACE_ERROR("bta_dm_set_encryption callback is not provided");
- return;
- }
- for (i = 0; i < bta_dm_cb.device_list.count; i++) {
- if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == bd_addr &&
- bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
- break;
- }
- if (i < bta_dm_cb.device_list.count) {
- if (bta_dm_cb.device_list.peer_device[i].p_encrypt_cback) {
- APPL_TRACE_ERROR("earlier enc was not done for same device");
- (*p_callback)(bd_addr, transport, BTA_BUSY);
- return;
- }
-
- if (BTM_SetEncryption(bd_addr, transport, bta_dm_encrypt_cback, NULL,
- sec_act) == BTM_CMD_STARTED) {
- bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = p_callback;
- }
- }
-}
-
-bool bta_dm_check_if_only_hd_connected(const RawAddress& peer_addr) {
- APPL_TRACE_DEBUG("%s: count(%d)", __func__, bta_dm_conn_srvcs.count);
-
- for (uint8_t j = 0; j < bta_dm_conn_srvcs.count; j++) {
- // Check if profiles other than hid are connected
- if ((bta_dm_conn_srvcs.conn_srvc[j].id != BTA_ID_HD) &&
- bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr == peer_addr) {
- APPL_TRACE_DEBUG("%s: Another profile (id=%d) is connected", __func__,
- bta_dm_conn_srvcs.conn_srvc[j].id);
- return false;
- }
- }
-
- return true;
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_observe_results_cb
- *
- * Description Callback for BLE Observe result
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS* p_inq,
- const uint8_t* p_eir, uint16_t eir_len) {
- tBTA_DM_SEARCH result;
- tBTM_INQ_INFO* p_inq_info;
- APPL_TRACE_DEBUG("bta_dm_observe_results_cb");
-
- result.inq_res.bd_addr = p_inq->remote_bd_addr;
- result.inq_res.rssi = p_inq->rssi;
- result.inq_res.ble_addr_type = p_inq->ble_addr_type;
- result.inq_res.inq_result_type = p_inq->inq_result_type;
- result.inq_res.device_type = p_inq->device_type;
- result.inq_res.flag = p_inq->flag;
- result.inq_res.ble_evt_type = p_inq->ble_evt_type;
- result.inq_res.ble_primary_phy = p_inq->ble_primary_phy;
- result.inq_res.ble_secondary_phy = p_inq->ble_secondary_phy;
- result.inq_res.ble_advertising_sid = p_inq->ble_advertising_sid;
- result.inq_res.ble_tx_power = p_inq->ble_tx_power;
- result.inq_res.ble_periodic_adv_int = p_inq->ble_periodic_adv_int;
-
- /* application will parse EIR to find out remote device name */
- result.inq_res.p_eir = const_cast<uint8_t*>(p_eir);
- result.inq_res.eir_len = eir_len;
-
- p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr);
- if (p_inq_info != NULL) {
- /* initialize remt_name_not_required to false so that we get the name by
- * default */
- result.inq_res.remt_name_not_required = false;
- }
-
- if (bta_dm_search_cb.p_scan_cback)
- bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_RES_EVT, &result);
-
- if (p_inq_info) {
- /* application indicates if it knows the remote name, inside the callback
- copy that to the inquiry data base*/
- if (result.inq_res.remt_name_not_required)
- p_inq_info->appl_knows_rem_name = true;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_opportunistic_observe_results_cb
- *
- * Description Callback for BLE Observe result
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_opportunistic_observe_results_cb(tBTM_INQ_RESULTS* p_inq,
- const uint8_t* p_eir,
- uint16_t eir_len) {
- tBTA_DM_SEARCH result;
- tBTM_INQ_INFO* p_inq_info;
-
- result.inq_res.bd_addr = p_inq->remote_bd_addr;
- result.inq_res.rssi = p_inq->rssi;
- result.inq_res.ble_addr_type = p_inq->ble_addr_type;
- result.inq_res.inq_result_type = p_inq->inq_result_type;
- result.inq_res.device_type = p_inq->device_type;
- result.inq_res.flag = p_inq->flag;
- result.inq_res.ble_evt_type = p_inq->ble_evt_type;
- result.inq_res.ble_primary_phy = p_inq->ble_primary_phy;
- result.inq_res.ble_secondary_phy = p_inq->ble_secondary_phy;
- result.inq_res.ble_advertising_sid = p_inq->ble_advertising_sid;
- result.inq_res.ble_tx_power = p_inq->ble_tx_power;
- result.inq_res.ble_periodic_adv_int = p_inq->ble_periodic_adv_int;
-
- /* application will parse EIR to find out remote device name */
- result.inq_res.p_eir = const_cast<uint8_t*>(p_eir);
- result.inq_res.eir_len = eir_len;
-
- p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr);
- if (p_inq_info != NULL) {
- /* initialize remt_name_not_required to false so that we get the name by
- * default */
- result.inq_res.remt_name_not_required = false;
- }
-
- if (bta_dm_search_cb.p_csis_scan_cback)
- bta_dm_search_cb.p_csis_scan_cback(BTA_DM_INQ_RES_EVT, &result);
-
- if (p_inq_info) {
- /* application indicates if it knows the remote name, inside the callback
- copy that to the inquiry data base*/
- if (result.inq_res.remt_name_not_required)
- p_inq_info->appl_knows_rem_name = true;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_observe_cmpl_cb
- *
- * Description Callback for BLE Observe complete
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_observe_cmpl_cb(void* p_result) {
- tBTA_DM_SEARCH data;
-
- APPL_TRACE_DEBUG("bta_dm_observe_cmpl_cb");
-
- data.inq_cmpl.num_resps = ((tBTM_INQUIRY_CMPL*)p_result)->num_resp;
- if (bta_dm_search_cb.p_scan_cback) {
- bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
- }
- if (bta_dm_search_cb.p_csis_scan_cback) {
- bta_dm_search_cb.p_csis_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
- }
-}
-
-static void ble_io_req(const RawAddress& bd_addr, tBTM_IO_CAP* p_io_cap,
- tBTM_OOB_DATA* p_oob_data, tBTM_LE_AUTH_REQ* p_auth_req,
- uint8_t* p_max_key_size, tBTM_LE_KEY_TYPE* p_init_key,
- tBTM_LE_KEY_TYPE* p_resp_key) {
- bte_appl_cfg.ble_io_cap = btif_storage_get_local_io_caps_ble();
-
- /* Retrieve the properties from file system if possible */
- tBTE_APPL_CFG nv_config;
- if (btif_dm_get_smp_config(&nv_config)) bte_appl_cfg = nv_config;
-
- /* *p_auth_req by default is false for devices with NoInputNoOutput; true for
- * other devices. */
-
- if (bte_appl_cfg.ble_auth_req)
- *p_auth_req = bte_appl_cfg.ble_auth_req |
- (bte_appl_cfg.ble_auth_req & 0x04) | ((*p_auth_req) & 0x04);
-
- /* if OOB is not supported, this call-out function does not need to do
- * anything
- * otherwise, look for the OOB data associated with the address and set
- * *p_oob_data accordingly.
- * If the answer can not be obtained right away,
- * set *p_oob_data to BTA_OOB_UNKNOWN and call bta_dm_ci_io_req() when the
- * answer is available.
- */
-
- btif_dm_set_oob_for_le_io_req(bd_addr, p_oob_data, p_auth_req);
-
- if (bte_appl_cfg.ble_io_cap <= 4) *p_io_cap = bte_appl_cfg.ble_io_cap;
-
- if (bte_appl_cfg.ble_init_key <= BTM_BLE_INITIATOR_KEY_SIZE)
- *p_init_key = bte_appl_cfg.ble_init_key;
-
- if (bte_appl_cfg.ble_resp_key <= BTM_BLE_RESPONDER_KEY_SIZE)
- *p_resp_key = bte_appl_cfg.ble_resp_key;
-
- if (bte_appl_cfg.ble_max_key_size > 7 && bte_appl_cfg.ble_max_key_size <= 16)
- *p_max_key_size = bte_appl_cfg.ble_max_key_size;
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_ble_smp_cback
- *
- * Description Callback for BLE SMP
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, const RawAddress& bda,
- tBTM_LE_EVT_DATA* p_data) {
- tBTM_STATUS status = BTM_SUCCESS;
- tBTA_DM_SEC sec_event;
- char* p_name = NULL;
-
- if (!bta_dm_cb.p_sec_cback) return BTM_NOT_AUTHORIZED;
-
- memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
- switch (event) {
- case BTM_LE_IO_REQ_EVT:
- ble_io_req(bda, &p_data->io_req.io_cap, &p_data->io_req.oob_data,
- &p_data->io_req.auth_req, &p_data->io_req.max_key_size,
- &p_data->io_req.init_keys, &p_data->io_req.resp_keys);
- APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req,
- p_data->io_req.oob_data);
- break;
-
- case BTM_LE_CONSENT_REQ_EVT:
- sec_event.ble_req.bd_addr = bda;
- p_name = BTM_SecReadDevName(bda);
- if (p_name != NULL)
- strlcpy((char*)sec_event.ble_req.bd_name, p_name, BD_NAME_LEN);
- else
- sec_event.ble_req.bd_name[0] = 0;
- bta_dm_cb.p_sec_cback(BTA_DM_BLE_CONSENT_REQ_EVT, &sec_event);
- break;
-
- case BTM_LE_SEC_REQUEST_EVT:
- sec_event.ble_req.bd_addr = bda;
- p_name = (bluetooth::shim::is_gd_security_enabled())
- ? bluetooth::shim::BTM_SecReadDevName(bda)
- : BTM_SecReadDevName(bda);
- if (p_name != NULL)
- strlcpy((char*)sec_event.ble_req.bd_name, p_name, BD_NAME_LEN + 1);
- else
- sec_event.ble_req.bd_name[0] = 0;
- bta_dm_cb.p_sec_cback(BTA_DM_BLE_SEC_REQ_EVT, &sec_event);
- break;
-
- case BTM_LE_KEY_NOTIF_EVT:
- sec_event.key_notif.bd_addr = bda;
- p_name = (bluetooth::shim::is_gd_security_enabled())
- ? bluetooth::shim::BTM_SecReadDevName(bda)
- : BTM_SecReadDevName(bda);
- if (p_name != NULL)
- strlcpy((char*)sec_event.key_notif.bd_name, p_name, BD_NAME_LEN + 1);
- else
- sec_event.key_notif.bd_name[0] = 0;
- sec_event.key_notif.passkey = p_data->key_notif;
- bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_NOTIF_EVT, &sec_event);
- break;
-
- case BTM_LE_KEY_REQ_EVT:
- sec_event.ble_req.bd_addr = bda;
- bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_REQ_EVT, &sec_event);
- break;
-
- case BTM_LE_OOB_REQ_EVT:
- sec_event.ble_req.bd_addr = bda;
- bta_dm_cb.p_sec_cback(BTA_DM_BLE_OOB_REQ_EVT, &sec_event);
- break;
-
- case BTM_LE_NC_REQ_EVT:
- sec_event.key_notif.bd_addr = bda;
- strlcpy((char*)sec_event.key_notif.bd_name, bta_dm_get_remname(),
- (BD_NAME_LEN + 1));
- sec_event.key_notif.passkey = p_data->key_notif;
- bta_dm_cb.p_sec_cback(BTA_DM_BLE_NC_REQ_EVT, &sec_event);
- break;
-
- case BTM_LE_SC_OOB_REQ_EVT:
- sec_event.ble_req.bd_addr = bda;
- bta_dm_cb.p_sec_cback(BTA_DM_BLE_SC_OOB_REQ_EVT, &sec_event);
- break;
-
- case BTM_LE_SC_LOC_OOB_EVT:
- tBTA_DM_LOC_OOB_DATA local_oob_data;
- local_oob_data.local_oob_c = p_data->local_oob_data.commitment;
- local_oob_data.local_oob_r = p_data->local_oob_data.randomizer;
- sec_event.local_oob_data = local_oob_data;
- bta_dm_cb.p_sec_cback(BTA_DM_BLE_SC_CR_LOC_OOB_EVT, &sec_event);
- break;
-
- case BTM_LE_KEY_EVT:
- sec_event.ble_key.bd_addr = bda;
- sec_event.ble_key.key_type = p_data->key.key_type;
- sec_event.ble_key.p_key_value = p_data->key.p_key_value;
- bta_dm_cb.p_sec_cback(BTA_DM_BLE_KEY_EVT, &sec_event);
- break;
-
- case BTM_LE_COMPLT_EVT:
- sec_event.auth_cmpl.bd_addr = bda;
- BTM_ReadDevInfo(bda, &sec_event.auth_cmpl.dev_type,
- &sec_event.auth_cmpl.addr_type);
- p_name = (bluetooth::shim::is_gd_security_enabled())
- ? bluetooth::shim::BTM_SecReadDevName(bda)
- : BTM_SecReadDevName(bda);
- if (p_name != NULL)
- strlcpy((char*)sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN + 1));
- else
- sec_event.auth_cmpl.bd_name[0] = 0;
-
- if (p_data->complt.reason != HCI_SUCCESS) {
- // TODO This is not a proper use of this type
- sec_event.auth_cmpl.fail_reason =
- static_cast<tHCI_STATUS>(BTA_DM_AUTH_CONVERT_SMP_CODE(
- (static_cast<uint8_t>(p_data->complt.reason))));
-
- if (btm_sec_is_a_bonded_dev(bda) &&
- p_data->complt.reason == SMP_CONN_TOUT) {
- // Bonded device failed to encrypt - to test this remove battery from
- // HID device right after connection, but before encryption is
- // established
- LOG(INFO) << __func__
- << ": bonded device disconnected when encrypting - no "
- "reason to unbond";
- } else {
- /* delete this device entry from Sec Dev DB */
- bta_dm_remove_sec_dev_entry(bda);
- }
-
- } else {
- sec_event.auth_cmpl.success = true;
- if (!p_data->complt.smp_over_br)
- GATT_ConfigServiceChangeCCC(bda, true, BT_TRANSPORT_LE);
- }
-
- if (bta_dm_cb.p_sec_cback) {
- // bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
- bta_dm_cb.p_sec_cback(BTA_DM_BLE_AUTH_CMPL_EVT, &sec_event);
- }
- break;
-
- default:
- status = BTM_NOT_AUTHORIZED;
- break;
- }
- return status;
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_ble_id_key_cback
- *
- * Description Callback for BLE local ID keys
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_ble_id_key_cback(uint8_t key_type,
- tBTM_BLE_LOCAL_KEYS* p_key) {
- switch (key_type) {
- case BTM_BLE_KEY_TYPE_ID:
- case BTM_BLE_KEY_TYPE_ER:
- if (bta_dm_cb.p_sec_cback) {
- tBTA_DM_SEC dm_key = {
- .ble_id_keys = {},
- };
- memcpy(&dm_key.ble_id_keys, p_key, sizeof(tBTM_BLE_LOCAL_KEYS));
-
- uint8_t evt = (key_type == BTM_BLE_KEY_TYPE_ID)
- ? BTA_DM_BLE_LOCAL_IR_EVT
- : BTA_DM_BLE_LOCAL_ER_EVT;
- bta_dm_cb.p_sec_cback(evt, &dm_key);
- }
- break;
-
- default:
- APPL_TRACE_DEBUG("Unknown key type %d", key_type);
- break;
- }
- return;
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_add_blekey
- *
- * Description This function adds an BLE Key to an security database entry.
- * This function shall only be called AFTER BTA_DmAddBleDevice
- * has been called.
- * It is normally called during host startup to restore all
- * required information stored in the NVRAM.
- *
- * Parameters:
- *
- ******************************************************************************/
-void bta_dm_add_blekey(const RawAddress& bd_addr, tBTA_LE_KEY_VALUE blekey,
- tBTM_LE_KEY_TYPE key_type) {
- BTM_SecAddBleKey(bd_addr, (tBTM_LE_KEY_VALUE*)&blekey, key_type);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_add_ble_device
- *
- * Description This function adds an BLE device to an security database
- * entry.
- * It is normally called during host startup to restore all
- * required information stored in the NVRAM.
- *
- * Parameters:
- *
- ******************************************************************************/
-void bta_dm_add_ble_device(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type,
- tBT_DEVICE_TYPE dev_type) {
- BTM_SecAddBleDevice(bd_addr, dev_type, addr_type);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_add_ble_device
- *
- * Description This function adds an BLE device to an security database
- * entry.
- * It is normally called during host startup to restore all
- * required information stored in the NVRAM.
- *
- * Parameters:
- *
- ******************************************************************************/
-void bta_dm_ble_passkey_reply(const RawAddress& bd_addr, bool accept,
- uint32_t passkey) {
- BTM_BlePasskeyReply(bd_addr, accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED,
- passkey);
-}
-
-/** This is response to SM numeric comparison request submitted to application.
- */
-void bta_dm_ble_confirm_reply(const RawAddress& bd_addr, bool accept) {
- BTM_BleConfirmReply(bd_addr, accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED);
-}
-
-/** This function set the preferred connection parameters */
-void bta_dm_ble_set_conn_params(const RawAddress& bd_addr,
- uint16_t conn_int_min, uint16_t conn_int_max,
- uint16_t peripheral_latency,
- uint16_t supervision_tout) {
- L2CA_AdjustConnectionIntervals(&conn_int_min, &conn_int_max,
- BTM_BLE_CONN_INT_MIN);
-
- BTM_BleSetPrefConnParams(bd_addr, conn_int_min, conn_int_max,
- peripheral_latency, supervision_tout);
-}
-
-/** This function update LE connection parameters */
-void bta_dm_ble_update_conn_params(const RawAddress& bd_addr, uint16_t min_int,
- uint16_t max_int, uint16_t latency,
- uint16_t timeout, uint16_t min_ce_len,
- uint16_t max_ce_len) {
- L2CA_AdjustConnectionIntervals(&min_int, &max_int, BTM_BLE_CONN_INT_MIN);
-
- if (!L2CA_UpdateBleConnParams(bd_addr, min_int, max_int, latency, timeout,
- min_ce_len, max_ce_len)) {
- APPL_TRACE_ERROR("Update connection parameters failed!");
- }
-}
-
-/** This function set the local device LE privacy settings. */
-void bta_dm_ble_config_local_privacy(bool privacy_enable) {
- BTM_BleConfigPrivacy(privacy_enable);
-}
-
-static void bta_dm_start_scan(uint8_t duration_sec) {
- tBTM_STATUS status = BTM_BleObserve(
- true, duration_sec, bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb);
-
- if (status != BTM_CMD_STARTED) {
- tBTA_DM_SEARCH data = {
- .inq_cmpl =
- {
- .num_resps = 0,
- },
- };
- APPL_TRACE_WARNING(" %s BTM_BleObserve failed. status %d", __func__,
- status);
- if (bta_dm_search_cb.p_scan_cback) {
- bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
- }
- if (bta_dm_search_cb.p_csis_scan_cback) {
- bta_dm_search_cb.p_csis_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
- }
- }
-}
-
-void bta_dm_ble_observe(bool start, uint8_t duration,
- tBTA_DM_SEARCH_CBACK* p_cback) {
- if (!start) {
- bta_dm_search_cb.p_scan_cback = NULL;
- BTM_BleObserve(false, 0, NULL, NULL);
- return;
- }
-
- /*Save the callback to be called when a scan results are available */
- bta_dm_search_cb.p_scan_cback = p_cback;
- bta_dm_start_scan(duration);
-}
-
-void bta_dm_ble_scan(bool start, uint8_t duration_sec) {
- /* Start or stop only if there is no active main scanner */
- if (bta_dm_search_cb.p_scan_cback != NULL) return;
-
- if (!start) {
- BTM_BleObserve(false, 0, NULL, NULL);
- return;
- }
-
- bta_dm_start_scan(duration_sec);
-}
-
-void bta_dm_ble_csis_observe(bool observe, tBTA_DM_SEARCH_CBACK* p_cback) {
- if (!observe) {
- bta_dm_search_cb.p_csis_scan_cback = NULL;
- BTM_BleOpportunisticObserve(false, NULL);
- return;
- }
-
- /* Save the callback to be called when a scan results are available */
- bta_dm_search_cb.p_csis_scan_cback = p_cback;
- BTM_BleOpportunisticObserve(true, bta_dm_opportunistic_observe_results_cb);
-}
-
-/** This function set the maximum transmission packet size */
-void bta_dm_ble_set_data_length(const RawAddress& bd_addr) {
- const controller_t* controller = controller_get_interface();
- uint16_t max_len = controller->get_ble_maximum_tx_data_length();
-
- if (BTM_SetBleDataLength(bd_addr, max_len) != BTM_SUCCESS) {
- LOG_INFO("Unable to set ble data length:%hu", max_len);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_ble_enable_scan_cmpl
- *
- * Description ADV payload filtering enable / disable complete callback
- *
- *
- * Returns None
- *
- ******************************************************************************/
-static void bta_ble_energy_info_cmpl(tBTM_BLE_TX_TIME_MS tx_time,
- tBTM_BLE_RX_TIME_MS rx_time,
- tBTM_BLE_IDLE_TIME_MS idle_time,
- tBTM_BLE_ENERGY_USED energy_used,
- tHCI_STATUS status) {
- tBTA_STATUS st = (status == HCI_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE;
- tBTM_CONTRL_STATE ctrl_state = BTM_CONTRL_UNKNOWN;
-
- if (BTA_SUCCESS == st) ctrl_state = bta_dm_pm_obtain_controller_state();
-
- if (bta_dm_cb.p_energy_info_cback)
- bta_dm_cb.p_energy_info_cback(tx_time, rx_time, idle_time, energy_used,
- ctrl_state, st);
-}
-
-/** This function obtains the energy info */
-void bta_dm_ble_get_energy_info(
- tBTA_BLE_ENERGY_INFO_CBACK* p_energy_info_cback) {
- bta_dm_cb.p_energy_info_cback = p_energy_info_cback;
- tBTM_STATUS btm_status = BTM_BleGetEnergyInfo(bta_ble_energy_info_cmpl);
- if (btm_status != BTM_CMD_STARTED)
- bta_ble_energy_info_cmpl(0, 0, 0, 0, HCI_ERR_UNSPECIFIED);
-}
-
-#ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
-#define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000
-#endif
-
-/*******************************************************************************
- *
- * Function bta_dm_gattc_register
- *
- * Description Register with GATTC in DM if BLE is needed.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_gattc_register(void) {
- if (bta_dm_search_cb.client_if == BTA_GATTS_INVALID_IF) {
- BTA_GATTC_AppRegister(bta_dm_gattc_callback,
- base::Bind([](uint8_t client_id, uint8_t status) {
- if (status == GATT_SUCCESS)
- bta_dm_search_cb.client_if = client_id;
- else
- bta_dm_search_cb.client_if = BTA_GATTS_INVALID_IF;
-
- }), false);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_gatt_disc_complete
- *
- * Description This function process the GATT service search complete.
- *
- * Parameters:
- *
- ******************************************************************************/
-static void bta_dm_gatt_disc_complete(uint16_t conn_id, tGATT_STATUS status) {
- APPL_TRACE_DEBUG("%s conn_id = %d", __func__, conn_id);
-
- tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
-
- /* no more services to be discovered */
- p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
- p_msg->disc_result.result.disc_res.result =
- (status == GATT_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE;
- APPL_TRACE_DEBUG("%s service found: 0x%08x", __func__,
- bta_dm_search_cb.services_found);
- p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
- p_msg->disc_result.result.disc_res.num_uuids = 0;
- p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
- p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
- strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
- bta_dm_get_remname(), BD_NAME_LEN + 1);
-
- p_msg->disc_result.result.disc_res.device_type |= BT_DEVICE_TYPE_BLE;
-
- bta_sys_sendmsg(p_msg);
-
- if (conn_id != GATT_INVALID_CONN_ID) {
- /* start a GATT channel close delay timer */
- bta_sys_start_timer(bta_dm_search_cb.gatt_close_timer,
- BTA_DM_GATT_CLOSE_DELAY_TOUT,
- BTA_DM_DISC_CLOSE_TOUT_EVT, 0);
- bta_dm_search_cb.pending_close_bda = bta_dm_search_cb.peer_bdaddr;
- }
- bta_dm_search_cb.gatt_disc_active = false;
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_close_gatt_conn
- *
- * Description This function close the GATT connection after delay
- *timeout.
- *
- * Parameters:
- *
- ******************************************************************************/
-void bta_dm_close_gatt_conn(UNUSED_ATTR tBTA_DM_MSG* p_data) {
- if (bta_dm_search_cb.conn_id != GATT_INVALID_CONN_ID)
- BTA_GATTC_Close(bta_dm_search_cb.conn_id);
-
- bta_dm_search_cb.pending_close_bda = RawAddress::kEmpty;
- bta_dm_search_cb.conn_id = GATT_INVALID_CONN_ID;
-}
-/*******************************************************************************
- *
- * Function btm_dm_start_gatt_discovery
- *
- * Description This is GATT initiate the service search by open a GATT
- * connection first.
- *
- * Parameters:
- *
- ******************************************************************************/
-void btm_dm_start_gatt_discovery(const RawAddress& bd_addr) {
- bta_dm_search_cb.gatt_disc_active = true;
-
- /* connection is already open */
- if (bta_dm_search_cb.pending_close_bda == bd_addr &&
- bta_dm_search_cb.conn_id != GATT_INVALID_CONN_ID) {
- bta_dm_search_cb.pending_close_bda = RawAddress::kEmpty;
- alarm_cancel(bta_dm_search_cb.gatt_close_timer);
- BTA_GATTC_ServiceSearchRequest(bta_dm_search_cb.conn_id, nullptr);
- } else {
- if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE)) {
- BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, true, true);
- } else {
- BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, true, false);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_cancel_gatt_discovery
- *
- * Description This is GATT cancel the GATT service search.
- *
- * Parameters:
- *
- ******************************************************************************/
-static void bta_dm_cancel_gatt_discovery(const RawAddress& bd_addr) {
- if (bta_dm_search_cb.conn_id == GATT_INVALID_CONN_ID) {
- BTA_GATTC_CancelOpen(bta_dm_search_cb.client_if, bd_addr, true);
- }
-
- bta_dm_gatt_disc_complete(bta_dm_search_cb.conn_id, (tGATT_STATUS)GATT_ERROR);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_proc_open_evt
- *
- * Description process BTA_GATTC_OPEN_EVT in DM.
- *
- * Parameters:
- *
- ******************************************************************************/
-void bta_dm_proc_open_evt(tBTA_GATTC_OPEN* p_data) {
- VLOG(1) << "DM Search state= " << bta_dm_search_cb.state
- << " search_cb.peer_dbaddr:" << bta_dm_search_cb.peer_bdaddr
- << " connected_bda=" << p_data->remote_bda.address;
-
- APPL_TRACE_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d",
- p_data->conn_id, p_data->client_if, p_data->status);
-
- bta_dm_search_cb.conn_id = p_data->conn_id;
-
- if (p_data->status == GATT_SUCCESS) {
- BTA_GATTC_ServiceSearchRequest(p_data->conn_id, nullptr);
- } else {
- bta_dm_gatt_disc_complete(GATT_INVALID_CONN_ID, p_data->status);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_gattc_callback
- *
- * Description This is GATT client callback function used in DM.
- *
- * Parameters:
- *
- ******************************************************************************/
-static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
- APPL_TRACE_DEBUG("bta_dm_gattc_callback event = %d", event);
-
- switch (event) {
- case BTA_GATTC_OPEN_EVT:
- bta_dm_proc_open_evt(&p_data->open);
- break;
-
- case BTA_GATTC_SEARCH_RES_EVT:
- break;
-
- case BTA_GATTC_SEARCH_CMPL_EVT:
- if (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE)
- bta_dm_gatt_disc_complete(p_data->search_cmpl.conn_id,
- p_data->search_cmpl.status);
- break;
-
- case BTA_GATTC_CLOSE_EVT:
- LOG_DEBUG("BTA_GATTC_CLOSE_EVT reason = %d", p_data->close.reason);
- /* in case of disconnect before search is completed */
- if ((bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) &&
- (bta_dm_search_cb.state != BTA_DM_SEARCH_ACTIVE) &&
- p_data->close.remote_bda == bta_dm_search_cb.peer_bdaddr) {
- bta_dm_gatt_disc_complete((uint16_t)GATT_INVALID_CONN_ID,
- (tGATT_STATUS)GATT_ERROR);
- }
- break;
-
- default:
- break;
- }
-}
-
-#if (BLE_VND_INCLUDED == TRUE)
-/*******************************************************************************
- *
- * Function bta_dm_ctrl_features_rd_cmpl_cback
- *
- * Description callback to handle controller feature read complete
- *
- * Parameters:
- *
- ******************************************************************************/
-static void bta_dm_ctrl_features_rd_cmpl_cback(tHCI_STATUS result) {
- APPL_TRACE_DEBUG("%s status = %d ", __func__, result);
- if (result == HCI_SUCCESS) {
- if (bta_dm_cb.p_sec_cback)
- bta_dm_cb.p_sec_cback(BTA_DM_LE_FEATURES_READ, NULL);
- } else {
- APPL_TRACE_ERROR("%s Ctrl BLE feature read failed: status :%d", __func__,
- result);
- }
-}
-#endif /* BLE_VND_INCLUDED */
diff --git a/bta/dm/bta_dm_api.cc b/bta/dm/bta_dm_api.cc
deleted file mode 100644
index c1bdf0e..0000000
--- a/bta/dm/bta_dm_api.cc
+++ /dev/null
@@ -1,672 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2014 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the API implementation file for the BTA device manager.
- *
- ******************************************************************************/
-
-#include <base/bind.h>
-
-#include <vector>
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bta/dm/bta_dm_int.h"
-#include "osi/include/allocator.h"
-#include "osi/include/compat.h"
-#include "stack/btm/btm_sec.h"
-#include "stack/include/bt_octets.h"
-#include "stack/include/btm_api.h"
-#include "stack/include/btm_client_interface.h"
-#include "stack/include/btu.h" // do_in_main_thread
-#include "types/bluetooth/uuid.h"
-#include "types/raw_address.h"
-
-using bluetooth::Uuid;
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-
-static const tBTA_SYS_REG bta_dm_search_reg = {bta_dm_search_sm_execute,
- bta_dm_search_sm_disable};
-
-void BTA_dm_init() {
- bta_sys_register(BTA_ID_DM_SEARCH, &bta_dm_search_reg);
- /* if UUID list is not provided as static data */
- bta_sys_eir_register(bta_dm_eir_update_uuid);
- bta_sys_cust_eir_register(bta_dm_eir_update_cust_uuid);
-}
-
-/** Enables bluetooth device under test mode */
-void BTA_EnableTestMode(void) {
- do_in_main_thread(FROM_HERE,
- base::Bind(base::IgnoreResult(BTM_EnableTestMode)));
-}
-
-/** This function sets the Bluetooth name of local device */
-void BTA_DmSetDeviceName(char* p_name) {
- std::vector<uint8_t> name(BD_NAME_LEN + 1);
- strlcpy((char*)name.data(), p_name, BD_NAME_LEN + 1);
-
- do_in_main_thread(FROM_HERE, base::Bind(bta_dm_set_dev_name, name));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmSearch
- *
- * Description This function searches for peer Bluetooth devices. It
- * performs an inquiry and gets the remote name for devices.
- * Service discovery is done if services is non zero
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmSearch(tBTA_DM_SEARCH_CBACK* p_cback, bool is_bonding_or_sdp) {
- tBTA_DM_API_SEARCH* p_msg =
- (tBTA_DM_API_SEARCH*)osi_calloc(sizeof(tBTA_DM_API_SEARCH));
-
- /* Queue request if a device is bonding or performing service discovery */
- if (is_bonding_or_sdp) {
- p_msg->hdr.event = BTA_DM_API_QUEUE_SEARCH_EVT;
- } else {
- p_msg->hdr.event = BTA_DM_API_SEARCH_EVT;
- }
- p_msg->p_cback = p_cback;
-
- bta_sys_sendmsg(p_msg);
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmSearchCancel
- *
- * Description This function cancels a search initiated by BTA_DmSearch
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmSearchCancel(void) {
- bta_dm_search_clear_queue();
-
- switch (bta_dm_search_get_state()) {
- case BTA_DM_SEARCH_IDLE:
- bta_dm_search_cancel_notify();
- break;
- case BTA_DM_SEARCH_ACTIVE:
- bta_dm_search_set_state(BTA_DM_SEARCH_CANCELLING);
- bta_dm_search_cancel();
- break;
- case BTA_DM_SEARCH_CANCELLING:
- bta_dm_search_cancel_notify();
- break;
- case BTA_DM_DISCOVER_ACTIVE:
- bta_dm_search_set_state(BTA_DM_SEARCH_CANCELLING);
- bta_dm_search_cancel_notify();
- break;
- }
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmDiscover
- *
- * Description This function does service discovery for services of a
- * peer device
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmDiscover(const RawAddress& bd_addr, tBTA_DM_SEARCH_CBACK* p_cback,
- tBT_TRANSPORT transport, bool is_bonding_or_sdp) {
- tBTA_DM_API_DISCOVER* p_msg =
- (tBTA_DM_API_DISCOVER*)osi_calloc(sizeof(tBTA_DM_API_DISCOVER));
-
- if (is_bonding_or_sdp) {
- p_msg->hdr.event = BTA_DM_API_QUEUE_DISCOVER_EVT;
- } else {
- p_msg->hdr.event = BTA_DM_API_DISCOVER_EVT;
- }
- p_msg->bd_addr = bd_addr;
- p_msg->transport = transport;
- p_msg->p_cback = p_cback;
-
- bta_sys_sendmsg(p_msg);
-}
-
-/** This function initiates a bonding procedure with a peer device */
-void BTA_DmBond(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type,
- tBT_TRANSPORT transport, tBT_DEVICE_TYPE device_type) {
- do_in_main_thread(FROM_HERE, base::Bind(bta_dm_bond, bd_addr, addr_type,
- transport, device_type));
-}
-
-/** This function cancels the bonding procedure with a peer device
- */
-void BTA_DmBondCancel(const RawAddress& bd_addr) {
- do_in_main_thread(FROM_HERE, base::Bind(bta_dm_bond_cancel, bd_addr));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmPinReply
- *
- * Description This function provides a pincode for a remote device when
- * one is requested by DM through BTA_DM_PIN_REQ_EVT
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmPinReply(const RawAddress& bd_addr, bool accept, uint8_t pin_len,
- uint8_t* p_pin) {
- std::unique_ptr<tBTA_DM_API_PIN_REPLY> msg =
- std::make_unique<tBTA_DM_API_PIN_REPLY>();
-
- msg->bd_addr = bd_addr;
- msg->accept = accept;
- if (accept) {
- msg->pin_len = pin_len;
- memcpy(msg->p_pin, p_pin, pin_len);
- }
-
- do_in_main_thread(FROM_HERE,
- base::Bind(bta_dm_pin_reply, base::Passed(&msg)));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmLocalOob
- *
- * Description This function retrieves the OOB data from local controller.
- * The result is reported by:
- * - bta_dm_co_loc_oob_ext() if device supports secure
- * connections (SC)
- * - bta_dm_co_loc_oob() if device doesn't support SC
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmLocalOob(void) {
- do_in_main_thread(FROM_HERE, base::Bind(BTM_ReadLocalOobData));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmConfirm
- *
- * Description This function accepts or rejects the numerical value of the
- * Simple Pairing process on BTA_DM_SP_CFM_REQ_EVT
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmConfirm(const RawAddress& bd_addr, bool accept) {
- do_in_main_thread(FROM_HERE, base::Bind(bta_dm_confirm, bd_addr, accept));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmAddDevice
- *
- * Description This function adds a device to the security database list of
- * peer device
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmAddDevice(const RawAddress& bd_addr, DEV_CLASS dev_class,
- const LinkKey& link_key, uint8_t key_type,
- uint8_t pin_length) {
- std::unique_ptr<tBTA_DM_API_ADD_DEVICE> msg =
- std::make_unique<tBTA_DM_API_ADD_DEVICE>();
-
- msg->bd_addr = bd_addr;
- msg->link_key_known = true;
- msg->key_type = key_type;
- msg->link_key = link_key;
-
- /* Load device class if specified */
- if (dev_class) {
- msg->dc_known = true;
- memcpy(msg->dc, dev_class, DEV_CLASS_LEN);
- }
-
- memset(msg->bd_name, 0, BD_NAME_LEN + 1);
- msg->pin_length = pin_length;
-
- do_in_main_thread(FROM_HERE,
- base::Bind(bta_dm_add_device, base::Passed(&msg)));
-}
-
-/** This function removes a device fromthe security database list of peer
- * device. It manages unpairing even while connected */
-tBTA_STATUS BTA_DmRemoveDevice(const RawAddress& bd_addr) {
- do_in_main_thread(FROM_HERE, base::Bind(bta_dm_remove_device, bd_addr));
- return BTA_SUCCESS;
-}
-
-/*******************************************************************************
- *
- * Function BTA_GetEirService
- *
- * Description This function is called to get BTA service mask from EIR.
- *
- * Parameters p_eir - pointer of EIR significant part
- * p_services - return the BTA service mask
- *
- * Returns None
- *
- ******************************************************************************/
-extern const uint16_t bta_service_id_to_uuid_lkup_tbl[];
-void BTA_GetEirService(const uint8_t* p_eir, size_t eir_len,
- tBTA_SERVICE_MASK* p_services) {
- uint8_t xx, yy;
- uint8_t num_uuid, max_num_uuid = 32;
- uint8_t uuid_list[32 * Uuid::kNumBytes16];
- uint16_t* p_uuid16 = (uint16_t*)uuid_list;
- tBTA_SERVICE_MASK mask;
-
- get_btm_client_interface().eir.BTM_GetEirUuidList(
- p_eir, eir_len, Uuid::kNumBytes16, &num_uuid, uuid_list, max_num_uuid);
- for (xx = 0; xx < num_uuid; xx++) {
- mask = 1;
- for (yy = 0; yy < BTA_MAX_SERVICE_ID; yy++) {
- if (*(p_uuid16 + xx) == bta_service_id_to_uuid_lkup_tbl[yy]) {
- *p_services |= mask;
- break;
- }
- mask <<= 1;
- }
-
- /* for HSP v1.2 only device */
- if (*(p_uuid16 + xx) == UUID_SERVCLASS_HEADSET_HS)
- *p_services |= BTA_HSP_SERVICE_MASK;
-
- if (*(p_uuid16 + xx) == UUID_SERVCLASS_HDP_SOURCE)
- *p_services |= BTA_HL_SERVICE_MASK;
-
- if (*(p_uuid16 + xx) == UUID_SERVCLASS_HDP_SINK)
- *p_services |= BTA_HL_SERVICE_MASK;
- }
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmGetConnectionState
- *
- * Description Returns whether the remote device is currently connected.
- *
- * Returns 0 if the device is NOT connected.
- *
- ******************************************************************************/
-bool BTA_DmGetConnectionState(const RawAddress& bd_addr) {
- tBTA_DM_PEER_DEVICE* p_dev = bta_dm_find_peer_device(bd_addr);
- return (p_dev && p_dev->conn_state == BTA_DM_CONNECTED);
-}
-
-/*******************************************************************************
- * Device Identification (DI) Server Functions
- ******************************************************************************/
-/*******************************************************************************
- *
- * Function BTA_DmSetLocalDiRecord
- *
- * Description This function adds a DI record to the local SDP database.
- *
- * Returns BTA_SUCCESS if record set sucessfully, otherwise error code.
- *
- ******************************************************************************/
-tBTA_STATUS BTA_DmSetLocalDiRecord(tSDP_DI_RECORD* p_device_info,
- uint32_t* p_handle) {
- tBTA_STATUS status = BTA_FAILURE;
-
- if (bta_dm_di_cb.di_num < BTA_DI_NUM_MAX) {
- if (SDP_SetLocalDiRecord((tSDP_DI_RECORD*)p_device_info, p_handle) ==
- SDP_SUCCESS) {
- if (!p_device_info->primary_record) {
- bta_dm_di_cb.di_handle[bta_dm_di_cb.di_num] = *p_handle;
- bta_dm_di_cb.di_num++;
- }
-
- bta_sys_add_uuid(UUID_SERVCLASS_PNP_INFORMATION);
- status = BTA_SUCCESS;
- }
- }
-
- return status;
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmAddBleKey
- *
- * Description Add/modify LE device information. This function will be
- * normally called during host startup to restore all required
- * information stored in the NVRAM.
- *
- * Parameters: bd_addr - BD address of the peer
- * p_le_key - LE key values.
- * key_type - LE SMP key type.
- *
- * Returns BTA_SUCCESS if successful
- * BTA_FAIL if operation failed.
- *
- ******************************************************************************/
-void BTA_DmAddBleKey(const RawAddress& bd_addr, tBTA_LE_KEY_VALUE* p_le_key,
- tBTM_LE_KEY_TYPE key_type) {
- do_in_main_thread(
- FROM_HERE, base::Bind(bta_dm_add_blekey, bd_addr, *p_le_key, key_type));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmAddBleDevice
- *
- * Description Add a BLE device. This function will be normally called
- * during host startup to restore all required information
- * for a LE device stored in the NVRAM.
- *
- * Parameters: bd_addr - BD address of the peer
- * dev_type - Remote device's device type.
- * addr_type - LE device address type.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmAddBleDevice(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type,
- tBT_DEVICE_TYPE dev_type) {
- do_in_main_thread(FROM_HERE, base::Bind(bta_dm_add_ble_device, bd_addr,
- addr_type, dev_type));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmBlePasskeyReply
- *
- * Description Send BLE SMP passkey reply.
- *
- * Parameters: bd_addr - BD address of the peer
- * accept - passkey entry sucessful or declined.
- * passkey - passkey value, must be a 6 digit number,
- * can be lead by 0.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmBlePasskeyReply(const RawAddress& bd_addr, bool accept,
- uint32_t passkey) {
- do_in_main_thread(FROM_HERE, base::Bind(bta_dm_ble_passkey_reply, bd_addr,
- accept, accept ? passkey : 0));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmBleConfirmReply
- *
- * Description Send BLE SMP SC user confirmation reply.
- *
- * Parameters: bd_addr - BD address of the peer
- * accept - numbers to compare are the same or
- * different.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmBleConfirmReply(const RawAddress& bd_addr, bool accept) {
- do_in_main_thread(FROM_HERE,
- base::Bind(bta_dm_ble_confirm_reply, bd_addr, accept));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmBleSecurityGrant
- *
- * Description Grant security request access.
- *
- * Parameters: bd_addr - BD address of the peer
- * res - security grant status.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmBleSecurityGrant(const RawAddress& bd_addr,
- tBTA_DM_BLE_SEC_GRANT res) {
- do_in_main_thread(FROM_HERE, base::Bind(BTM_SecurityGrant, bd_addr, res));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmSetBlePrefConnParams
- *
- * Description This function is called to set the preferred connection
- * parameters when default connection parameter is not desired.
- *
- * Parameters: bd_addr - BD address of the peripheral
- * scan_interval - scan interval
- * scan_window - scan window
- * min_conn_int - minimum preferred connection interval
- * max_conn_int - maximum preferred connection interval
- * peripheral_latency - preferred peripheral latency
- * supervision_tout - preferred supervision timeout
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmSetBlePrefConnParams(const RawAddress& bd_addr,
- uint16_t min_conn_int, uint16_t max_conn_int,
- uint16_t peripheral_latency,
- uint16_t supervision_tout) {
- do_in_main_thread(
- FROM_HERE,
- base::Bind(bta_dm_ble_set_conn_params, bd_addr, min_conn_int,
- max_conn_int, peripheral_latency, supervision_tout));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmBleUpdateConnectionParam
- *
- * Description Update connection parameters, can only be used when
- * connection is up.
- *
- * Parameters: bd_addr - BD address of the peer
- * min_int - minimum connection interval,
- * [0x0004 ~ 0x4000]
- * max_int - maximum connection interval,
- * [0x0004 ~ 0x4000]
- * latency - peripheral latency [0 ~ 500]
- * timeout - supervision timeout [0x000a ~ 0xc80]
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmBleUpdateConnectionParams(const RawAddress& bd_addr,
- uint16_t min_int, uint16_t max_int,
- uint16_t latency, uint16_t timeout,
- uint16_t min_ce_len, uint16_t max_ce_len) {
- do_in_main_thread(
- FROM_HERE, base::Bind(bta_dm_ble_update_conn_params, bd_addr, min_int,
- max_int, latency, timeout, min_ce_len, max_ce_len));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmBleConfigLocalPrivacy
- *
- * Description Enable/disable privacy on the local device
- *
- * Parameters: privacy_enable - enable/disabe privacy on remote device.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmBleConfigLocalPrivacy(bool privacy_enable) {
- do_in_main_thread(
- FROM_HERE, base::Bind(bta_dm_ble_config_local_privacy, privacy_enable));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmBleGetEnergyInfo
- *
- * Description This function is called to obtain the energy info
- *
- * Parameters p_cmpl_cback - Command complete callback
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmBleGetEnergyInfo(tBTA_BLE_ENERGY_INFO_CBACK* p_cmpl_cback) {
- do_in_main_thread(FROM_HERE,
- base::Bind(bta_dm_ble_get_energy_info, p_cmpl_cback));
-}
-
-/** This function is to set maximum LE data packet size */
-void BTA_DmBleRequestMaxTxDataLength(const RawAddress& remote_device) {
- do_in_main_thread(FROM_HERE,
- base::Bind(bta_dm_ble_set_data_length, remote_device));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmSetEncryption
- *
- * Description This function is called to ensure that connection is
- * encrypted. Should be called only on an open connection.
- * Typically only needed for connections that first want to
- * bring up unencrypted links, then later encrypt them.
- *
- * Parameters: bd_addr - Address of the peer device
- * transport - transport of the link to be encruypted
- * p_callback - Pointer to callback function to indicat the
- * link encryption status
- * sec_act - This is the security action to indicate
- * what kind of BLE security level is required
- * for the BLE link if BLE is supported.
- * Note: This parameter is ignored for the
- * BR/EDR or if BLE is not supported.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmSetEncryption(const RawAddress& bd_addr, tBT_TRANSPORT transport,
- tBTA_DM_ENCRYPT_CBACK* p_callback,
- tBTM_BLE_SEC_ACT sec_act) {
- APPL_TRACE_API("%s", __func__);
- do_in_main_thread(FROM_HERE, base::Bind(bta_dm_set_encryption, bd_addr,
- transport, p_callback, sec_act));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmCloseACL
- *
- * Description This function force to close an ACL connection and remove
- * the device from the security database list of known devices.
- *
- * Parameters: bd_addr - Address of the peer device
- * remove_dev - remove device or not after link down
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmCloseACL(const RawAddress& bd_addr, bool remove_dev,
- tBT_TRANSPORT transport) {
- do_in_main_thread(
- FROM_HERE, base::Bind(bta_dm_close_acl, bd_addr, remove_dev, transport));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmBleObserve
- *
- * Description This procedure keep the device listening for advertising
- * events from a broadcast device.
- *
- * Parameters start: start or stop observe.
- *
- * Returns void
-
- *
- * Returns void.
- *
- ******************************************************************************/
-extern void BTA_DmBleObserve(bool start, uint8_t duration,
- tBTA_DM_SEARCH_CBACK* p_results_cb) {
- APPL_TRACE_API("%s:start = %d ", __func__, start);
- do_in_main_thread(
- FROM_HERE, base::Bind(bta_dm_ble_observe, start, duration, p_results_cb));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmBleScan
- *
- * Description Start or stop the scan procedure if it's not already started
- * with BTA_DmBleObserve().
- *
- * Parameters start: start or stop the scan procedure,
- * duration_sec: Duration of the scan. Continuous scan if 0 is
- * passed,
- *
- * Returns void
- *
- ******************************************************************************/
-extern void BTA_DmBleScan(bool start, uint8_t duration_sec) {
- APPL_TRACE_API("%s:start = %d ", __func__, start);
- do_in_main_thread(FROM_HERE,
- base::Bind(bta_dm_ble_scan, start, duration_sec));
-}
-
-/*******************************************************************************
- *
- * Function BTA_DmBleCsisObserve
- *
- * Description This procedure keeps the external observer listening for
- * advertising events from a CSIS grouped device.
- *
- * Parameters observe: enable or disable passive observe,
- * p_results_cb: Callback to be called with scan results,
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_DmBleCsisObserve(bool observe, tBTA_DM_SEARCH_CBACK* p_results_cb) {
- APPL_TRACE_API("%s:enable = %d ", __func__, observe);
- do_in_main_thread(FROM_HERE,
- base::Bind(bta_dm_ble_csis_observe, observe, p_results_cb));
-}
-
-/*******************************************************************************
- *
- * Function BTA_VendorInit
- *
- * Description This function initializes vendor specific
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_VendorInit(void) { APPL_TRACE_API("BTA_VendorInit"); }
diff --git a/bta/dm/bta_dm_cfg.cc b/bta/dm/bta_dm_cfg.cc
deleted file mode 100644
index d5c7575..0000000
--- a/bta/dm/bta_dm_cfg.cc
+++ /dev/null
@@ -1,603 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains compile-time configurable constants for the device
- * manager.
- *
- ******************************************************************************/
-
-#include <cstdint>
-
-#include "bt_target.h" // Must be first to define build configuration
-
-#include "bta/dm/bta_dm_int.h"
-#include "bta/include/bta_api.h"
-#include "bta/include/bta_hh_api.h"
-#include "bta/include/bta_jv_api.h"
-#include "bta/sys/bta_sys.h"
-#include "types/raw_address.h"
-
-/* page timeout in 625uS */
-#ifndef BTA_DM_PAGE_TIMEOUT
-#define BTA_DM_PAGE_TIMEOUT 8192
-#endif
-
-/* TRUE to avoid scatternet when av is streaming (be the central) */
-#ifndef BTA_DM_AVOID_SCATTER_A2DP
-#define BTA_DM_AVOID_SCATTER_A2DP TRUE
-#endif
-
-/* For Insight, PM cfg lookup tables are runtime configurable (to allow tweaking
- * of params for power consumption measurements) */
-#ifndef BTE_SIM_APP
-#define tBTA_DM_PM_TYPE_QUALIFIER const
-#else
-#define tBTA_DM_PM_TYPE_QUALIFIER
-#endif
-
-const tBTA_DM_CFG bta_dm_cfg = {
- /* mobile phone COD */
- BTA_DM_COD,
- /* page timeout in 625uS */
- BTA_DM_PAGE_TIMEOUT,
- /* true to avoid scatternet when av is streaming (be the central) */
- BTA_DM_AVOID_SCATTER_A2DP};
-
-#ifndef BTA_DM_SCATTERNET
-/* By default, allow partial scatternet */
-#define BTA_DM_SCATTERNET BTA_DM_PARTIAL_SCATTERNET
-#endif
-
-#ifndef BTA_HH_ROLE
-/* By default, do not specify HH role (backward compatibility) */
-#define BTA_HH_ROLE BTA_ANY_ROLE
-#endif
-
-#ifndef BTA_PANU_ROLE
-/* By default, AV role (backward BTA_CENTRAL_ROLE_PREF) */
-#define BTA_PANU_ROLE BTA_PERIPHERAL_ROLE_ONLY
-#endif
-#define BTA_DM_NUM_RM_ENTRY 6
-
-/* appids for PAN used by insight sample application
- these have to be same as defined in btui_int.h */
-#define BTUI_PAN_ID_PANU 0
-#define BTUI_PAN_ID_NAP 1
-#define BTUI_PAN_ID_GN 2
-
-/* First element is always for SYS:
- app_id = # of entries table, cfg is
- device scatternet support */
-const tBTA_DM_RM bta_dm_rm_cfg[] = {
- {BTA_ID_SYS, BTA_DM_NUM_RM_ENTRY, BTA_DM_SCATTERNET},
- {BTA_ID_PAN, BTUI_PAN_ID_NAP, BTA_ANY_ROLE},
- {BTA_ID_PAN, BTUI_PAN_ID_GN, BTA_ANY_ROLE},
- {BTA_ID_PAN, BTA_APP_ID_PAN_MULTI, BTA_CENTRAL_ROLE_ONLY},
- {BTA_ID_PAN, BTUI_PAN_ID_PANU, BTA_PANU_ROLE},
- {BTA_ID_HH, BTA_ALL_APP_ID, BTA_HH_ROLE},
- {BTA_ID_AV, BTA_ALL_APP_ID, BTA_CENTRAL_ROLE_PREF}};
-
-const tBTA_DM_CFG* p_bta_dm_cfg = &bta_dm_cfg;
-
-const tBTA_DM_RM* p_bta_dm_rm_cfg = &bta_dm_rm_cfg[0];
-
-#define BTA_DM_NUM_PM_ENTRY \
- 25 /* number of entries in bta_dm_pm_cfg except the first */
-#define BTA_DM_NUM_PM_SPEC 16 /* number of entries in bta_dm_pm_spec */
-
-tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_CFG
- bta_dm_pm_cfg[BTA_DM_NUM_PM_ENTRY + 1] = {
- {BTA_ID_SYS, BTA_DM_NUM_PM_ENTRY,
- 0}, /* reserved: specifies length of this table. */
- {BTA_ID_AG, BTA_ALL_APP_ID,
- 0}, /* ag uses first spec table for app id 0 */
- {BTA_ID_CT, 1, 1}, /* ct (BTA_ID_CT,APP ID=1) spec table */
- {BTA_ID_CG, BTA_ALL_APP_ID, 1}, /* cg resue ct spec table */
- {BTA_ID_DG, BTA_ALL_APP_ID, 2}, /* dg spec table */
- {BTA_ID_AV, BTA_ALL_APP_ID, 4}, /* av spec table */
- {BTA_ID_FTC, BTA_ALL_APP_ID, 7}, /* ftc spec table */
- {BTA_ID_FTS, BTA_ALL_APP_ID, 8}, /* fts spec table */
- {BTA_ID_HD, BTA_ALL_APP_ID, 3}, /* hd spec table */
- {BTA_ID_HH, BTA_HH_APP_ID_JOY, 5}, /* app BTA_HH_APP_ID_JOY,
- similar to hh spec table */
- {BTA_ID_HH, BTA_HH_APP_ID_GPAD, 5}, /* app BTA_HH_APP_ID_GPAD,
- similar to hh spec table */
- {BTA_ID_HH, BTA_ALL_APP_ID, 6}, /* hh spec table */
- {BTA_ID_PBC, BTA_ALL_APP_ID, 2}, /* reuse dg spec table */
- {BTA_ID_PBS, BTA_ALL_APP_ID, 8}, /* reuse fts spec table */
- {BTA_ID_OPC, BTA_ALL_APP_ID, 7}, /* reuse ftc spec table */
- {BTA_ID_OPS, BTA_ALL_APP_ID, 8}, /* reuse fts spec table */
- {BTA_ID_MSE, BTA_ALL_APP_ID, 8}, /* reuse fts spec table */
- {BTA_ID_JV, BTA_JV_PM_ID_1,
- 7}, /* app BTA_JV_PM_ID_1, reuse ftc spec table */
- {BTA_ID_JV, BTA_ALL_APP_ID, 8}, /* reuse fts spec table */
- {BTA_ID_HL, BTA_ALL_APP_ID, 9}, /* reuse fts spec table */
- {BTA_ID_PAN, BTUI_PAN_ID_PANU, 10}, /* PANU spec table */
- {BTA_ID_PAN, BTUI_PAN_ID_NAP, 11}, /* NAP spec table */
- {BTA_ID_HS, BTA_ALL_APP_ID, 12}, /* HS spec table */
- {BTA_ID_GATTC, BTA_ALL_APP_ID, 14}, /* gattc spec table */
- {BTA_ID_GATTS, BTA_ALL_APP_ID, 15} /* gatts spec table */
-};
-
-tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
- /* AG : 0 */
- {(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
- (BTA_DM_PM_SSR2), /* the SSR entry */
- {
- {{BTA_DM_PM_SNIFF_A2DP_IDX, 7000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_SNIFF_SCO_OPEN_IDX, 7000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
- {{BTA_DM_PM_SNIFF_A2DP_IDX, 7000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
- {{BTA_DM_PM_SNIFF_A2DP_IDX, 7000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
- {{BTA_DM_PM_RETRY, 7000},
- {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
- }},
-
- /* CT, CG : 1 */
- {(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
- (BTA_DM_PM_SSR2), /* the SSR entry */
- {
- {{BTA_DM_PM_PARK, 5000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* conn open park */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_SNIFF_A2DP_IDX, 5000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* sco open sniff */
- {{BTA_DM_PM_PARK, 5000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* sco close park */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
- {{BTA_DM_PM_RETRY, 5000},
- {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
- }},
-
- /* DG, PBC : 2 */
- {(BTA_DM_PM_ACTIVE), /* no power saving mode allowed */
- (BTA_DM_PM_SSR2), /* the SSR entry */
- {
- {{BTA_DM_PM_SNIFF, 5000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
- {{BTA_DM_PM_SNIFF, 1000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
- {{BTA_DM_PM_NO_ACTION, 0},
- {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
- }},
-
- /* HD : 3 */
- {(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
- (BTA_DM_PM_SSR3), /* the SSR entry */
- {
- {{BTA_DM_PM_SNIFF_HD_ACTIVE_IDX, 5000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
- {{BTA_DM_PM_SNIFF_HD_IDLE_IDX, 5000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
- {{BTA_DM_PM_SNIFF_HD_ACTIVE_IDX, 0},
- {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
- {{BTA_DM_PM_NO_ACTION, 0},
- {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
- }},
-
- /* AV : 4 */
- {(BTA_DM_PM_SNIFF), /* allow sniff */
- (BTA_DM_PM_SSR2), /* the SSR entry */
- {
- {{BTA_DM_PM_SNIFF_A2DP_IDX, 7000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
- {{BTA_DM_PM_SNIFF_A2DP_IDX, 7000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
- {{BTA_DM_PM_NO_ACTION, 0},
- {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
- }},
-
- /* HH for joysticks and gamepad : 5 */
- {(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
- (BTA_DM_PM_SSR1), /* the SSR entry */
- {
- {{BTA_DM_PM_SNIFF6, BTA_DM_PM_HH_OPEN_DELAY},
- {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
- {{BTA_DM_PM_NO_ACTION, 0},
- {BTA_DM_PM_NO_ACTION, 0}}, /* sco close, used for HH suspend */
- {{BTA_DM_PM_SNIFF6, BTA_DM_PM_HH_IDLE_DELAY},
- {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
- {{BTA_DM_PM_SNIFF6, BTA_DM_PM_HH_ACTIVE_DELAY},
- {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
- {{BTA_DM_PM_NO_ACTION, 0},
- {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
- }},
-
- /* HH : 6 */
- {(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
- (BTA_DM_PM_SSR1), /* the SSR entry */
- {
- {{BTA_DM_PM_SNIFF_HH_OPEN_IDX, BTA_DM_PM_HH_OPEN_DELAY},
- {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
- {{BTA_DM_PM_NO_ACTION, 0},
- {BTA_DM_PM_NO_ACTION, 0}}, /* sco close, used for HH suspend */
- {{BTA_DM_PM_SNIFF_HH_IDLE_IDX, BTA_DM_PM_HH_IDLE_DELAY},
- {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
- {{BTA_DM_PM_SNIFF_HH_ACTIVE_IDX, BTA_DM_PM_HH_ACTIVE_DELAY},
- {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
- {{BTA_DM_PM_NO_ACTION, 0},
- {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
- }},
-
- /* FTC, OPC, JV : 7 */
- {(BTA_DM_PM_SNIFF), /* allow sniff */
- (BTA_DM_PM_SSR2), /* the SSR entry */
- {
- {{BTA_DM_PM_ACTIVE, 0},
- {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
- {{BTA_DM_PM_SNIFF_A2DP_IDX, BTA_FTC_IDLE_TO_SNIFF_DELAY_MS},
- {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
- {{BTA_DM_PM_NO_ACTION, 0},
- {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
- }},
-
- /* FTS, PBS, OPS, MSE, BTA_JV_PM_ID_1 : 8 */
- {(BTA_DM_PM_SNIFF), /* allow sniff */
- (BTA_DM_PM_SSR2), /* the SSR entry */
- {
- {{BTA_DM_PM_ACTIVE, 0},
- {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
- {{BTA_DM_PM_SNIFF_A2DP_IDX, BTA_FTS_OPS_IDLE_TO_SNIFF_DELAY_MS},
- {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
- {{BTA_DM_PM_NO_ACTION, 0},
- {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
- }},
-
- /* HL : 9 */
- {(BTA_DM_PM_SNIFF), /* allow sniff */
- (BTA_DM_PM_SSR2), /* the SSR entry */
- {
- {{BTA_DM_PM_SNIFF_A2DP_IDX, 5000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_NO_ACTION, 0},
- {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
- {{BTA_DM_PM_NO_ACTION, 0},
- {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
- {{BTA_DM_PM_NO_ACTION, 0},
- {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
- }},
-
- /* PANU : 10 */
- {(BTA_DM_PM_SNIFF), /* allow sniff */
- (BTA_DM_PM_SSR2), /* the SSR entry */
- {
- {{BTA_DM_PM_ACTIVE, 0},
- {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
- {{BTA_DM_PM_SNIFF_A2DP_IDX, 5000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
- {{BTA_DM_PM_NO_ACTION, 0},
- {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
- }},
-
- /* NAP : 11 */
- {(BTA_DM_PM_SNIFF), /* allow sniff */
- (BTA_DM_PM_SSR2), /* the SSR entry */
- {
- {{BTA_DM_PM_ACTIVE, 0},
- {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
- {{BTA_DM_PM_SNIFF_A2DP_IDX, 5000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
-
- {{BTA_DM_PM_NO_ACTION, 0},
- {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
- }},
-
- /* HS : 12 */
- {(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
- (BTA_DM_PM_SSR2), /* the SSR entry */
- {
- {{BTA_DM_PM_SNIFF, 7000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_SNIFF3, 7000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
- {{BTA_DM_PM_SNIFF, 7000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
- {{BTA_DM_PM_SNIFF, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
- {{BTA_DM_PM_RETRY, 7000},
- {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
- }},
-
- /* AVK : 13 */
- {(BTA_DM_PM_SNIFF), /* allow sniff */
- (BTA_DM_PM_SSR2), /* the SSR entry */
- {
- {{BTA_DM_PM_SNIFF, 3000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
- {{BTA_DM_PM_SNIFF4, 3000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
- {{BTA_DM_PM_NO_ACTION, 0},
- {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
- }}
-
- /* GATTC : 14 */
- ,
- {(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
- (BTA_DM_PM_SSR2), /* the SSR entry */
- {
- {{BTA_DM_PM_SNIFF_A2DP_IDX, 10000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
- {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
- {{BTA_DM_PM_SNIFF_A2DP_IDX, 10000},
- {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
- {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
- {{BTA_DM_PM_RETRY, 5000},
- {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
- }}
- /* GATTS : 15 */
- ,
- {(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
- (BTA_DM_PM_SSR2), /* the SSR entry */
- {
- {{BTA_DM_PM_NO_PREF, 0},
- {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
- {{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
- {{BTA_DM_PM_RETRY, 5000},
- {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
- }}
-
-#ifdef BTE_SIM_APP /* For Insight builds only */
- /* Entries at the end of the pm_spec table are user-defined (runtime
- configurable),
- for power consumption experiments.
- Insight finds the first user-defined entry by looking for the first
- BTA_DM_PM_NO_PREF.
- The number of user_defined specs is defined by
- BTA_SWRAP_UD_PM_SPEC_COUNT */
- ,
- {BTA_DM_PM_NO_PREF}, /* pm_spec USER_DEFINED_0 */
- {BTA_DM_PM_NO_PREF} /* pm_spec USER_DEFINED_1 */
-#endif /* BTE_SIM_APP */
-};
-
-/* Please refer to the SNIFF table definitions in bta_api.h.
- *
- * Adding to or Modifying the Table
- * Additional sniff parameter entries can be added for BTA_DM_PM_SNIFF6 -
- * BTA_DM_PM_SNIFF7.
- * Overrides of additional table entries can be specified in bdroid_buildcfg.h.
- * If additional
- * sniff parameter entries are added or an override of an existing entry is
- * specified in
- * bdroid_buildcfg.h then the BTA_DM_PM_*_IDX defines in bta_api.h will need to
- * be match the new
- * ordering.
- *
- * Table Ordering
- * Sniff Table entries must be ordered from highest latency (biggest interval)
- * to lowest latency.
- * If there is a conflict among the connected services the setting with the
- * lowest latency will
- * be selected.
- */
-tBTA_DM_PM_TYPE_QUALIFIER tBTM_PM_PWR_MD bta_dm_pm_md[] = {
- /*
- * More sniff parameter entries can be added for
- * BTA_DM_PM_SNIFF3 - BTA_DM_PM_SNIFF7, if needed. When entries are added or
- * removed, BTA_DM_PM_PARK_IDX needs to be updated to reflect the actual
- * index
- * BTA_DM_PM_PARK_IDX is defined in bta_api.h and can be override by the
- * bdroid_buildcfg.h settings.
- * The SNIFF table entries must be in the order from highest latency
- * (biggest
- * interval) to lowest latency. If there's a conflict among the connected
- * services, the setting with lowest latency wins.
- */
- /* sniff modes: max interval, min interval, attempt, timeout */
- {BTA_DM_PM_SNIFF_MAX, BTA_DM_PM_SNIFF_MIN, BTA_DM_PM_SNIFF_ATTEMPT,
- BTA_DM_PM_SNIFF_TIMEOUT, BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF - A2DP */
- {BTA_DM_PM_SNIFF1_MAX, BTA_DM_PM_SNIFF1_MIN, BTA_DM_PM_SNIFF1_ATTEMPT,
- BTA_DM_PM_SNIFF1_TIMEOUT, BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF1 */
- {BTA_DM_PM_SNIFF2_MAX, BTA_DM_PM_SNIFF2_MIN, BTA_DM_PM_SNIFF2_ATTEMPT,
- BTA_DM_PM_SNIFF2_TIMEOUT,
- BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF2- HD idle */
- {BTA_DM_PM_SNIFF3_MAX, BTA_DM_PM_SNIFF3_MIN, BTA_DM_PM_SNIFF3_ATTEMPT,
- BTA_DM_PM_SNIFF3_TIMEOUT,
- BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF3- SCO open */
- {BTA_DM_PM_SNIFF4_MAX, BTA_DM_PM_SNIFF4_MIN, BTA_DM_PM_SNIFF4_ATTEMPT,
- BTA_DM_PM_SNIFF4_TIMEOUT,
- BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF4- HD active */
- {BTA_DM_PM_SNIFF5_MAX, BTA_DM_PM_SNIFF5_MIN, BTA_DM_PM_SNIFF5_ATTEMPT,
- BTA_DM_PM_SNIFF5_TIMEOUT,
- BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF5- HD active */
- {BTA_DM_PM_SNIFF6_MAX, BTA_DM_PM_SNIFF6_MIN, BTA_DM_PM_SNIFF6_ATTEMPT,
- BTA_DM_PM_SNIFF6_TIMEOUT,
- BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF6- HD active */
- {BTA_DM_PM_PARK_MAX, BTA_DM_PM_PARK_MIN, BTA_DM_PM_PARK_ATTEMPT,
- BTA_DM_PM_PARK_TIMEOUT, BTM_PM_MD_PARK}
-
-#ifdef BTE_SIM_APP /* For Insight builds only */
- /* Entries at the end of the bta_dm_pm_md table are user-defined (runtime
- configurable),
- for power consumption experiments.
- Insight finds the first user-defined entry by looking for the first
- 'max=0'.
- The number of user_defined specs is defined by BTA_SWRAP_UD_PM_DM_COUNT
- */
- ,
- {0}, /* CONN_OPEN/SCO_CLOSE power mode settings for pm_spec USER_DEFINED_0
- */
- {0}, /* SCO_OPEN power mode settings for pm_spec USER_DEFINED_0 */
-
- {0}, /* CONN_OPEN/SCO_CLOSE power mode settings for pm_spec USER_DEFINED_1
- */
- {0} /* SCO_OPEN power mode settings for pm_spec USER_DEFINED_1 */
-#endif /* BTE_SIM_APP */
-};
-
-/* 0=max_lat -> no SSR */
-/* the smaller of the SSR max latency wins.
- * the entries in this table must be from highest latency (biggest interval) to
- * lowest latency */
-tBTA_DM_SSR_SPEC bta_dm_ssr_spec[] = {
- /*max_lat, min_rmt_to, min_loc_to*/
- {0, 0, 0, "no_ssr"}, /* BTA_DM_PM_SSR0 - do not use SSR */
- /* BTA_DM_PM_SSR1 - HH, can NOT share entry with any other profile, seting
- default max latency and min remote timeout as 0, and always read
- individual device preference from HH module */
- {0, 0, 2, "hid_host"},
- {1200, 2, 2, "sniff_capable"}, /* BTA_DM_PM_SSR2 - others (as long as sniff
- is allowed)*/
- {360, 160, 1600, "hid_device"}, /* BTA_DM_PM_SSR3 - HD */
- {1200, 65534, 65534, "a2dp"} /* BTA_DM_PM_SSR4 - A2DP streaming */
-};
-
-tBTA_DM_SSR_SPEC* p_bta_dm_ssr_spec = &bta_dm_ssr_spec[0];
-
-const tBTA_DM_PM_CFG* p_bta_dm_pm_cfg = &bta_dm_pm_cfg[0];
-const tBTA_DM_PM_SPEC* p_bta_dm_pm_spec = &bta_dm_pm_spec[0];
-const tBTM_PM_PWR_MD* p_bta_dm_pm_md = &bta_dm_pm_md[0];
-
-/* The performance impact of EIR packet size
- *
- * When BTM_EIR_DEFAULT_FEC_REQUIRED is true,
- * 1 to 17 bytes, DM1 is used and most robust.
- * 18 to 121 bytes, DM3 is used but impacts inquiry scan time with large number
- * of devices.(almost double with 150 users)
- * 122 to 224 bytes, DM5 is used but cause quite big performance loss even with
- * small number of users. so it is not recommended.
- * 225 to 240 bytes, DH5 is used without FEC but it not recommended.
- * (same reason of DM5)
- *
- * When BTM_EIR_DEFAULT_FEC_REQUIRED is false,
- * 1 to 27 bytes, DH1 is used but only robust at short range.
- * 28 to 183 bytes, DH3 is used but only robust at short range and impacts
- * inquiry
- * scan time with large number of devices.
- * 184 to 240 bytes, DH5 is used but it not recommended.
-*/
-
-#if (BTA_EIR_CANNED_UUID_LIST == TRUE)
-/* for example */
-const uint8_t bta_dm_eir_uuid16_list[] = {
- 0x08, 0x11, /* Headset */
- 0x1E, 0x11, /* Handsfree */
- 0x0E, 0x11, /* AV Remote Control */
- 0x0B, 0x11, /* Audio Sink */
-};
-#endif // BTA_EIR_CANNED_UUID_LIST
-
-/* Extended Inquiry Response */
-const tBTA_DM_EIR_CONF bta_dm_eir_cfg = {
- 50, /* minimum length of local name when it is shortened */
- /* if length of local name is longer than this and EIR has not enough */
- /* room for all UUID list then local name is shortened to this length */
-#if (BTA_EIR_CANNED_UUID_LIST == TRUE)
- 8, (uint8_t*)bta_dm_eir_uuid16_list,
-#else // BTA_EIR_CANNED_UUID_LIST
- {
- /* mask of UUID list in EIR */
- 0xFFFFFFFF, /* LSB is the first UUID of the first 32 UUIDs in
- BTM_EIR_UUID_LKUP_TBL */
- 0xFFFFFFFF /* LSB is the first UUID of the next 32 UUIDs in
- BTM_EIR_UUID_LKUP_TBL */
- /* BTM_EIR_UUID_LKUP_TBL can be overrided */
- },
-#endif // BTA_EIR_CANNED_UUID_LIST
- NULL, /* Inquiry TX power */
- 0, /* length of flags in bytes */
- NULL, /* flags for EIR */
- 0, /* length of manufacturer specific in bytes */
- NULL, /* manufacturer specific */
- 0, /* length of additional data in bytes */
- NULL /* additional data */
-};
-const tBTA_DM_EIR_CONF* p_bta_dm_eir_cfg = &bta_dm_eir_cfg;
diff --git a/bta/dm/bta_dm_ci.cc b/bta/dm/bta_dm_ci.cc
deleted file mode 100644
index ea81524..0000000
--- a/bta/dm/bta_dm_ci.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the API implementation file for the BTA device manager.
- *
- ******************************************************************************/
-#include <base/bind.h>
-#include <memory>
-
-#include "bta/dm/bta_dm_int.h"
-#include "stack/include/bt_types.h"
-#include "stack/include/btu.h" // do_in_main_thread
-#include "types/raw_address.h"
-
-/*******************************************************************************
- *
- * Function bta_dm_ci_rmt_oob
- *
- * Description This function must be called in response to function
- * bta_dm_co_rmt_oob() to provide the OOB data associated
- * with the remote device.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_ci_rmt_oob(bool accept, const RawAddress& bd_addr, const Octet16& c,
- const Octet16& r) {
- std::unique_ptr<tBTA_DM_CI_RMT_OOB> msg =
- std::make_unique<tBTA_DM_CI_RMT_OOB>();
-
- msg->bd_addr = bd_addr;
- msg->accept = accept;
- msg->c = c;
- msg->r = r;
-
- do_in_main_thread(FROM_HERE,
- base::Bind(bta_dm_ci_rmt_oob_act, base::Passed(&msg)));
-}
-
diff --git a/bta/dm/bta_dm_int.h b/bta/dm/bta_dm_int.h
deleted file mode 100644
index 02d25eb..0000000
--- a/bta/dm/bta_dm_int.h
+++ /dev/null
@@ -1,563 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the private interface file for the BTA device manager.
- *
- ******************************************************************************/
-#ifndef BTA_DM_INT_H
-#define BTA_DM_INT_H
-
-#include <base/strings/stringprintf.h>
-
-#include <memory>
-#include <string>
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bta/include/bta_api.h"
-#include "bta/include/bta_gatt_api.h"
-#include "bta/sys/bta_sys.h"
-#include "main/shim/dumpsys.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/bt_octets.h"
-#include "types/bluetooth/uuid.h"
-#include "types/raw_address.h"
-
-#ifndef CASE_RETURN_TEXT
-#define CASE_RETURN_TEXT(code) \
- case code: \
- return #code
-#endif
-
-/*****************************************************************************
- * Constants and data types
- ****************************************************************************/
-
-#define BTA_COPY_DEVICE_CLASS(coddst, codsrc) \
- { \
- ((uint8_t*)(coddst))[0] = ((uint8_t*)(codsrc))[0]; \
- ((uint8_t*)(coddst))[1] = ((uint8_t*)(codsrc))[1]; \
- ((uint8_t*)(coddst))[2] = ((uint8_t*)(codsrc))[2]; \
- }
-
-#define BTA_DM_MSG_LEN 50
-
-#define BTA_SERVICE_ID_TO_SERVICE_MASK(id) (1 << (id))
-
-/* DM search events */
-enum {
- /* DM search API events */
- BTA_DM_API_SEARCH_EVT = BTA_SYS_EVT_START(BTA_ID_DM_SEARCH),
- BTA_DM_API_DISCOVER_EVT,
- BTA_DM_INQUIRY_CMPL_EVT,
- BTA_DM_REMT_NAME_EVT,
- BTA_DM_SDP_RESULT_EVT,
- BTA_DM_SEARCH_CMPL_EVT,
- BTA_DM_DISCOVERY_RESULT_EVT,
- BTA_DM_DISC_CLOSE_TOUT_EVT,
- BTA_DM_API_QUEUE_SEARCH_EVT,
- BTA_DM_API_QUEUE_DISCOVER_EVT
-};
-
-/* data type for BTA_DM_API_SEARCH_EVT and BTA_DM_API_QUEUE_SEARCH_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- tBTA_SERVICE_MASK services;
- tBTA_DM_SEARCH_CBACK* p_cback;
-} tBTA_DM_API_SEARCH;
-
-/* data type for BTA_DM_API_DISCOVER_EVT and BTA_DM_API_QUEUE_DISCOVER_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- RawAddress bd_addr;
- tBTA_DM_SEARCH_CBACK* p_cback;
- tBT_TRANSPORT transport;
-} tBTA_DM_API_DISCOVER;
-
-typedef struct {
- RawAddress bd_addr;
- bool accept;
- uint8_t pin_len;
- uint8_t p_pin[PIN_CODE_LEN];
-} tBTA_DM_API_PIN_REPLY;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- RawAddress bd_addr;
- tBTM_IO_CAP io_cap;
- tBTM_OOB_DATA oob_data;
- tBTM_AUTH_REQ auth_req;
-} tBTA_DM_CI_IO_REQ;
-
-typedef struct {
- RawAddress bd_addr;
- Octet16 c;
- Octet16 r;
- bool accept;
-} tBTA_DM_CI_RMT_OOB;
-
-/* data type for BTA_DM_REMT_NAME_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- tBTA_DM_SEARCH result;
-} tBTA_DM_REM_NAME;
-
-/* data type for tBTA_DM_DISC_RESULT */
-typedef struct {
- BT_HDR_RIGID hdr;
- tBTA_DM_SEARCH result;
-} tBTA_DM_DISC_RESULT;
-
-/* data type for BTA_DM_INQUIRY_CMPL_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- uint8_t num;
-} tBTA_DM_INQUIRY_CMPL;
-
-/* data type for BTA_DM_SDP_RESULT_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- uint16_t sdp_result;
-} tBTA_DM_SDP_RESULT;
-
-typedef struct {
- RawAddress bd_addr;
- DEV_CLASS dc;
- LinkKey link_key;
- uint8_t key_type;
- bool link_key_known;
- bool dc_known;
- BD_NAME bd_name;
- uint8_t pin_length;
-} tBTA_DM_API_ADD_DEVICE;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- bool enable;
-} tBTA_DM_API_BLE_FEATURE;
-
-/* union of all data types */
-typedef union {
- /* GKI event buffer header */
- BT_HDR_RIGID hdr;
-
- tBTA_DM_API_SEARCH search;
-
- tBTA_DM_API_DISCOVER discover;
-
- tBTA_DM_REM_NAME rem_name;
-
- tBTA_DM_DISC_RESULT disc_result;
-
- tBTA_DM_INQUIRY_CMPL inq_cmpl;
-
- tBTA_DM_SDP_RESULT sdp_event;
-
-} tBTA_DM_MSG;
-
-#define BTA_DM_NUM_PEER_DEVICE 7
-
-typedef enum : uint8_t {
- BTA_DM_NOT_CONNECTED = 0,
- BTA_DM_CONNECTED = 1,
- BTA_DM_UNPAIRING = 2,
-} tBTA_DM_CONN_STATE;
-
-inline std::string bta_conn_state_text(tBTA_DM_CONN_STATE state) {
- switch (state) {
- CASE_RETURN_TEXT(BTA_DM_NOT_CONNECTED);
- CASE_RETURN_TEXT(BTA_DM_CONNECTED);
- CASE_RETURN_TEXT(BTA_DM_UNPAIRING);
- default:
- return std::string("UNKNOWN");
- }
-}
-
-typedef enum : uint8_t {
- BTA_DM_DI_NONE = 0x00, /* nothing special */
- BTA_DM_DI_SET_SNIFF = 0x01, /* set this bit if call BTM_SetPowerMode(sniff) */
- BTA_DM_DI_INT_SNIFF = 0x02, /* set this bit if call BTM_SetPowerMode(sniff) &
- enter sniff mode */
- BTA_DM_DI_ACP_SNIFF = 0x04, /* set this bit if peer init sniff */
- BTA_DM_DI_UNUSED = 0x08,
- BTA_DM_DI_USE_SSR = 0x10, /* set this bit if ssr is supported for this link */
- BTA_DM_DI_AV_ACTIVE = 0x20, /* set this bit if AV is active for this link */
-} tBTA_DM_DEV_INFO_BITMASK;
-typedef uint8_t tBTA_DM_DEV_INFO;
-
-inline std::string device_info_text(tBTA_DM_DEV_INFO info) {
- const char* const device_info_text[] = {
- ":set_sniff", ":int_sniff", ":acp_sniff",
- ":unused", ":use_ssr", ":av_active",
- };
-
- std::string s = base::StringPrintf("0x%02x", info);
- if (info == BTA_DM_DI_NONE) return s + std::string(":none");
- for (size_t i = 0; i < sizeof(device_info_text) / sizeof(device_info_text[0]);
- i++) {
- if (info & (1u << i)) s += std::string(device_info_text[i]);
- }
- return s;
-}
-
-/* set power mode request type */
-#define BTA_DM_PM_RESTART 1
-#define BTA_DM_PM_NEW_REQ 2
-#define BTA_DM_PM_EXECUTE 3
-typedef uint8_t tBTA_DM_PM_REQ;
-
-struct tBTA_DM_PEER_DEVICE {
- RawAddress peer_bdaddr;
- tBTA_DM_CONN_STATE conn_state;
- tBTA_PREF_ROLES pref_role;
- bool in_use;
-
- private:
- friend void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport);
- friend void bta_dm_pm_btm_status(const RawAddress& bd_addr,
- tBTM_PM_STATUS status, uint16_t value,
- tHCI_STATUS hci_status);
- friend void bta_dm_pm_sniff(struct tBTA_DM_PEER_DEVICE* p_peer_dev,
- uint8_t index);
- friend void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
- uint8_t app_id, const RawAddress& peer_addr);
- friend void handle_remote_features_complete(const RawAddress& bd_addr);
- tBTA_DM_DEV_INFO info;
-
- public:
- tBTA_DM_DEV_INFO Info() const { return info; }
-
- tBTA_DM_ENCRYPT_CBACK* p_encrypt_cback;
- tBTM_PM_STATUS prev_low; /* previous low power mode used */
- tBTA_DM_PM_ACTION pm_mode_attempted;
- tBTA_DM_PM_ACTION pm_mode_failed;
- bool remove_dev_pending;
- tBT_TRANSPORT transport;
-};
-
-/* structure to store list of
- active connections */
-typedef struct {
- tBTA_DM_PEER_DEVICE peer_device[BTA_DM_NUM_PEER_DEVICE];
- uint8_t count;
- uint8_t le_count;
-} tBTA_DM_ACTIVE_LINK;
-
-typedef struct {
- RawAddress peer_bdaddr;
- tBTA_SYS_ID id;
- uint8_t app_id;
- tBTA_SYS_CONN_STATUS state;
- bool new_request;
-
- std::string ToString() const {
- return base::StringPrintf(
- "peer:%s sys_name:%s app_id:%hhu state:%s new:request:%s",
- PRIVATE_ADDRESS(peer_bdaddr), BtaIdSysText(id).c_str(), app_id,
- bta_sys_conn_status_text(state).c_str(), logbool(new_request).c_str());
- }
-
-} tBTA_DM_SRVCS;
-
-#ifndef BTA_DM_NUM_CONN_SRVS
-#define BTA_DM_NUM_CONN_SRVS 30
-#endif
-
-typedef struct {
- uint8_t count;
- tBTA_DM_SRVCS conn_srvc[BTA_DM_NUM_CONN_SRVS];
-
-} tBTA_DM_CONNECTED_SRVCS;
-
-typedef struct {
-#define BTA_DM_PM_SNIFF_TIMER_IDX 0
-#define BTA_DM_PM_PARK_TIMER_IDX 1
-#define BTA_DM_PM_SUSPEND_TIMER_IDX 2
-#define BTA_DM_PM_MODE_TIMER_MAX 3
- /*
- * Keep three different timers for PARK, SNIFF and SUSPEND if TBFC is
- * supported.
- */
- alarm_t* timer[BTA_DM_PM_MODE_TIMER_MAX];
-
- uint8_t srvc_id[BTA_DM_PM_MODE_TIMER_MAX];
- uint8_t pm_action[BTA_DM_PM_MODE_TIMER_MAX];
- uint8_t active; /* number of active timer */
-
- RawAddress peer_bdaddr;
- bool in_use;
-} tBTA_PM_TIMER;
-
-extern tBTA_DM_CONNECTED_SRVCS bta_dm_conn_srvcs;
-
-#define BTA_DM_NUM_PM_TIMER 7
-
-/* DM control block */
-typedef struct {
- bool is_bta_dm_active;
- tBTA_DM_ACTIVE_LINK device_list;
- tBTA_DM_SEC_CBACK* p_sec_cback;
- tBTA_BLE_ENERGY_INFO_CBACK* p_energy_info_cback;
- uint16_t state;
- bool disabling;
- alarm_t* disable_timer;
- uint32_t wbt_sdp_handle; /* WIDCOMM Extensions SDP record handle */
- uint8_t wbt_scn; /* WIDCOMM Extensions SCN */
- uint8_t num_central_only;
- uint8_t pm_id;
- tBTA_PM_TIMER pm_timer[BTA_DM_NUM_PM_TIMER];
- uint8_t cur_av_count; /* current AV connecions */
- bool disable_pair_mode; /* disable pair mode or not */
- bool conn_paired_only; /* allow connectable to paired device only or not */
- tBTA_DM_API_SEARCH search_msg;
-
- /* Storage for pin code request parameters */
- RawAddress pin_bd_addr;
- DEV_CLASS pin_dev_class;
- tBTA_DM_SEC_EVT pin_evt;
- tBTM_IO_CAP loc_io_caps; /* IO Capabilities of local device */
- tBTM_IO_CAP rmt_io_caps; /* IO Capabilities of remote device */
- tBTM_AUTH_REQ loc_auth_req; /* Authentication required for local device */
- tBTM_AUTH_REQ rmt_auth_req;
- uint32_t num_val; /* the numeric value for comparison. If just_works, do not
- show this number to UI */
- bool just_works; /* true, if "Just Works" association model */
-#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
- /* store UUID list for EIR */
- uint32_t eir_uuid[BTM_EIR_SERVICE_ARRAY_SIZE];
-#if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
- tBTA_CUSTOM_UUID bta_custom_uuid[BTA_EIR_SERVER_NUM_CUSTOM_UUID];
-#endif
-
-#endif
-
- tBTA_DM_ENCRYPT_CBACK* p_encrypt_cback;
- alarm_t* switch_delay_timer;
-
-} tBTA_DM_CB;
-
-/* DM search control block */
-typedef struct {
- tBTA_DM_SEARCH_CBACK* p_search_cback;
- tBTM_INQ_INFO* p_btm_inq_info;
- tBTA_SERVICE_MASK services;
- tBTA_SERVICE_MASK services_to_search;
- tBTA_SERVICE_MASK services_found;
- tSDP_DISCOVERY_DB* p_sdp_db;
- uint16_t state;
- RawAddress peer_bdaddr;
- bool name_discover_done;
- BD_NAME peer_name;
- alarm_t* search_timer;
- uint8_t service_index;
- tBTA_DM_MSG* p_pending_search;
- fixed_queue_t* pending_discovery_queue;
- bool wait_disc;
- bool sdp_results;
- bluetooth::Uuid uuid;
- uint8_t peer_scn;
- tBT_TRANSPORT transport;
- tBTA_DM_SEARCH_CBACK* p_scan_cback;
- tBTA_DM_SEARCH_CBACK* p_csis_scan_cback;
- tGATT_IF client_if;
- uint8_t uuid_to_search;
- bool gatt_disc_active;
- uint16_t conn_id;
- alarm_t* gatt_close_timer; /* GATT channel close delay timer */
- RawAddress pending_close_bda; /* pending GATT channel remote device address */
-
-} tBTA_DM_SEARCH_CB;
-
-/* DI control block */
-typedef struct {
- uint8_t di_num; /* total local DI record number */
- uint32_t di_handle[BTA_DI_NUM_MAX]; /* local DI record handle, the first one
- is primary record */
-} tBTA_DM_DI_CB;
-
-/* DM search state */
-enum {
-
- BTA_DM_SEARCH_IDLE,
- BTA_DM_SEARCH_ACTIVE,
- BTA_DM_SEARCH_CANCELLING,
- BTA_DM_DISCOVER_ACTIVE
-
-};
-
-typedef struct {
- DEV_CLASS dev_class; /* local device class */
- uint16_t page_timeout; /* timeout for page in slots */
- bool avoid_scatter; /* true to avoid scatternet when av is streaming (be the
- central) */
-
-} tBTA_DM_CFG;
-
-extern const uint32_t bta_service_id_to_btm_srv_id_lkup_tbl[];
-
-typedef struct {
- uint8_t id;
- uint8_t app_id;
- uint8_t cfg;
-
-} tBTA_DM_RM;
-
-extern const tBTA_DM_CFG* p_bta_dm_cfg;
-extern const tBTA_DM_RM* p_bta_dm_rm_cfg;
-
-typedef struct {
- uint8_t id;
- uint8_t app_id;
- uint8_t spec_idx; /* index of spec table to use */
-
-} tBTA_DM_PM_CFG;
-
-typedef struct {
- tBTA_DM_PM_ACTION power_mode;
- uint16_t timeout;
-
-} tBTA_DM_PM_ACTN;
-
-typedef struct {
- uint8_t allow_mask; /* mask of sniff/hold/park modes to allow */
- uint8_t ssr; /* set SSR on conn open/unpark */
- tBTA_DM_PM_ACTN actn_tbl[BTA_DM_PM_NUM_EVTS][2];
-
-} tBTA_DM_PM_SPEC;
-
-typedef struct {
- uint16_t max_lat;
- uint16_t min_rmt_to;
- uint16_t min_loc_to;
- const char* name{nullptr};
-} tBTA_DM_SSR_SPEC;
-
-typedef struct {
- uint16_t manufacturer;
- uint16_t lmp_sub_version;
- uint8_t lmp_version;
-} tBTA_DM_LMP_VER_INFO;
-
-extern const uint16_t bta_service_id_to_uuid_lkup_tbl[];
-
-extern const tBTA_DM_PM_CFG* p_bta_dm_pm_cfg;
-extern const tBTA_DM_PM_SPEC* p_bta_dm_pm_spec;
-extern const tBTM_PM_PWR_MD* p_bta_dm_pm_md;
-extern tBTA_DM_SSR_SPEC* p_bta_dm_ssr_spec;
-
-/* update dynamic BRCM Aware EIR data */
-extern const tBTA_DM_EIR_CONF bta_dm_eir_cfg;
-extern const tBTA_DM_EIR_CONF* p_bta_dm_eir_cfg;
-
-/* DM control block */
-extern tBTA_DM_CB bta_dm_cb;
-
-/* DM search control block */
-extern tBTA_DM_SEARCH_CB bta_dm_search_cb;
-
-/* DI control block */
-extern tBTA_DM_DI_CB bta_dm_di_cb;
-
-extern bool bta_dm_search_sm_execute(BT_HDR_RIGID* p_msg);
-extern void bta_dm_search_sm_disable(void);
-
-extern void bta_dm_enable(tBTA_DM_SEC_CBACK*);
-extern void bta_dm_disable();
-extern void bta_dm_init_cb(void);
-extern void bta_dm_deinit_cb(void);
-extern void bta_dm_set_dev_name(const std::vector<uint8_t>&);
-extern void bta_dm_set_visibility(tBTA_DM_DISC, tBTA_DM_CONN);
-extern void bta_dm_set_scan_config(tBTA_DM_MSG* p_data);
-extern void bta_dm_vendor_spec_command(tBTA_DM_MSG* p_data);
-extern void bta_dm_bond(const RawAddress&, tBLE_ADDR_TYPE, tBT_TRANSPORT,
- tBT_DEVICE_TYPE);
-extern void bta_dm_bond_cancel(const RawAddress&);
-extern void bta_dm_pin_reply(std::unique_ptr<tBTA_DM_API_PIN_REPLY> msg);
-extern void bta_dm_add_device(std::unique_ptr<tBTA_DM_API_ADD_DEVICE> msg);
-extern void bta_dm_remove_device(const RawAddress& bd_addr);
-extern void bta_dm_close_acl(const RawAddress&, bool, tBT_TRANSPORT);
-
-extern void bta_dm_pm_btm_status(const RawAddress&, tBTM_PM_STATUS, uint16_t,
- tHCI_STATUS);
-extern void bta_dm_pm_timer(const RawAddress&, tBTA_DM_PM_ACTION);
-extern void bta_dm_add_ampkey(tBTA_DM_MSG* p_data);
-
-extern void bta_dm_add_blekey(const RawAddress& bd_addr,
- tBTA_LE_KEY_VALUE blekey,
- tBTM_LE_KEY_TYPE key_type);
-extern void bta_dm_add_ble_device(const RawAddress& bd_addr,
- tBLE_ADDR_TYPE addr_type,
- tBT_DEVICE_TYPE dev_type);
-extern void bta_dm_ble_passkey_reply(const RawAddress& bd_addr, bool accept,
- uint32_t passkey);
-extern void bta_dm_ble_confirm_reply(const RawAddress&, bool);
-extern void bta_dm_ble_set_conn_params(const RawAddress&, uint16_t, uint16_t,
- uint16_t, uint16_t);
-extern void bta_dm_close_gatt_conn(tBTA_DM_MSG* p_data);
-extern void bta_dm_ble_observe(bool, uint8_t, tBTA_DM_SEARCH_CBACK*);
-extern void bta_dm_ble_scan(bool, uint8_t);
-extern void bta_dm_ble_csis_observe(bool, tBTA_DM_SEARCH_CBACK*);
-extern void bta_dm_ble_update_conn_params(const RawAddress&, uint16_t, uint16_t,
- uint16_t, uint16_t, uint16_t,
- uint16_t);
-extern void bta_dm_ble_config_local_privacy(bool);
-
-extern void bta_dm_ble_set_data_length(const RawAddress& bd_addr);
-
-extern void bta_dm_ble_get_energy_info(tBTA_BLE_ENERGY_INFO_CBACK*);
-
-extern void bta_dm_set_encryption(const RawAddress&, tBT_TRANSPORT,
- tBTA_DM_ENCRYPT_CBACK*, tBTM_BLE_SEC_ACT);
-extern void bta_dm_confirm(const RawAddress&, bool);
-
-extern void bta_dm_ci_rmt_oob_act(std::unique_ptr<tBTA_DM_CI_RMT_OOB> msg);
-
-extern void bta_dm_init_pm(void);
-extern void bta_dm_disable_pm(void);
-
-extern uint8_t bta_dm_get_av_count(void);
-extern void bta_dm_search_start(tBTA_DM_MSG* p_data);
-extern void bta_dm_search_cancel();
-extern void bta_dm_discover(tBTA_DM_MSG* p_data);
-extern void bta_dm_inq_cmpl(uint8_t num);
-extern void bta_dm_rmt_name(tBTA_DM_MSG* p_data);
-extern void bta_dm_sdp_result(tBTA_DM_MSG* p_data);
-extern void bta_dm_search_cmpl();
-extern void bta_dm_free_sdp_db();
-extern void bta_dm_disc_result(tBTA_DM_MSG* p_data);
-extern void bta_dm_search_result(tBTA_DM_MSG* p_data);
-extern void bta_dm_discovery_cmpl(tBTA_DM_MSG* p_data);
-extern void bta_dm_queue_search(tBTA_DM_MSG* p_data);
-extern void bta_dm_queue_disc(tBTA_DM_MSG* p_data);
-extern void bta_dm_execute_queued_request();
-extern bool bta_dm_is_search_request_queued();
-extern void bta_dm_search_clear_queue();
-extern void bta_dm_search_cancel_notify();
-extern void bta_dm_disc_rmt_name(tBTA_DM_MSG* p_data);
-extern tBTA_DM_PEER_DEVICE* bta_dm_find_peer_device(
- const RawAddress& peer_addr);
-
-uint8_t bta_dm_search_get_state();
-void bta_dm_search_set_state(uint8_t state);
-
-void bta_dm_eir_update_uuid(uint16_t uuid16, bool adding);
-void bta_dm_eir_update_cust_uuid(const tBTA_CUSTOM_UUID &curr, bool adding);
-
-#undef CASE_RETURN_TEXT
-#endif /* BTA_DM_INT_H */
diff --git a/bta/dm/bta_dm_main.cc b/bta/dm/bta_dm_main.cc
deleted file mode 100644
index 523831b..0000000
--- a/bta/dm/bta_dm_main.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the main implementation file for the BTA device manager.
- *
- ******************************************************************************/
-
-#include "bt_trace.h"
-#include "bta/dm/bta_dm_int.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/bt_types.h"
-
-/*****************************************************************************
- * Constants and types
- ****************************************************************************/
-
-tBTA_DM_CB bta_dm_cb;
-tBTA_DM_SEARCH_CB bta_dm_search_cb;
-tBTA_DM_DI_CB bta_dm_di_cb;
-
-/*******************************************************************************
- *
- * Function bta_dm_sm_search_disable
- *
- * Description unregister BTA SEARCH DM
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_search_sm_disable() { bta_sys_deregister(BTA_ID_DM_SEARCH); }
-
-void bta_dm_search_set_state(uint8_t state) { bta_dm_search_cb.state = state; }
-uint8_t bta_dm_search_get_state() { return bta_dm_search_cb.state; }
-
-/*******************************************************************************
- *
- * Function bta_dm_search_sm_execute
- *
- * Description State machine event handling function for DM
- *
- *
- * Returns void
- *
- ******************************************************************************/
-bool bta_dm_search_sm_execute(BT_HDR_RIGID* p_msg) {
- APPL_TRACE_EVENT("bta_dm_search_sm_execute state:%d, event:0x%x",
- bta_dm_search_cb.state, p_msg->event);
-
- tBTA_DM_MSG* message = (tBTA_DM_MSG*)p_msg;
- switch (bta_dm_search_cb.state) {
- case BTA_DM_SEARCH_IDLE:
- switch (p_msg->event) {
- case BTA_DM_API_SEARCH_EVT:
- bta_dm_search_set_state(BTA_DM_SEARCH_ACTIVE);
- bta_dm_search_start(message);
- break;
- case BTA_DM_API_DISCOVER_EVT:
- bta_dm_search_set_state(BTA_DM_DISCOVER_ACTIVE);
- bta_dm_discover(message);
- break;
- case BTA_DM_SDP_RESULT_EVT:
- bta_dm_free_sdp_db();
- break;
- case BTA_DM_DISC_CLOSE_TOUT_EVT:
- bta_dm_close_gatt_conn(message);
- break;
- case BTA_DM_API_QUEUE_SEARCH_EVT:
- bta_dm_queue_search(message);
- break;
- case BTA_DM_API_QUEUE_DISCOVER_EVT:
- bta_dm_queue_disc(message);
- break;
- }
- break;
- case BTA_DM_SEARCH_ACTIVE:
- switch (p_msg->event) {
- case BTA_DM_REMT_NAME_EVT:
- bta_dm_rmt_name(message);
- break;
- case BTA_DM_SDP_RESULT_EVT:
- bta_dm_sdp_result(message);
- break;
- case BTA_DM_SEARCH_CMPL_EVT:
- bta_dm_search_cmpl();
- break;
- case BTA_DM_DISCOVERY_RESULT_EVT:
- bta_dm_search_result(message);
- break;
- case BTA_DM_DISC_CLOSE_TOUT_EVT:
- bta_dm_close_gatt_conn(message);
- break;
- case BTA_DM_API_DISCOVER_EVT:
- case BTA_DM_API_QUEUE_DISCOVER_EVT:
- bta_dm_queue_disc(message);
- break;
- }
- break;
- case BTA_DM_SEARCH_CANCELLING:
- switch (p_msg->event) {
- case BTA_DM_API_SEARCH_EVT:
- case BTA_DM_API_QUEUE_SEARCH_EVT:
- bta_dm_queue_search(message);
- break;
- case BTA_DM_API_DISCOVER_EVT:
- case BTA_DM_API_QUEUE_DISCOVER_EVT:
- bta_dm_queue_disc(message);
- break;
- case BTA_DM_SDP_RESULT_EVT:
- case BTA_DM_REMT_NAME_EVT:
- case BTA_DM_SEARCH_CMPL_EVT:
- case BTA_DM_DISCOVERY_RESULT_EVT:
- bta_dm_search_set_state(BTA_DM_SEARCH_IDLE);
- bta_dm_free_sdp_db();
- bta_dm_search_cancel_notify();
- bta_dm_execute_queued_request();
- break;
- }
- break;
- case BTA_DM_DISCOVER_ACTIVE:
- switch (p_msg->event) {
- case BTA_DM_REMT_NAME_EVT:
- bta_dm_disc_rmt_name(message);
- break;
- case BTA_DM_SDP_RESULT_EVT:
- bta_dm_sdp_result(message);
- break;
- case BTA_DM_SEARCH_CMPL_EVT:
- bta_dm_search_cmpl();
- break;
- case BTA_DM_DISCOVERY_RESULT_EVT:
- bta_dm_disc_result(message);
- break;
- case BTA_DM_API_SEARCH_EVT:
- case BTA_DM_API_QUEUE_SEARCH_EVT:
- bta_dm_queue_search(message);
- break;
- case BTA_DM_API_DISCOVER_EVT:
- case BTA_DM_API_QUEUE_DISCOVER_EVT:
- bta_dm_queue_disc(message);
- break;
- }
- break;
- }
- return true;
-}
diff --git a/bta/dm/bta_dm_pm.cc b/bta/dm/bta_dm_pm.cc
deleted file mode 100644
index 7e0b4cc..0000000
--- a/bta/dm/bta_dm_pm.cc
+++ /dev/null
@@ -1,1114 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains the action functions for device manager state
- * machine.
- *
- ******************************************************************************/
-
-#include <base/bind.h>
-#include <cstdint>
-#include <mutex>
-
-#include "bta/dm/bta_dm_int.h"
-#include "bta/include/bta_api.h"
-#include "bta/include/bta_dm_api.h"
-#include "bta/sys/bta_sys.h"
-#include "device/include/controller.h"
-#include "main/shim/dumpsys.h"
-#include "osi/include/log.h"
-#include "stack/include/acl_api.h"
-#include "stack/include/btu.h" // do_in_main_thread
-#include "types/raw_address.h"
-
-static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
- uint8_t app_id, const RawAddress& peer_addr);
-static void bta_dm_pm_set_mode(const RawAddress& peer_addr,
- tBTA_DM_PM_ACTION pm_mode,
- tBTA_DM_PM_REQ pm_req);
-static void bta_dm_pm_timer_cback(void* data);
-static void bta_dm_pm_btm_cback(const RawAddress& bd_addr,
- tBTM_PM_STATUS status, uint16_t value,
- tHCI_STATUS hci_status);
-static bool bta_dm_pm_park(const RawAddress& peer_addr);
-void bta_dm_pm_sniff(tBTA_DM_PEER_DEVICE* p_peer_dev, uint8_t index);
-static bool bta_dm_pm_is_sco_active();
-static int bta_dm_get_sco_index();
-static void bta_dm_pm_stop_timer_by_index(tBTA_PM_TIMER* p_timer,
- uint8_t timer_idx);
-
-#if (BTA_HH_INCLUDED == TRUE)
-#include "../hh/bta_hh_int.h"
-/* BTA_DM_PM_SSR1 will be dedicated for HH SSR setting entry, no other profile
- * can use it */
-#define BTA_DM_PM_SSR_HH BTA_DM_PM_SSR1
-#endif
-static void bta_dm_pm_ssr(const RawAddress& peer_addr, int ssr);
-
-tBTA_DM_CONNECTED_SRVCS bta_dm_conn_srvcs;
-static std::recursive_mutex pm_timer_schedule_mutex;
-static std::recursive_mutex pm_timer_state_mutex;
-
-/*******************************************************************************
- *
- * Function bta_dm_init_pm
- *
- * Description Initializes the BT low power manager
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_init_pm(void) {
- memset(&bta_dm_conn_srvcs, 0x00, sizeof(bta_dm_conn_srvcs));
-
- /* if there are no power manger entries, so not register */
- if (p_bta_dm_pm_cfg[0].app_id != 0) {
- bta_sys_pm_register(bta_dm_pm_cback);
-
- BTM_PmRegister((BTM_PM_REG_SET), &bta_dm_cb.pm_id, bta_dm_pm_btm_cback);
- }
-
- /* Need to initialize all PM timer service IDs */
- for (int i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
- for (int j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++)
- bta_dm_cb.pm_timer[i].srvc_id[j] = BTA_ID_MAX;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_disable_pm
- *
- * Description Disable PM
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_disable_pm(void) {
- BTM_PmRegister(BTM_PM_DEREG, &bta_dm_cb.pm_id, bta_dm_pm_btm_cback);
-
- /*
- * Deregister the PM callback from the system handling to prevent
- * re-enabling the PM timers after this call if the callback is invoked.
- */
- bta_sys_pm_register(NULL);
-
- /* Need to stop all active timers. */
- for (int i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
- for (int j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
- bta_dm_pm_stop_timer_by_index(&bta_dm_cb.pm_timer[i], j);
- bta_dm_cb.pm_timer[i].pm_action[j] = BTA_DM_PM_NO_ACTION;
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_get_av_count
- *
- * Description Get the number of connected AV
- *
- *
- * Returns number of av connections
- *
- ******************************************************************************/
-uint8_t bta_dm_get_av_count(void) {
- uint8_t count = 0;
- for (int i = 0; i < bta_dm_conn_srvcs.count; i++) {
- if (bta_dm_conn_srvcs.conn_srvc[i].id == BTA_ID_AV) ++count;
- }
- return count;
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_pm_stop_timer
- *
- * Description stop a PM timer
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_pm_stop_timer(const RawAddress& peer_addr) {
- APPL_TRACE_DEBUG("%s: ", __func__);
-
- for (int i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
- if (bta_dm_cb.pm_timer[i].in_use &&
- bta_dm_cb.pm_timer[i].peer_bdaddr == peer_addr) {
- for (int j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
- bta_dm_pm_stop_timer_by_index(&bta_dm_cb.pm_timer[i], j);
- /*
- * TODO: For now, stopping the timer does not reset
- * pm_action[j].
- * The reason is because some of the internal logic that
- * (re)assigns the pm_action[] values is taking into account
- * the older value; e.g., see the pm_action[] assignment in
- * function bta_dm_pm_start_timer().
- * Such subtlety in the execution logic is error prone, and
- * should be eliminiated in the future.
- */
- }
- break;
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_pm_action_to_timer_idx
- *
- * Description convert power mode into timer index for each connected
- * device
- *
- *
- * Returns index of the power mode delay timer
- *
- ******************************************************************************/
-static uint8_t bta_pm_action_to_timer_idx(uint8_t pm_action) {
- if (pm_action == BTA_DM_PM_SUSPEND)
- return BTA_DM_PM_SUSPEND_TIMER_IDX;
- else if (pm_action == BTA_DM_PM_PARK)
- return BTA_DM_PM_PARK_TIMER_IDX;
- else if ((pm_action & BTA_DM_PM_SNIFF) == BTA_DM_PM_SNIFF)
- return BTA_DM_PM_SNIFF_TIMER_IDX;
-
- /* Active, no preference, no action and retry */
- return BTA_DM_PM_MODE_TIMER_MAX;
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_pm_stop_timer_by_mode
- *
- * Description stop a PM timer
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_pm_stop_timer_by_mode(const RawAddress& peer_addr,
- uint8_t power_mode) {
- const uint8_t timer_idx = bta_pm_action_to_timer_idx(power_mode);
- if (timer_idx == BTA_DM_PM_MODE_TIMER_MAX) return;
-
- for (int i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
- if (bta_dm_cb.pm_timer[i].in_use &&
- bta_dm_cb.pm_timer[i].peer_bdaddr == peer_addr) {
- if (bta_dm_cb.pm_timer[i].srvc_id[timer_idx] != BTA_ID_MAX) {
- bta_dm_pm_stop_timer_by_index(&bta_dm_cb.pm_timer[i], timer_idx);
- /*
- * TODO: Intentionally setting pm_action[timer_idx].
- * This assignment should be eliminated in the future - see the
- * pm_action[] related comment inside function
- * bta_dm_pm_stop_timer().
- */
- bta_dm_cb.pm_timer[i].pm_action[timer_idx] = power_mode;
- }
- break;
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_pm_stop_timer_by_srvc_id
- *
- * Description stop all timer started by the service ID.
- *
- *
- * Returns index of the power mode delay timer
- *
- ******************************************************************************/
-static void bta_dm_pm_stop_timer_by_srvc_id(const RawAddress& peer_addr,
- uint8_t srvc_id) {
- for (int i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
- if (bta_dm_cb.pm_timer[i].in_use &&
- bta_dm_cb.pm_timer[i].peer_bdaddr == peer_addr) {
- for (int j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
- if (bta_dm_cb.pm_timer[i].srvc_id[j] == srvc_id) {
- bta_dm_pm_stop_timer_by_index(&bta_dm_cb.pm_timer[i], j);
- bta_dm_cb.pm_timer[i].pm_action[j] = BTA_DM_PM_NO_ACTION;
- break;
- }
- }
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_pm_start_timer
- *
- * Description start a PM timer
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_pm_start_timer(tBTA_PM_TIMER* p_timer, uint8_t timer_idx,
- uint64_t timeout_ms, uint8_t srvc_id,
- uint8_t pm_action) {
- std::unique_lock<std::recursive_mutex> schedule_lock(pm_timer_schedule_mutex);
- std::unique_lock<std::recursive_mutex> state_lock(pm_timer_state_mutex);
- p_timer->in_use = true;
-
- if (p_timer->srvc_id[timer_idx] == BTA_ID_MAX) p_timer->active++;
-
- if (p_timer->pm_action[timer_idx] < pm_action)
- p_timer->pm_action[timer_idx] = pm_action;
-
- p_timer->srvc_id[timer_idx] = srvc_id;
- state_lock.unlock();
-
- alarm_set_on_mloop(p_timer->timer[timer_idx], timeout_ms,
- bta_dm_pm_timer_cback, p_timer->timer[timer_idx]);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_pm_stop_timer_by_index
- *
- * Description stop a PM timer
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_pm_stop_timer_by_index(tBTA_PM_TIMER* p_timer,
- uint8_t timer_idx) {
- if ((p_timer == NULL) || (timer_idx >= BTA_DM_PM_MODE_TIMER_MAX)) return;
-
- std::unique_lock<std::recursive_mutex> schedule_lock(pm_timer_schedule_mutex);
- std::unique_lock<std::recursive_mutex> state_lock(pm_timer_state_mutex);
- if (p_timer->srvc_id[timer_idx] == BTA_ID_MAX) {
- return;
- } /* The timer was not scheduled */
-
- ASSERT_LOG(p_timer->in_use,
- "Timer was not scheduled p_timer->srvc_id[timer_idx]:%hhu",
- p_timer->srvc_id[timer_idx]);
- ASSERT_LOG(p_timer->active > 0, "No tasks on timer are active");
-
- p_timer->srvc_id[timer_idx] = BTA_ID_MAX;
- /* NOTE: pm_action[timer_idx] intentionally not reset */
-
- p_timer->active--;
- if (p_timer->active == 0) p_timer->in_use = false;
- state_lock.unlock();
-
- alarm_cancel(p_timer->timer[timer_idx]);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_pm_cback
- *
- * Description Conn change callback from sys for low power management
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
- uint8_t app_id, const RawAddress& peer_addr) {
- uint8_t i, j;
- tBTA_DM_PEER_DEVICE* p_dev;
- tBTA_DM_PM_REQ pm_req = BTA_DM_PM_NEW_REQ;
-
- LOG_DEBUG("Power management callback status:%s[%hhu] id:%s[%d], app:%hhu",
- bta_sys_conn_status_text(status).c_str(), status,
- BtaIdSysText(id).c_str(), id, app_id);
-
- /* find if there is an power mode entry for the service */
- for (i = 1; i <= p_bta_dm_pm_cfg[0].app_id; i++) {
- if ((p_bta_dm_pm_cfg[i].id == id) &&
- ((p_bta_dm_pm_cfg[i].app_id == BTA_ALL_APP_ID) ||
- (p_bta_dm_pm_cfg[i].app_id == app_id)))
- break;
- }
-
- /* if no entries are there for the app_id and subsystem in p_bta_dm_pm_spec*/
- if (i > p_bta_dm_pm_cfg[0].app_id) {
- LOG_DEBUG("Ignoring power management callback as no service entries exist");
- return;
- }
-
- LOG_DEBUG("Stopped all timers for service to device:%s id:%hhu",
- PRIVATE_ADDRESS(peer_addr), id);
- bta_dm_pm_stop_timer_by_srvc_id(peer_addr, id);
-
- p_dev = bta_dm_find_peer_device(peer_addr);
- if (p_dev) {
- LOG_DEBUG("Device info:%s", device_info_text(p_dev->Info()).c_str());
- } else {
- LOG_ERROR("Unable to find peer device...yet soldiering on...");
- }
-
- /* set SSR parameters on SYS CONN OPEN */
- int index = BTA_DM_PM_SSR0;
- if ((BTA_SYS_CONN_OPEN == status) && p_dev &&
- (p_dev->Info() & BTA_DM_DI_USE_SSR)) {
- index = p_bta_dm_pm_spec[p_bta_dm_pm_cfg[i].spec_idx].ssr;
- } else if (BTA_ID_AV == id) {
- if (BTA_SYS_CONN_BUSY == status) {
- /* set SSR4 for A2DP on SYS CONN BUSY */
- index = BTA_DM_PM_SSR4;
- } else if (BTA_SYS_CONN_IDLE == status) {
- index = p_bta_dm_pm_spec[p_bta_dm_pm_cfg[i].spec_idx].ssr;
- }
- }
-
- /* if no action for the event */
- if (p_bta_dm_pm_spec[p_bta_dm_pm_cfg[i].spec_idx]
- .actn_tbl[status][0]
- .power_mode == BTA_DM_PM_NO_ACTION) {
- if (BTA_DM_PM_SSR0 == index) /* and do not need to set SSR, return. */
- return;
- }
-
- for (j = 0; j < bta_dm_conn_srvcs.count; j++) {
- /* check if an entry already present */
- if ((bta_dm_conn_srvcs.conn_srvc[j].id == id) &&
- (bta_dm_conn_srvcs.conn_srvc[j].app_id == app_id) &&
- bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr == peer_addr) {
- bta_dm_conn_srvcs.conn_srvc[j].new_request = true;
- break;
- }
- }
-
- /* if subsystem has no more preference on the power mode remove
- the cb */
- if (p_bta_dm_pm_spec[p_bta_dm_pm_cfg[i].spec_idx]
- .actn_tbl[status][0]
- .power_mode == BTA_DM_PM_NO_PREF) {
- if (j != bta_dm_conn_srvcs.count) {
- bta_dm_conn_srvcs.count--;
-
- for (; j < bta_dm_conn_srvcs.count; j++) {
- memcpy(&bta_dm_conn_srvcs.conn_srvc[j],
- &bta_dm_conn_srvcs.conn_srvc[j + 1],
- sizeof(bta_dm_conn_srvcs.conn_srvc[j]));
- }
- } else {
- APPL_TRACE_WARNING("bta_dm_act no entry for connected service cbs");
- return;
- }
- } else if (j == bta_dm_conn_srvcs.count) {
- /* check if we have more connected service that cbs */
- if (bta_dm_conn_srvcs.count == BTA_DM_NUM_CONN_SRVS) {
- LOG_WARN("bta_dm_act no more connected service cbs");
- return;
- }
-
- /* fill in a new cb */
- bta_dm_conn_srvcs.conn_srvc[j].id = id;
- bta_dm_conn_srvcs.conn_srvc[j].app_id = app_id;
- bta_dm_conn_srvcs.conn_srvc[j].new_request = true;
- bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr = peer_addr;
-
- LOG_INFO("New connection service:%s[%hhu] app_id:%d",
- BtaIdSysText(id).c_str(), id, app_id);
-
- bta_dm_conn_srvcs.count++;
- bta_dm_conn_srvcs.conn_srvc[j].state = status;
- } else {
- /* no service is added or removed. only updating status. */
- bta_dm_conn_srvcs.conn_srvc[j].state = status;
- }
-
- /* stop timer */
- bta_dm_pm_stop_timer(peer_addr);
- if (bta_dm_conn_srvcs.count > 0) {
- pm_req = BTA_DM_PM_RESTART;
- APPL_TRACE_DEBUG(
- "%s bta_dm_pm_stop_timer for current service, restart other "
- "service timers: count = %d",
- __func__, bta_dm_conn_srvcs.count);
- }
-
- if (p_dev) {
- p_dev->pm_mode_attempted = 0;
- p_dev->pm_mode_failed = 0;
- }
-
- if (p_bta_dm_ssr_spec[index].max_lat || index == BTA_DM_PM_SSR_HH) {
- bta_dm_pm_ssr(peer_addr, index);
- } else {
- const controller_t* controller = controller_get_interface();
- uint8_t* p = NULL;
- if (controller->supports_sniff_subrating() &&
- ((NULL != (p = BTM_ReadRemoteFeatures(peer_addr))) &&
- HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
- (index == BTA_DM_PM_SSR0)) {
- if (status == BTA_SYS_SCO_OPEN) {
- APPL_TRACE_DEBUG("%s: SCO inactive, reset SSR to zero", __func__);
- BTM_SetSsrParams(peer_addr, 0, 0, 0);
- } else if (status == BTA_SYS_SCO_CLOSE) {
- APPL_TRACE_DEBUG("%s: SCO active, back to old SSR", __func__);
- bta_dm_pm_ssr(peer_addr, BTA_DM_PM_SSR0);
- }
- }
- }
-
- bta_dm_pm_set_mode(peer_addr, BTA_DM_PM_NO_ACTION, pm_req);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_pm_set_mode
- *
- * Description Set the power mode for the device
- *
- *
- * Returns void
- *
- ******************************************************************************/
-
-static void bta_dm_pm_set_mode(const RawAddress& peer_addr,
- tBTA_DM_PM_ACTION pm_request,
- tBTA_DM_PM_REQ pm_req) {
- tBTA_DM_PM_ACTION pm_action = BTA_DM_PM_NO_ACTION;
- uint64_t timeout_ms = 0;
- uint8_t i, j;
- tBTA_DM_PM_ACTION failed_pm = 0;
- tBTA_DM_PEER_DEVICE* p_peer_device = NULL;
- tBTA_DM_PM_ACTION allowed_modes = 0;
- tBTA_DM_PM_ACTION pref_modes = 0;
- const tBTA_DM_PM_CFG* p_pm_cfg;
- const tBTA_DM_PM_SPEC* p_pm_spec;
- const tBTA_DM_PM_ACTN* p_act0;
- const tBTA_DM_PM_ACTN* p_act1;
- tBTA_DM_SRVCS* p_srvcs = NULL;
- bool timer_started = false;
- uint8_t timer_idx, available_timer = BTA_DM_PM_MODE_TIMER_MAX;
- uint64_t remaining_ms = 0;
-
- if (!bta_dm_cb.device_list.count) {
- LOG_INFO("Device list count is zero");
- return;
- }
-
- /* see if any attempt to put device in low power mode failed */
- p_peer_device = bta_dm_find_peer_device(peer_addr);
- /* if no peer device found return */
- if (p_peer_device == NULL) {
- LOG_INFO("No peer device found");
- return;
- }
-
- failed_pm = p_peer_device->pm_mode_failed;
-
- for (i = 0; i < bta_dm_conn_srvcs.count; i++) {
- p_srvcs = &bta_dm_conn_srvcs.conn_srvc[i];
- if (p_srvcs->peer_bdaddr == peer_addr) {
- /* p_bta_dm_pm_cfg[0].app_id is the number of entries */
- for (j = 1; j <= p_bta_dm_pm_cfg[0].app_id; j++) {
- if ((p_bta_dm_pm_cfg[j].id == p_srvcs->id) &&
- ((p_bta_dm_pm_cfg[j].app_id == BTA_ALL_APP_ID) ||
- (p_bta_dm_pm_cfg[j].app_id == p_srvcs->app_id)))
- break;
- }
-
- p_pm_cfg = &p_bta_dm_pm_cfg[j];
- p_pm_spec = &p_bta_dm_pm_spec[p_pm_cfg->spec_idx];
- p_act0 = &p_pm_spec->actn_tbl[p_srvcs->state][0];
- p_act1 = &p_pm_spec->actn_tbl[p_srvcs->state][1];
-
- allowed_modes |= p_pm_spec->allow_mask;
- LOG_DEBUG(
- "Service:%s[%hhu] state:%s[%hhu] allowed_modes:0x%02x "
- "service_index:%hhu ",
- BtaIdSysText(p_srvcs->id).c_str(), p_srvcs->id,
- bta_sys_conn_status_text(p_srvcs->state).c_str(), p_srvcs->state,
- allowed_modes, j);
-
- /* PM actions are in the order of strictness */
-
- /* first check if the first preference is ok */
- if (!(failed_pm & p_act0->power_mode)) {
- pref_modes |= p_act0->power_mode;
-
- if (p_act0->power_mode >= pm_action) {
- pm_action = p_act0->power_mode;
-
- if (pm_req != BTA_DM_PM_NEW_REQ || p_srvcs->new_request) {
- p_srvcs->new_request = false;
- timeout_ms = p_act0->timeout;
- }
- }
- }
- /* if first preference has already failed, try second preference */
- else if (!(failed_pm & p_act1->power_mode)) {
- pref_modes |= p_act1->power_mode;
-
- if (p_act1->power_mode > pm_action) {
- pm_action = p_act1->power_mode;
- timeout_ms = p_act1->timeout;
- }
- }
- }
- }
-
- if (pm_action & (BTA_DM_PM_PARK | BTA_DM_PM_SNIFF)) {
- /* some service don't like the mode */
- if (!(allowed_modes & pm_action)) {
- /* select the other mode if its allowed and preferred, otherwise 0 which
- * is BTA_DM_PM_NO_ACTION */
- pm_action =
- (allowed_modes & (BTA_DM_PM_PARK | BTA_DM_PM_SNIFF) & pref_modes);
-
- /* no timeout needed if no action is required */
- if (pm_action == BTA_DM_PM_NO_ACTION) {
- timeout_ms = 0;
- }
- }
- }
- /* if need to start a timer */
- if ((pm_req != BTA_DM_PM_EXECUTE) && (timeout_ms > 0)) {
- for (i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
- if (bta_dm_cb.pm_timer[i].in_use &&
- bta_dm_cb.pm_timer[i].peer_bdaddr == peer_addr) {
- timer_idx = bta_pm_action_to_timer_idx(pm_action);
- if (timer_idx != BTA_DM_PM_MODE_TIMER_MAX) {
- remaining_ms =
- alarm_get_remaining_ms(bta_dm_cb.pm_timer[i].timer[timer_idx]);
- if (remaining_ms < timeout_ms) {
- /* Cancel and restart the timer */
- /*
- * TODO: The value of pm_action[timer_idx] is
- * conditionally updated between the two function
- * calls below when the timer is restarted.
- * This logic is error-prone and should be eliminated
- * in the future.
- */
- bta_dm_pm_stop_timer_by_index(&bta_dm_cb.pm_timer[i], timer_idx);
- bta_dm_pm_start_timer(&bta_dm_cb.pm_timer[i], timer_idx, timeout_ms,
- p_srvcs->id, pm_action);
- }
- timer_started = true;
- }
- break;
- } else if (!bta_dm_cb.pm_timer[i].in_use) {
- if (available_timer == BTA_DM_PM_MODE_TIMER_MAX) available_timer = i;
- }
- }
- /* new power mode for a new active connection */
- if (!timer_started) {
- if (available_timer != BTA_DM_PM_MODE_TIMER_MAX) {
- bta_dm_cb.pm_timer[available_timer].peer_bdaddr = peer_addr;
- timer_idx = bta_pm_action_to_timer_idx(pm_action);
- if (timer_idx != BTA_DM_PM_MODE_TIMER_MAX) {
- bta_dm_pm_start_timer(&bta_dm_cb.pm_timer[available_timer], timer_idx,
- timeout_ms, p_srvcs->id, pm_action);
- timer_started = true;
- }
- } else {
- LOG_WARN("no more timers");
- }
- }
- return;
- }
- /* if pending power mode timer expires, and currecnt link is in a
- lower power mode than current profile requirement, igonre it */
- if (pm_req == BTA_DM_PM_EXECUTE && pm_request < pm_action) {
- LOG_ERROR("Ignore the power mode request: %d", pm_request);
- return;
- }
- if (pm_action == BTA_DM_PM_PARK) {
- p_peer_device->pm_mode_attempted = BTA_DM_PM_PARK;
- bta_dm_pm_park(peer_addr);
- LOG_WARN("DEPRECATED Setting link to park mode peer:%s",
- PRIVATE_ADDRESS(peer_addr));
- } else if (pm_action & BTA_DM_PM_SNIFF) {
- /* dont initiate SNIFF, if link_policy has it disabled */
- if (BTM_is_sniff_allowed_for(peer_addr)) {
- LOG_DEBUG(
- "Link policy allows sniff mode so setting mode "
- "peer:%s",
- PRIVATE_ADDRESS(peer_addr));
- p_peer_device->pm_mode_attempted = BTA_DM_PM_SNIFF;
- bta_dm_pm_sniff(p_peer_device, (uint8_t)(pm_action & 0x0F));
- } else {
- LOG_DEBUG("Link policy disallows sniff mode, ignore request peer:%s",
- PRIVATE_ADDRESS(peer_addr));
- }
- } else if (pm_action == BTA_DM_PM_ACTIVE) {
- LOG_DEBUG("Setting link to active mode peer:%s",
- PRIVATE_ADDRESS(peer_addr));
- bta_dm_pm_active(peer_addr);
- }
-}
-/*******************************************************************************
- *
- * Function bta_ag_pm_park
- *
- * Description Switch to park mode.
- *
- *
- * Returns true if park attempted, false otherwise.
- *
- ******************************************************************************/
-static bool bta_dm_pm_park(const RawAddress& peer_addr) {
- tBTM_PM_MODE mode = BTM_PM_STS_ACTIVE;
-
- /* if not in park mode, switch to park */
- if (!BTM_ReadPowerMode(peer_addr, &mode)) {
- LOG_WARN("Unable to read power mode for peer:%s",
- PRIVATE_ADDRESS(peer_addr));
- }
-
- if (mode != BTM_PM_MD_PARK) {
- tBTM_STATUS status = BTM_SetPowerMode(bta_dm_cb.pm_id, peer_addr,
- &p_bta_dm_pm_md[BTA_DM_PM_PARK_IDX]);
- if (status == BTM_CMD_STORED || status == BTM_CMD_STARTED) {
- return true;
- }
- LOG_WARN("Unable to set park power mode");
- }
- return true;
-}
-
-/*******************************************************************************
- *
- * Function bta_ag_pm_sniff
- *
- * Description Switch to sniff mode.
- *
- *
- * Returns true if sniff attempted, false otherwise.
- *
- ******************************************************************************/
-void bta_dm_pm_sniff(tBTA_DM_PEER_DEVICE* p_peer_dev, uint8_t index) {
- tBTM_PM_MODE mode = BTM_PM_MD_ACTIVE;
- tBTM_PM_PWR_MD pwr_md;
- tBTM_STATUS status;
-
- if (!BTM_ReadPowerMode(p_peer_dev->peer_bdaddr, &mode)) {
- LOG_WARN("Unable to read power mode for peer:%s",
- PRIVATE_ADDRESS(p_peer_dev->peer_bdaddr));
- }
- tBTM_PM_STATUS mode_status = static_cast<tBTM_PM_STATUS>(mode);
- LOG_DEBUG("Current power mode:%s[0x%x] peer_info:%s[0x%02x]",
- power_mode_status_text(mode_status).c_str(), mode_status,
- device_info_text(p_peer_dev->Info()).c_str(), p_peer_dev->Info());
-
- uint8_t* p_rem_feat = BTM_ReadRemoteFeatures(p_peer_dev->peer_bdaddr);
-
- const controller_t* controller = controller_get_interface();
- if (mode != BTM_PM_MD_SNIFF ||
- (controller->supports_sniff_subrating() && p_rem_feat &&
- HCI_SNIFF_SUB_RATE_SUPPORTED(p_rem_feat) &&
- !(p_peer_dev->Info() & BTA_DM_DI_USE_SSR))) {
- /* Dont initiate Sniff if controller has alreay accepted
- * remote sniff params. This avoid sniff loop issue with
- * some agrresive headsets who use sniff latencies more than
- * DUT supported range of Sniff intervals.*/
- if ((mode == BTM_PM_MD_SNIFF) &&
- (p_peer_dev->Info() & BTA_DM_DI_ACP_SNIFF)) {
- LOG_DEBUG("Link already in sniff mode peer:%s",
- PRIVATE_ADDRESS(p_peer_dev->peer_bdaddr));
- return;
- }
- }
- /* if the current mode is not sniff, issue the sniff command.
- * If sniff, but SSR is not used in this link, still issue the command */
- memcpy(&pwr_md, &p_bta_dm_pm_md[index], sizeof(tBTM_PM_PWR_MD));
- if (p_peer_dev->Info() & BTA_DM_DI_INT_SNIFF) {
- LOG_DEBUG("Trying to force power mode");
- pwr_md.mode |= BTM_PM_MD_FORCE;
- }
- status = BTM_SetPowerMode(bta_dm_cb.pm_id, p_peer_dev->peer_bdaddr, &pwr_md);
- if (status == BTM_CMD_STORED || status == BTM_CMD_STARTED) {
- p_peer_dev->info &= ~(BTA_DM_DI_INT_SNIFF | BTA_DM_DI_ACP_SNIFF);
- p_peer_dev->info |= BTA_DM_DI_SET_SNIFF;
- } else if (status == BTM_SUCCESS) {
- APPL_TRACE_DEBUG("bta_dm_pm_sniff BTM_SetPowerMode() returns BTM_SUCCESS");
- p_peer_dev->info &=
- ~(BTA_DM_DI_INT_SNIFF | BTA_DM_DI_ACP_SNIFF | BTA_DM_DI_SET_SNIFF);
- } else {
- LOG_ERROR("Unable to set power mode peer:%s status:%s",
- PRIVATE_ADDRESS(p_peer_dev->peer_bdaddr),
- btm_status_text(status).c_str());
- p_peer_dev->info &=
- ~(BTA_DM_DI_INT_SNIFF | BTA_DM_DI_ACP_SNIFF | BTA_DM_DI_SET_SNIFF);
- }
-}
-/*******************************************************************************
- *
- * Function bta_dm_pm_ssr
- *
- * Description checks and sends SSR parameters
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_pm_ssr(const RawAddress& peer_addr, int ssr) {
- int current_ssr_index;
- int ssr_index = ssr;
- tBTA_DM_SSR_SPEC* p_spec = &p_bta_dm_ssr_spec[ssr_index];
-
- LOG_DEBUG("Request to put link to device:%s into power_mode:%s",
- PRIVATE_ADDRESS(peer_addr), p_spec->name);
- /* go through the connected services */
- for (int i = 0; i < bta_dm_conn_srvcs.count; i++) {
- const tBTA_DM_SRVCS& service = bta_dm_conn_srvcs.conn_srvc[i];
- if (service.peer_bdaddr != peer_addr) {
- continue;
- }
- /* p_bta_dm_pm_cfg[0].app_id is the number of entries */
- for (int j = 1; j <= p_bta_dm_pm_cfg[0].app_id; j++) {
- /* find the associated p_bta_dm_pm_cfg */
- const tBTA_DM_PM_CFG& config = p_bta_dm_pm_cfg[j];
- current_ssr_index = p_bta_dm_pm_spec[config.spec_idx].ssr;
- if ((config.id == service.id) && ((config.app_id == BTA_ALL_APP_ID) ||
- (config.app_id == service.app_id))) {
- LOG_INFO("Found connected service:%s app_id:%d peer:%s spec_name:%s",
- BtaIdSysText(service.id).c_str(), service.app_id,
- PRIVATE_ADDRESS(peer_addr),
- p_bta_dm_ssr_spec[current_ssr_index].name);
- break;
- }
- }
- /* find the ssr index with the smallest max latency. */
- tBTA_DM_SSR_SPEC* p_spec_cur = &p_bta_dm_ssr_spec[current_ssr_index];
-#if (BTA_HH_INCLUDED == TRUE)
- /* HH has the per connection SSR preference, already read the SSR params
- * from BTA HH */
- if (current_ssr_index == BTA_DM_PM_SSR_HH) {
- if (bta_hh_read_ssr_param(peer_addr, &p_spec_cur->max_lat,
- &p_spec_cur->min_rmt_to) == BTA_HH_ERR) {
- continue;
- }
- }
-#endif
- if (p_spec_cur->max_lat < p_spec->max_lat ||
- (ssr_index == BTA_DM_PM_SSR0 && current_ssr_index != BTA_DM_PM_SSR0)) {
- LOG_DEBUG(
- "Changing sniff subrating specification for %s from %s[%d] ==> "
- "%s[%d]",
- PRIVATE_ADDRESS(peer_addr), p_spec->name, ssr_index, p_spec_cur->name,
- current_ssr_index);
- ssr_index = current_ssr_index;
- p_spec = &p_bta_dm_ssr_spec[ssr_index];
- }
- }
-
- if (p_spec->max_lat) {
- /* Avoid SSR reset on device which has SCO connected */
- if (bta_dm_pm_is_sco_active()) {
- int idx = bta_dm_get_sco_index();
- if (idx != -1) {
- if (bta_dm_conn_srvcs.conn_srvc[idx].peer_bdaddr == peer_addr) {
- LOG_WARN("SCO is active on device, ignore SSR");
- return;
- }
- }
- }
-
- LOG_DEBUG(
- "Setting sniff subrating for device:%s spec_name:%s max_latency(s):%.2f"
- " min_local_timeout(s):%.2f min_remote_timeout(s):%.2f",
- PRIVATE_ADDRESS(peer_addr), p_spec->name,
- ticks_to_seconds(p_spec->max_lat), ticks_to_seconds(p_spec->min_loc_to),
- ticks_to_seconds(p_spec->min_rmt_to));
- /* set the SSR parameters. */
- BTM_SetSsrParams(peer_addr, p_spec->max_lat, p_spec->min_rmt_to,
- p_spec->min_loc_to);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_pm_active
- *
- * Description Brings connection to active mode
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_dm_pm_active(const RawAddress& peer_addr) {
- tBTM_PM_PWR_MD pm{
- .mode = BTM_PM_MD_ACTIVE,
- };
-
- /* switch to active mode */
- tBTM_STATUS status = BTM_SetPowerMode(bta_dm_cb.pm_id, peer_addr, &pm);
- switch (status) {
- case BTM_CMD_STORED:
- LOG_DEBUG("Active power mode stored for execution later for remote:%s",
- PRIVATE_ADDRESS(peer_addr));
- break;
- case BTM_CMD_STARTED:
- LOG_DEBUG("Active power mode started for remote:%s",
- PRIVATE_ADDRESS(peer_addr));
- break;
- case BTM_SUCCESS:
- LOG_INFO("Active power mode already set for device:%s",
- PRIVATE_ADDRESS(peer_addr));
- break;
- default:
- LOG_WARN("Unable to set active power mode for device:%s status:%s",
- PRIVATE_ADDRESS(peer_addr), btm_status_text(status).c_str());
- break;
- }
-}
-
-/** BTM power manager callback */
-static void bta_dm_pm_btm_cback(const RawAddress& bd_addr,
- tBTM_PM_STATUS status, uint16_t value,
- tHCI_STATUS hci_status) {
- do_in_main_thread(FROM_HERE, base::Bind(bta_dm_pm_btm_status, bd_addr, status,
- value, hci_status));
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_pm_timer_cback
- *
- * Description Power management timer callback.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_pm_timer_cback(void* data) {
- uint8_t i, j;
- alarm_t* alarm = (alarm_t*)data;
-
- std::unique_lock<std::recursive_mutex> state_lock(pm_timer_state_mutex);
- for (i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
- APPL_TRACE_DEBUG("dm_pm_timer[%d] in use? %d", i,
- bta_dm_cb.pm_timer[i].in_use);
- if (bta_dm_cb.pm_timer[i].in_use) {
- for (j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
- if (bta_dm_cb.pm_timer[i].timer[j] == alarm) {
- bta_dm_cb.pm_timer[i].active--;
- bta_dm_cb.pm_timer[i].srvc_id[j] = BTA_ID_MAX;
- APPL_TRACE_DEBUG("dm_pm_timer[%d] expires, timer_idx=%d", i, j);
- break;
- }
- }
- if (bta_dm_cb.pm_timer[i].active == 0)
- bta_dm_cb.pm_timer[i].in_use = false;
- if (j < BTA_DM_PM_MODE_TIMER_MAX) break;
- }
- }
- state_lock.unlock();
-
- /* no more timers */
- if (i == BTA_DM_NUM_PM_TIMER) return;
-
- do_in_main_thread(
- FROM_HERE, base::Bind(bta_dm_pm_timer, bta_dm_cb.pm_timer[i].peer_bdaddr,
- bta_dm_cb.pm_timer[i].pm_action[j]));
-}
-
-/** Process pm status event from btm */
-void bta_dm_pm_btm_status(const RawAddress& bd_addr, tBTM_PM_STATUS status,
- uint16_t interval, tHCI_STATUS hci_status) {
- LOG_DEBUG(
- "Power mode notification event status:%s peer:%s interval:%hu "
- "hci_status:%s",
- power_mode_status_text(status).c_str(), PRIVATE_ADDRESS(bd_addr),
- interval, hci_error_code_text(hci_status).c_str());
-
- tBTA_DM_PEER_DEVICE* p_dev = bta_dm_find_peer_device(bd_addr);
- if (p_dev == nullptr) {
- LOG_INFO("Unable to process power event for peer:%s",
- PRIVATE_ADDRESS(bd_addr));
- return;
- }
-
- tBTA_DM_DEV_INFO info = p_dev->Info();
- /* check new mode */
- switch (status) {
- case BTM_PM_STS_ACTIVE:
- /* if our sniff or park attempt failed
- we should not try it again*/
- if (hci_status != 0) {
- APPL_TRACE_ERROR("%s hci_status=%d", __func__, hci_status);
- p_dev->info &=
- ~(BTA_DM_DI_INT_SNIFF | BTA_DM_DI_ACP_SNIFF | BTA_DM_DI_SET_SNIFF);
-
- if (p_dev->pm_mode_attempted & (BTA_DM_PM_PARK | BTA_DM_PM_SNIFF)) {
- p_dev->pm_mode_failed |=
- ((BTA_DM_PM_PARK | BTA_DM_PM_SNIFF) & p_dev->pm_mode_attempted);
- bta_dm_pm_stop_timer_by_mode(bd_addr, p_dev->pm_mode_attempted);
- bta_dm_pm_set_mode(bd_addr, BTA_DM_PM_NO_ACTION, BTA_DM_PM_RESTART);
- }
- } else {
- if (p_dev->prev_low) {
- /* need to send the SSR paramaters to controller again */
- bta_dm_pm_ssr(p_dev->peer_bdaddr, BTA_DM_PM_SSR0);
- }
- p_dev->prev_low = BTM_PM_STS_ACTIVE;
- /* link to active mode, need to restart the timer for next low power
- * mode if needed */
- bta_dm_pm_stop_timer(bd_addr);
- bta_dm_pm_set_mode(bd_addr, BTA_DM_PM_NO_ACTION, BTA_DM_PM_RESTART);
- }
- break;
-
- case BTM_PM_STS_PARK:
- case BTM_PM_STS_HOLD:
- /* save the previous low power mode - for SSR.
- * SSR parameters are sent to controller on "conn open".
- * the numbers stay good until park/hold/detach */
- if (p_dev->info & BTA_DM_DI_USE_SSR) p_dev->prev_low = status;
- break;
-
- case BTM_PM_STS_SSR:
- if (hci_status != 0) {
- LOG_WARN("Received error when attempting to set sniff subrating mode");
- }
- if (interval) {
- p_dev->info |= BTA_DM_DI_USE_SSR;
- LOG_DEBUG("Enabling sniff subrating mode for peer:%s",
- PRIVATE_ADDRESS(bd_addr));
- } else {
- p_dev->info &= ~BTA_DM_DI_USE_SSR;
- LOG_DEBUG("Disabling sniff subrating mode for peer:%s",
- PRIVATE_ADDRESS(bd_addr));
- }
- break;
- case BTM_PM_STS_SNIFF:
- if (hci_status == 0) {
- /* Stop PM timer now if already active for
- * particular device since link is already
- * put in sniff mode by remote device, and
- * PM timer sole purpose is to put the link
- * in sniff mode from host side.
- */
- bta_dm_pm_stop_timer(bd_addr);
- } else {
- p_dev->info &=
- ~(BTA_DM_DI_SET_SNIFF | BTA_DM_DI_INT_SNIFF | BTA_DM_DI_ACP_SNIFF);
- if (info & BTA_DM_DI_SET_SNIFF)
- p_dev->info |= BTA_DM_DI_INT_SNIFF;
- else
- p_dev->info |= BTA_DM_DI_ACP_SNIFF;
- }
- break;
-
- case BTM_PM_STS_ERROR:
- p_dev->info &= ~BTA_DM_DI_SET_SNIFF;
- break;
-
- default:
- LOG_ERROR("Received unknown power mode status event:%hhu", status);
- break;
- }
-}
-
-/** Process pm timer event from btm */
-void bta_dm_pm_timer(const RawAddress& bd_addr, tBTA_DM_PM_ACTION pm_request) {
- APPL_TRACE_EVENT("%s", __func__);
- bta_dm_pm_set_mode(bd_addr, pm_request, BTA_DM_PM_EXECUTE);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_find_peer_device
- *
- * Description Given an address, find the associated control block.
- *
- * Returns tBTA_DM_PEER_DEVICE
- *
- ******************************************************************************/
-tBTA_DM_PEER_DEVICE* bta_dm_find_peer_device(const RawAddress& peer_addr) {
- tBTA_DM_PEER_DEVICE* p_dev = NULL;
-
- for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
- if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == peer_addr) {
- p_dev = &bta_dm_cb.device_list.peer_device[i];
- break;
- }
- }
- return p_dev;
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_is_sco_active
- *
- * Description Loop through connected services for HFP+State=SCO
- *
- * Returns bool. true if SCO active, else false
- *
- ******************************************************************************/
-static bool bta_dm_pm_is_sco_active() {
- int j;
- bool bScoActive = false;
-
- for (j = 0; j < bta_dm_conn_srvcs.count; j++) {
- /* check if an entry already present */
- if ((bta_dm_conn_srvcs.conn_srvc[j].id == BTA_ID_AG) &&
- (bta_dm_conn_srvcs.conn_srvc[j].state == BTA_SYS_SCO_OPEN)) {
- bScoActive = true;
- break;
- }
- }
- return bScoActive;
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_get_sco_index
- *
- * Description Loop through connected services for HFP+State=SCO
- *
- * Returns index at which SCO is connected, in absence of SCO return -1
- *
- ******************************************************************************/
-static int bta_dm_get_sco_index() {
- for (int j = 0; j < bta_dm_conn_srvcs.count; j++) {
- /* check for SCO connected index */
- if ((bta_dm_conn_srvcs.conn_srvc[j].id == BTA_ID_AG) &&
- (bta_dm_conn_srvcs.conn_srvc[j].state == BTA_SYS_SCO_OPEN)) {
- return j;
- }
- }
- return -1;
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_pm_obtain_controller_state
- *
- * Description This function obtains the consolidated controller power
- * state
- *
- * Parameters:
- *
- ******************************************************************************/
-tBTM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void) {
- /* Did not use counts as it is not sure, how accurate the count values are
- *in
- ** bta_dm_cb.device_list.count > 0 || bta_dm_cb.device_list.le_count > 0 */
-
- tBTM_CONTRL_STATE cur_state = BTM_CONTRL_UNKNOWN;
- cur_state = BTM_PM_ReadControllerState();
-
- APPL_TRACE_DEBUG("bta_dm_pm_obtain_controller_state: %d", cur_state);
- return cur_state;
-}
diff --git a/bta/gatt/bta_gattc_act.cc b/bta/gatt/bta_gattc_act.cc
deleted file mode 100644
index ac46809..0000000
--- a/bta/gatt/bta_gattc_act.cc
+++ /dev/null
@@ -1,1459 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains the GATT client action functions for the state
- * machine.
- *
- ******************************************************************************/
-
-#define LOG_TAG "bt_bta_gattc"
-
-#include <base/bind.h>
-#include <base/logging.h>
-#include <base/strings/stringprintf.h>
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bta/gatt/bta_gattc_int.h"
-#include "bta/hh/bta_hh_int.h"
-#include "btif/include/btif_debug_conn.h"
-#include "device/include/controller.h"
-#include "main/shim/dumpsys.h"
-#include "osi/include/allocator.h"
-#include "osi/include/log.h"
-#include "osi/include/osi.h" // UNUSED_ATTR
-#include "stack/include/bt_hdr.h"
-#include "stack/include/btm_ble_api_types.h"
-#include "stack/include/btu.h" // do_in_main_thread
-#include "stack/include/l2c_api.h"
-#include "types/bluetooth/uuid.h"
-#include "types/raw_address.h"
-
-using base::StringPrintf;
-using bluetooth::Uuid;
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-static void bta_gattc_conn_cback(tGATT_IF gattc_if, const RawAddress& bda,
- uint16_t conn_id, bool connected,
- tGATT_DISCONN_REASON reason,
- tBT_TRANSPORT transport);
-
-static void bta_gattc_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op,
- tGATT_STATUS status,
- tGATT_CL_COMPLETE* p_data);
-static void bta_gattc_cmpl_sendmsg(uint16_t conn_id, tGATTC_OPTYPE op,
- tGATT_STATUS status,
- tGATT_CL_COMPLETE* p_data);
-
-static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB* p_clreg);
-static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, const RawAddress& bda);
-static void bta_gattc_cong_cback(uint16_t conn_id, bool congested);
-static void bta_gattc_phy_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
- uint8_t tx_phy, uint8_t rx_phy,
- tGATT_STATUS status);
-static void bta_gattc_conn_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
- uint16_t interval, uint16_t latency,
- uint16_t timeout, tGATT_STATUS status);
-static void bta_gattc_init_bk_conn(const tBTA_GATTC_API_OPEN* p_data,
- tBTA_GATTC_RCB* p_clreg);
-
-static tGATT_CBACK bta_gattc_cl_cback = {
- .p_conn_cb = bta_gattc_conn_cback,
- .p_cmpl_cb = bta_gattc_cmpl_cback,
- .p_disc_res_cb = bta_gattc_disc_res_cback,
- .p_disc_cmpl_cb = bta_gattc_disc_cmpl_cback,
- .p_req_cb = nullptr,
- .p_enc_cmpl_cb = bta_gattc_enc_cmpl_cback,
- .p_congestion_cb = bta_gattc_cong_cback,
- .p_phy_update_cb = bta_gattc_phy_update_cback,
- .p_conn_update_cb = bta_gattc_conn_update_cback};
-
-/* opcode(tGATTC_OPTYPE) order has to be comply with internal event order */
-static uint16_t bta_gattc_opcode_to_int_evt[] = {
- /* Skip: GATTC_OPTYPE_NONE */
- /* Skip: GATTC_OPTYPE_DISCOVERY */
- BTA_GATTC_API_READ_EVT, /* GATTC_OPTYPE_READ */
- BTA_GATTC_API_WRITE_EVT, /* GATTC_OPTYPE_WRITE */
- BTA_GATTC_API_EXEC_EVT, /* GATTC_OPTYPE_EXE_WRITE */
- BTA_GATTC_API_CFG_MTU_EVT /* GATTC_OPTYPE_CONFIG */
-};
-
-static const char* bta_gattc_op_code_name[] = {
- "Unknown", /* GATTC_OPTYPE_NONE */
- "Discovery", /* GATTC_OPTYPE_DISCOVERY */
- "Read", /* GATTC_OPTYPE_READ */
- "Write", /* GATTC_OPTYPE_WRITE */
- "Exec", /* GATTC_OPTYPE_EXE_WRITE */
- "Config", /* GATTC_OPTYPE_CONFIG */
- "Notification", /* GATTC_OPTYPE_NOTIFICATION */
- "Indication" /* GATTC_OPTYPE_INDICATION */
-};
-
-/*****************************************************************************
- * Action Functions
- ****************************************************************************/
-
-void bta_gattc_reset_discover_st(tBTA_GATTC_SERV* p_srcb, tGATT_STATUS status);
-
-/** Enables GATTC module */
-static void bta_gattc_enable() {
- VLOG(1) << __func__;
-
- if (bta_gattc_cb.state == BTA_GATTC_STATE_DISABLED) {
- /* initialize control block */
- bta_gattc_cb = tBTA_GATTC_CB();
- bta_gattc_cb.state = BTA_GATTC_STATE_ENABLED;
- } else {
- VLOG(1) << "GATTC is already enabled";
- }
-}
-
-/** Disable GATTC module by cleaning up all active connections and deregister
- * all application */
-void bta_gattc_disable() {
- uint8_t i;
-
- VLOG(1) << __func__;
-
- if (bta_gattc_cb.state != BTA_GATTC_STATE_ENABLED) {
- LOG(ERROR) << "not enabled, or disabled in progress";
- return;
- }
-
- for (i = 0; i < BTA_GATTC_CL_MAX; i++) {
- if (!bta_gattc_cb.cl_rcb[i].in_use) continue;
-
- bta_gattc_cb.state = BTA_GATTC_STATE_DISABLING;
-/* don't deregister HH GATT IF */
-/* HH GATT IF will be deregistered by bta_hh_le_deregister when disable HH */
- if (!bta_hh_le_is_hh_gatt_if(bta_gattc_cb.cl_rcb[i].client_if)) {
- bta_gattc_deregister(&bta_gattc_cb.cl_rcb[i]);
- }
- }
-
- /* no registered apps, indicate disable completed */
- if (bta_gattc_cb.state != BTA_GATTC_STATE_DISABLING) {
- bta_gattc_cb = tBTA_GATTC_CB();
- bta_gattc_cb.state = BTA_GATTC_STATE_DISABLED;
- }
-}
-
-/** start an application interface */
-static void bta_gattc_start_if(uint8_t client_if) {
- if (!bta_gattc_cl_get_regcb(client_if)) {
- LOG(ERROR) << "Unable to start app.: Unknown client_if=" << +client_if;
- return;
- }
-
- GATT_StartIf(client_if);
-}
-
-/** Register a GATT client application with BTA */
-void bta_gattc_register(const Uuid& app_uuid, tBTA_GATTC_CBACK* p_cback,
- BtaAppRegisterCallback cb, bool eatt_suppport) {
- tGATT_STATUS status = GATT_NO_RESOURCES;
- uint8_t client_if = 0;
- VLOG(1) << __func__ << ": state:" << +bta_gattc_cb.state;
-
- /* check if GATTC module is already enabled . Else enable */
- if (bta_gattc_cb.state == BTA_GATTC_STATE_DISABLED) {
- bta_gattc_enable();
- }
- /* todo need to check duplicate uuid */
- for (uint8_t i = 0; i < BTA_GATTC_CL_MAX; i++) {
- if (!bta_gattc_cb.cl_rcb[i].in_use) {
- if ((bta_gattc_cb.cl_rcb[i].client_if = GATT_Register(
- app_uuid, "GattClient", &bta_gattc_cl_cback, eatt_suppport)) ==
- 0) {
- LOG(ERROR) << "Register with GATT stack failed.";
- status = GATT_ERROR;
- } else {
- bta_gattc_cb.cl_rcb[i].in_use = true;
- bta_gattc_cb.cl_rcb[i].p_cback = p_cback;
- bta_gattc_cb.cl_rcb[i].app_uuid = app_uuid;
-
- /* BTA use the same client interface as BTE GATT statck */
- client_if = bta_gattc_cb.cl_rcb[i].client_if;
-
- do_in_main_thread(FROM_HERE,
- base::Bind(&bta_gattc_start_if, client_if));
-
- status = GATT_SUCCESS;
- break;
- }
- }
- }
-
- if (!cb.is_null()) cb.Run(client_if, status);
-}
-
-/** De-Register a GATT client application with BTA */
-void bta_gattc_deregister(tBTA_GATTC_RCB* p_clreg) {
- if (!p_clreg) {
- LOG(ERROR) << __func__ << ": Deregister Failed unknown client cif";
- bta_hh_cleanup_disable(BTA_HH_OK);
- return;
- }
-
- uint8_t accept_list_size = 0;
- if (controller_get_interface()->supports_ble()) {
- accept_list_size = controller_get_interface()->get_ble_acceptlist_size();
- }
-
- /* remove bg connection associated with this rcb */
- for (uint8_t i = 0; i < accept_list_size; i++) {
- if (!bta_gattc_cb.bg_track[i].in_use) continue;
-
- if (bta_gattc_cb.bg_track[i].cif_mask & (1 << (p_clreg->client_if - 1))) {
- bta_gattc_mark_bg_conn(p_clreg->client_if,
- bta_gattc_cb.bg_track[i].remote_bda, false);
- GATT_CancelConnect(p_clreg->client_if,
- bta_gattc_cb.bg_track[i].remote_bda, false);
- }
- }
-
- if (p_clreg->num_clcb == 0) {
- bta_gattc_deregister_cmpl(p_clreg);
- return;
- }
-
- /* close all CLCB related to this app */
- for (uint8_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
- if (!bta_gattc_cb.clcb[i].in_use || (bta_gattc_cb.clcb[i].p_rcb != p_clreg))
- continue;
-
- p_clreg->dereg_pending = true;
-
- BT_HDR_RIGID buf;
- buf.event = BTA_GATTC_API_CLOSE_EVT;
- buf.layer_specific = bta_gattc_cb.clcb[i].bta_conn_id;
- bta_gattc_close(&bta_gattc_cb.clcb[i], (tBTA_GATTC_DATA*)&buf);
- }
-}
-
-/** process connect API request */
-void bta_gattc_process_api_open(const tBTA_GATTC_DATA* p_msg) {
- uint16_t event = ((BT_HDR_RIGID*)p_msg)->event;
-
- tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(p_msg->api_conn.client_if);
- if (!p_clreg) {
- LOG(ERROR) << __func__
- << ": Failed, unknown client_if=" << +p_msg->api_conn.client_if;
- return;
- }
-
- if (!p_msg->api_conn.is_direct) {
- bta_gattc_init_bk_conn(&p_msg->api_conn, p_clreg);
- return;
- }
-
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_alloc_clcb(
- p_msg->api_conn.client_if, p_msg->api_conn.remote_bda,
- p_msg->api_conn.transport);
- if (p_clcb != NULL) {
- bta_gattc_sm_execute(p_clcb, event, p_msg);
- } else {
- LOG(ERROR) << "No resources to open a new connection.";
-
- bta_gattc_send_open_cback(p_clreg, GATT_NO_RESOURCES,
- p_msg->api_conn.remote_bda, GATT_INVALID_CONN_ID,
- p_msg->api_conn.transport, 0);
- }
-}
-
-/** process connect API request */
-void bta_gattc_process_api_open_cancel(const tBTA_GATTC_DATA* p_msg) {
- CHECK(p_msg != nullptr);
-
- uint16_t event = ((BT_HDR_RIGID*)p_msg)->event;
-
- if (!p_msg->api_cancel_conn.is_direct) {
- LOG_DEBUG("Cancel GATT client background connection");
- bta_gattc_cancel_bk_conn(&p_msg->api_cancel_conn);
- return;
- }
- LOG_DEBUG("Cancel GATT client direct connection");
-
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_cif(
- p_msg->api_cancel_conn.client_if, p_msg->api_cancel_conn.remote_bda,
- BT_TRANSPORT_LE);
- if (p_clcb != NULL) {
- bta_gattc_sm_execute(p_clcb, event, p_msg);
- return;
- }
-
- LOG(ERROR) << "No such connection need to be cancelled";
-
- tBTA_GATTC_RCB* p_clreg =
- bta_gattc_cl_get_regcb(p_msg->api_cancel_conn.client_if);
-
- if (p_clreg && p_clreg->p_cback) {
- tBTA_GATTC cb_data;
- cb_data.status = GATT_ERROR;
- (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
- }
-}
-
-/** process encryption complete message */
-static void bta_gattc_process_enc_cmpl(tGATT_IF client_if,
- const RawAddress& bda) {
- tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(client_if);
-
- if (!p_clreg || !p_clreg->p_cback) return;
-
- tBTA_GATTC cb_data;
- memset(&cb_data, 0, sizeof(tBTA_GATTC));
-
- cb_data.enc_cmpl.client_if = client_if;
- cb_data.enc_cmpl.remote_bda = bda;
-
- (*p_clreg->p_cback)(BTA_GATTC_ENC_CMPL_CB_EVT, &cb_data);
-}
-
-void bta_gattc_cancel_open_error(tBTA_GATTC_CLCB* p_clcb,
- UNUSED_ATTR const tBTA_GATTC_DATA* p_data) {
- tBTA_GATTC cb_data;
-
- cb_data.status = GATT_ERROR;
-
- if (p_clcb && p_clcb->p_rcb && p_clcb->p_rcb->p_cback)
- (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
-}
-
-void bta_gattc_open_error(tBTA_GATTC_CLCB* p_clcb,
- UNUSED_ATTR const tBTA_GATTC_DATA* p_data) {
- LOG(ERROR) << "Connection already opened. wrong state";
-
- bta_gattc_send_open_cback(p_clcb->p_rcb, GATT_SUCCESS, p_clcb->bda,
- p_clcb->bta_conn_id, p_clcb->transport, 0);
-}
-
-void bta_gattc_open_fail(tBTA_GATTC_CLCB* p_clcb,
- UNUSED_ATTR const tBTA_GATTC_DATA* p_data) {
- LOG(WARNING) << __func__ << ": Cannot establish Connection. conn_id="
- << loghex(p_clcb->bta_conn_id) << ". Return GATT_ERROR("
- << +GATT_ERROR << ")";
-
- bta_gattc_send_open_cback(p_clcb->p_rcb, GATT_ERROR, p_clcb->bda,
- p_clcb->bta_conn_id, p_clcb->transport, 0);
- /* open failure, remove clcb */
- bta_gattc_clcb_dealloc(p_clcb);
-}
-
-/** Process API connection function */
-void bta_gattc_open(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
- tBTA_GATTC_DATA gattc_data;
-
- /* open/hold a connection */
- if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda, true,
- p_data->api_conn.transport, p_data->api_conn.opportunistic,
- p_data->api_conn.initiating_phys)) {
- LOG(ERROR) << "Connection open failure";
-
- bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_OPEN_FAIL_EVT, p_data);
- return;
- }
-
- /* a connected remote device */
- if (GATT_GetConnIdIfConnected(
- p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda,
- &p_clcb->bta_conn_id, p_data->api_conn.transport)) {
- gattc_data.int_conn.hdr.layer_specific = p_clcb->bta_conn_id;
-
- bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
- }
- /* else wait for the callback event */
-}
-
-/** Process API Open for a background connection */
-static void bta_gattc_init_bk_conn(const tBTA_GATTC_API_OPEN* p_data,
- tBTA_GATTC_RCB* p_clreg) {
- if (!bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, true)) {
- LOG_WARN("Unable to find space for acceptlist connection mask");
- bta_gattc_send_open_cback(p_clreg, GATT_NO_RESOURCES, p_data->remote_bda,
- GATT_INVALID_CONN_ID, BT_TRANSPORT_LE, 0);
- return;
- }
-
- /* always call open to hold a connection */
- if (!GATT_Connect(p_data->client_if, p_data->remote_bda, false,
- p_data->transport, false)) {
- LOG(ERROR) << __func__
- << " unable to connect to remote bd_addr=" << p_data->remote_bda;
- bta_gattc_send_open_cback(p_clreg, GATT_ERROR, p_data->remote_bda,
- GATT_INVALID_CONN_ID, BT_TRANSPORT_LE, 0);
- return;
- }
-
- uint16_t conn_id;
- if (!GATT_GetConnIdIfConnected(p_data->client_if, p_data->remote_bda,
- &conn_id, p_data->transport)) {
- LOG_WARN("Not a connected remote device");
- return;
- }
-
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_alloc_clcb(
- p_data->client_if, p_data->remote_bda, BT_TRANSPORT_LE);
- if (!p_clcb) {
- LOG_WARN("Unable to find connection link for device:%s",
- PRIVATE_ADDRESS(p_data->remote_bda));
- return;
- }
-
- p_clcb->bta_conn_id = conn_id;
- tBTA_GATTC_DATA gattc_data = {
- .hdr =
- {
- .layer_specific = conn_id,
- },
- };
-
- /* open connection */
- bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT,
- static_cast<const tBTA_GATTC_DATA*>(&gattc_data));
-}
-
-/** Process API Cancel Open for a background connection */
-void bta_gattc_cancel_bk_conn(const tBTA_GATTC_API_CANCEL_OPEN* p_data) {
- tBTA_GATTC_RCB* p_clreg;
- tBTA_GATTC cb_data;
- cb_data.status = GATT_ERROR;
-
- /* remove the device from the bg connection mask */
- if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, false)) {
- if (GATT_CancelConnect(p_data->client_if, p_data->remote_bda, false)) {
- cb_data.status = GATT_SUCCESS;
- } else {
- LOG(ERROR) << __func__ << ": failed";
- }
- }
- p_clreg = bta_gattc_cl_get_regcb(p_data->client_if);
-
- if (p_clreg && p_clreg->p_cback) {
- (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
- }
-}
-
-void bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB* p_clcb,
- UNUSED_ATTR const tBTA_GATTC_DATA* p_data) {
- tBTA_GATTC cb_data;
-
- if (p_clcb->p_rcb->p_cback) {
- cb_data.status = GATT_SUCCESS;
- (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
- }
-
- bta_gattc_clcb_dealloc(p_clcb);
-}
-
-void bta_gattc_cancel_open(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data) {
- tBTA_GATTC cb_data;
-
- if (GATT_CancelConnect(p_clcb->p_rcb->client_if,
- p_data->api_cancel_conn.remote_bda, true)) {
- bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CANCEL_OPEN_OK_EVT, p_data);
- } else {
- if (p_clcb->p_rcb->p_cback) {
- cb_data.status = GATT_ERROR;
- (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
- }
- }
-}
-
-/** receive connection callback from stack */
-void bta_gattc_conn(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
- tGATT_IF gatt_if;
- VLOG(1) << __func__ << ": server cache state=" << +p_clcb->p_srcb->state;
-
- if (p_data != NULL) {
- VLOG(1) << __func__ << ": conn_id=" << loghex(p_data->hdr.layer_specific);
- p_clcb->bta_conn_id = p_data->int_conn.hdr.layer_specific;
-
- GATT_GetConnectionInfor(p_data->hdr.layer_specific, &gatt_if, p_clcb->bda,
- &p_clcb->transport);
- }
-
- p_clcb->p_srcb->connected = true;
-
- if (p_clcb->p_srcb->mtu == 0) p_clcb->p_srcb->mtu = GATT_DEF_BLE_MTU_SIZE;
-
- /* start database cache if needed */
- if (p_clcb->p_srcb->gatt_database.IsEmpty() ||
- p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE) {
- if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) {
- p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD;
- if (bta_gattc_cache_load(p_clcb->p_srcb)) {
- p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
- bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_SUCCESS);
- } else {
- p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
- /* cache load failure, start discovery */
- bta_gattc_start_discover(p_clcb, NULL);
- }
- } else /* cache is building */
- p_clcb->state = BTA_GATTC_DISCOVER_ST;
- }
-
- else {
- /* a pending service handle change indication */
- if (p_clcb->p_srcb->srvc_hdl_chg) {
- p_clcb->p_srcb->srvc_hdl_chg = false;
-
- /* set true to read database hash before service discovery */
- if (bta_gattc_is_robust_caching_enabled()) {
- p_clcb->p_srcb->srvc_hdl_db_hash = true;
- }
-
- /* start discovery */
- bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
- }
- }
-
- if (p_clcb->p_rcb) {
- /* there is no RM for GATT */
- if (p_clcb->transport == BT_TRANSPORT_BR_EDR)
- bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
-
- bta_gattc_send_open_cback(p_clcb->p_rcb, GATT_SUCCESS, p_clcb->bda,
- p_clcb->bta_conn_id, p_clcb->transport,
- p_clcb->p_srcb->mtu);
- }
-}
-
-/** close a connection */
-void bta_gattc_close_fail(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data) {
- tBTA_GATTC cb_data;
-
- if (p_clcb->p_rcb->p_cback) {
- memset(&cb_data, 0, sizeof(tBTA_GATTC));
- cb_data.close.client_if = p_clcb->p_rcb->client_if;
- cb_data.close.conn_id = p_data->hdr.layer_specific;
- cb_data.close.remote_bda = p_clcb->bda;
- cb_data.close.reason = BTA_GATT_CONN_NONE;
-
- LOG(WARNING) << __func__ << ": conn_id=" << loghex(cb_data.close.conn_id)
- << ". Returns GATT_ERROR(" << +GATT_ERROR << ").";
-
- (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data);
- }
-}
-
-/** close a GATTC connection */
-void bta_gattc_close(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
- tBTA_GATTC_CBACK* p_cback = p_clcb->p_rcb->p_cback;
- tBTA_GATTC_RCB* p_clreg = p_clcb->p_rcb;
- tBTA_GATTC cb_data = {
- .close =
- {
- .client_if = p_clcb->p_rcb->client_if,
- .conn_id = p_clcb->bta_conn_id,
- .reason = GATT_CONN_OK,
- .remote_bda = p_clcb->bda,
- .status = GATT_SUCCESS,
- },
- };
-
- if (p_clcb->transport == BT_TRANSPORT_BR_EDR)
- bta_sys_conn_close(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
-
- bta_gattc_clcb_dealloc(p_clcb);
-
- if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT) {
- GATT_Disconnect(p_data->hdr.layer_specific);
- LOG_DEBUG("Local close event client_if:%hu conn_id:%hu reason:%s",
- cb_data.close.client_if, cb_data.close.conn_id,
- gatt_disconnection_reason_text(
- static_cast<tGATT_DISCONN_REASON>(cb_data.close.reason))
- .c_str());
- } else if (p_data->hdr.event == BTA_GATTC_INT_DISCONN_EVT) {
- cb_data.close.reason = p_data->int_conn.reason;
- LOG_DEBUG("Peer close disconnect event client_if:%hu conn_id:%hu reason:%s",
- cb_data.close.client_if, cb_data.close.conn_id,
- gatt_disconnection_reason_text(
- static_cast<tGATT_DISCONN_REASON>(cb_data.close.reason))
- .c_str());
- }
-
- if (p_cback) (*p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data);
-
- if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending) {
- bta_gattc_deregister_cmpl(p_clreg);
- }
-}
-
-/** when a SRCB finished discovery, tell all related clcb */
-void bta_gattc_reset_discover_st(tBTA_GATTC_SERV* p_srcb, tGATT_STATUS status) {
- for (uint8_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
- if (bta_gattc_cb.clcb[i].p_srcb == p_srcb) {
- bta_gattc_cb.clcb[i].status = status;
- bta_gattc_sm_execute(&bta_gattc_cb.clcb[i], BTA_GATTC_DISCOVER_CMPL_EVT,
- NULL);
- }
- }
-}
-
-/** close a GATTC connection while in discovery state */
-void bta_gattc_disc_close(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data) {
- VLOG(1) << __func__
- << ": Discovery cancel conn_id=" << loghex(p_clcb->bta_conn_id);
-
- if (p_clcb->disc_active)
- bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR);
- else
- p_clcb->state = BTA_GATTC_CONN_ST;
-
- // This function only gets called as the result of a BTA_GATTC_API_CLOSE_EVT
- // while in the BTA_GATTC_DISCOVER_ST state. Once the state changes, the
- // connection itself still needs to be closed to resolve the original event.
- if (p_clcb->state == BTA_GATTC_CONN_ST) {
- VLOG(1) << "State is back to BTA_GATTC_CONN_ST. Trigger connection close";
- bta_gattc_close(p_clcb, p_data);
- }
-}
-
-/** when a SRCB start discovery, tell all related clcb and set the state */
-static void bta_gattc_set_discover_st(tBTA_GATTC_SERV* p_srcb) {
- uint8_t i;
-
- for (i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
- if (bta_gattc_cb.clcb[i].p_srcb == p_srcb) {
- bta_gattc_cb.clcb[i].status = GATT_SUCCESS;
- bta_gattc_cb.clcb[i].state = BTA_GATTC_DISCOVER_ST;
- bta_gattc_cb.clcb[i].request_during_discovery =
- BTA_GATTC_DISCOVER_REQ_NONE;
- }
- }
-}
-
-/** process service change in discovery state, mark up the auto update flag and
- * set status to be discovery cancel for current discovery.
- */
-void bta_gattc_restart_discover(tBTA_GATTC_CLCB* p_clcb,
- UNUSED_ATTR const tBTA_GATTC_DATA* p_data) {
- p_clcb->status = GATT_CANCEL;
- p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
-}
-
-/** Configure MTU size on the GATT connection */
-void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
- if (!bta_gattc_enqueue(p_clcb, p_data)) return;
-
- tGATT_STATUS status =
- GATTC_ConfigureMTU(p_clcb->bta_conn_id, p_data->api_mtu.mtu);
-
- /* if failed, return callback here */
- if (status != GATT_SUCCESS && status != GATT_CMD_STARTED) {
- /* Dequeue the data, if it was enqueued */
- if (p_clcb->p_q_cmd == p_data) p_clcb->p_q_cmd = NULL;
-
- bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG, status,
- NULL);
- }
-}
-
-void bta_gattc_start_discover_internal(tBTA_GATTC_CLCB* p_clcb) {
- if (p_clcb->transport == BT_TRANSPORT_LE)
- L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, false);
-
- bta_gattc_init_cache(p_clcb->p_srcb);
- p_clcb->status = bta_gattc_discover_pri_service(
- p_clcb->bta_conn_id, p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
- if (p_clcb->status != GATT_SUCCESS) {
- LOG(ERROR) << "discovery on server failed";
- bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
- } else
- p_clcb->disc_active = true;
-}
-
-/** Start a discovery on server */
-void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb,
- UNUSED_ATTR const tBTA_GATTC_DATA* p_data) {
- VLOG(1) << __func__ << ": conn_id:" << loghex(p_clcb->bta_conn_id)
- << " p_clcb->p_srcb->state:" << +p_clcb->p_srcb->state;
-
- if (((p_clcb->p_q_cmd == NULL ||
- p_clcb->auto_update == BTA_GATTC_REQ_WAITING) &&
- p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) ||
- p_clcb->p_srcb->state == BTA_GATTC_SERV_DISC)
- /* no pending operation, start discovery right away */
- {
- p_clcb->auto_update = BTA_GATTC_NO_SCHEDULE;
-
- if (p_clcb->p_srcb != NULL) {
- /* set all srcb related clcb into discovery ST */
- bta_gattc_set_discover_st(p_clcb->p_srcb);
-
- /* clear the service change mask */
- p_clcb->p_srcb->srvc_hdl_chg = false;
- p_clcb->p_srcb->update_count = 0;
- p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT;
-
- /* read db hash if db hash characteristic exists */
- if (bta_gattc_is_robust_caching_enabled() &&
- p_clcb->p_srcb->srvc_hdl_db_hash && bta_gattc_read_db_hash(p_clcb)) {
- LOG(INFO) << __func__
- << ": pending service discovery, read db hash first";
- p_clcb->p_srcb->srvc_hdl_db_hash = false;
- return;
- }
-
- bta_gattc_start_discover_internal(p_clcb);
- } else {
- LOG(ERROR) << "unknown device, can not start discovery";
- }
- }
- /* pending operation, wait until it finishes */
- else {
- p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
-
- if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE)
- p_clcb->state = BTA_GATTC_CONN_ST; /* set clcb state */
- }
-}
-
-/** discovery on server is finished */
-void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb,
- UNUSED_ATTR const tBTA_GATTC_DATA* p_data) {
- const tBTA_GATTC_DATA* p_q_cmd = p_clcb->p_q_cmd;
-
- VLOG(1) << __func__ << ": conn_id=" << loghex(p_clcb->bta_conn_id);
-
- if (p_clcb->transport == BT_TRANSPORT_LE)
- L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, true);
- p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
- p_clcb->disc_active = false;
-
- if (p_clcb->status != GATT_SUCCESS) {
- /* clean up cache */
- if (p_clcb->p_srcb) {
- p_clcb->p_srcb->gatt_database.Clear();
- }
-
- /* used to reset cache in application */
- bta_gattc_cache_reset(p_clcb->p_srcb->server_bda);
- }
-
- if (p_clcb->p_srcb) {
- p_clcb->p_srcb->pending_discovery.Clear();
- }
-
- if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
- /* start discovery again */
- p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
- bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
- }
- /* get any queued command to proceed */
- else if (p_q_cmd != NULL) {
- p_clcb->p_q_cmd = NULL;
- /* execute pending operation of link block still present */
- if (L2CA_IsLinkEstablished(p_clcb->p_srcb->server_bda, p_clcb->transport)) {
- bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd);
- }
- /* if the command executed requeued the cmd, we don't
- * want to free the underlying buffer that's being
- * referenced by p_clcb->p_q_cmd
- */
- if (p_q_cmd != p_clcb->p_q_cmd) osi_free_and_reset((void**)&p_q_cmd);
- }
-
- if (p_clcb->p_rcb->p_cback) {
- tBTA_GATTC bta_gattc;
- bta_gattc.remote_bda = p_clcb->p_srcb->server_bda;
- (*p_clcb->p_rcb->p_cback)(BTA_GATTC_SRVC_DISC_DONE_EVT, &bta_gattc);
- }
-}
-
-/** Read an attribute */
-void bta_gattc_read(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
- if (!bta_gattc_enqueue(p_clcb, p_data)) return;
-
- tGATT_STATUS status;
- if (p_data->api_read.handle != 0) {
- tGATT_READ_PARAM read_param;
- memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
- read_param.by_handle.handle = p_data->api_read.handle;
- read_param.by_handle.auth_req = p_data->api_read.auth_req;
- status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_HANDLE, &read_param);
- } else {
- tGATT_READ_PARAM read_param;
- memset(&read_param, 0, sizeof(tGATT_READ_BY_TYPE));
-
- read_param.char_type.s_handle = p_data->api_read.s_handle;
- read_param.char_type.e_handle = p_data->api_read.e_handle;
- read_param.char_type.uuid = p_data->api_read.uuid;
- read_param.char_type.auth_req = p_data->api_read.auth_req;
- status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_TYPE, &read_param);
- }
-
- /* read fail */
- if (status != GATT_SUCCESS) {
- /* Dequeue the data, if it was enqueued */
- if (p_clcb->p_q_cmd == p_data) p_clcb->p_q_cmd = NULL;
-
- bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status,
- NULL);
- }
-}
-
-/** read multiple */
-void bta_gattc_read_multi(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data) {
- if (!bta_gattc_enqueue(p_clcb, p_data)) return;
-
- tGATT_READ_PARAM read_param;
- memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
-
- read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr;
- read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req;
- memcpy(&read_param.read_multiple.handles, p_data->api_read_multi.handles,
- sizeof(uint16_t) * p_data->api_read_multi.num_attr);
-
- tGATT_STATUS status =
- GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE, &read_param);
- /* read fail */
- if (status != GATT_SUCCESS) {
- /* Dequeue the data, if it was enqueued */
- if (p_clcb->p_q_cmd == p_data) p_clcb->p_q_cmd = NULL;
-
- bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status,
- NULL);
- }
-}
-
-/** Write an attribute */
-void bta_gattc_write(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
- if (!bta_gattc_enqueue(p_clcb, p_data)) return;
-
- tGATT_STATUS status = GATT_SUCCESS;
- tGATT_VALUE attr;
-
- attr.conn_id = p_clcb->bta_conn_id;
- attr.handle = p_data->api_write.handle;
- attr.offset = p_data->api_write.offset;
- attr.len = p_data->api_write.len;
- attr.auth_req = p_data->api_write.auth_req;
-
- if (p_data->api_write.p_value)
- memcpy(attr.value, p_data->api_write.p_value, p_data->api_write.len);
-
- status =
- GATTC_Write(p_clcb->bta_conn_id, p_data->api_write.write_type, &attr);
-
- /* write fail */
- if (status != GATT_SUCCESS) {
- /* Dequeue the data, if it was enqueued */
- if (p_clcb->p_q_cmd == p_data) p_clcb->p_q_cmd = NULL;
-
- bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_WRITE, status,
- NULL);
- }
-}
-
-/** send execute write */
-void bta_gattc_execute(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
- if (!bta_gattc_enqueue(p_clcb, p_data)) return;
-
- tGATT_STATUS status =
- GATTC_ExecuteWrite(p_clcb->bta_conn_id, p_data->api_exec.is_execute);
- if (status != GATT_SUCCESS) {
- /* Dequeue the data, if it was enqueued */
- if (p_clcb->p_q_cmd == p_data) p_clcb->p_q_cmd = NULL;
-
- bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_EXE_WRITE, status,
- NULL);
- }
-}
-
-/** send handle value confirmation */
-void bta_gattc_confirm(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
- uint16_t cid = p_data->api_confirm.cid;
-
- if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific,
- cid) != GATT_SUCCESS) {
- LOG(ERROR) << __func__ << ": to cid=" << loghex(cid) << " failed";
- } else {
- /* if over BR_EDR, inform PM for mode change */
- if (p_clcb->transport == BT_TRANSPORT_BR_EDR) {
- bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
- bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
- }
- }
-}
-
-/** read complete */
-static void bta_gattc_read_cmpl(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_OP_CMPL* p_data) {
- GATT_READ_OP_CB cb = p_clcb->p_q_cmd->api_read.read_cb;
- void* my_cb_data = p_clcb->p_q_cmd->api_read.read_cb_data;
-
- /* if it was read by handle, return the handle requested, if read by UUID, use
- * handle returned from remote
- */
- uint16_t handle = p_clcb->p_q_cmd->api_read.handle;
- if (handle == 0) handle = p_data->p_cmpl->att_value.handle;
-
- osi_free_and_reset((void**)&p_clcb->p_q_cmd);
-
- if (cb) {
- cb(p_clcb->bta_conn_id, p_data->status, handle,
- p_data->p_cmpl->att_value.len, p_data->p_cmpl->att_value.value,
- my_cb_data);
- }
-}
-
-/** write complete */
-static void bta_gattc_write_cmpl(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_OP_CMPL* p_data) {
- GATT_WRITE_OP_CB cb = p_clcb->p_q_cmd->api_write.write_cb;
- void* my_cb_data = p_clcb->p_q_cmd->api_write.write_cb_data;
-
- osi_free_and_reset((void**)&p_clcb->p_q_cmd);
-
- if (cb) {
- cb(p_clcb->bta_conn_id, p_data->status, p_data->p_cmpl->att_value.handle,
- p_data->p_cmpl->att_value.len, p_data->p_cmpl->att_value.value,
- my_cb_data);
- }
-}
-
-/** execute write complete */
-static void bta_gattc_exec_cmpl(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_OP_CMPL* p_data) {
- tBTA_GATTC cb_data;
-
- osi_free_and_reset((void**)&p_clcb->p_q_cmd);
- p_clcb->status = GATT_SUCCESS;
-
- /* execute complete, callback */
- cb_data.exec_cmpl.conn_id = p_clcb->bta_conn_id;
- cb_data.exec_cmpl.status = p_data->status;
-
- (*p_clcb->p_rcb->p_cback)(BTA_GATTC_EXEC_EVT, &cb_data);
-}
-
-/** configure MTU operation complete */
-static void bta_gattc_cfg_mtu_cmpl(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_OP_CMPL* p_data) {
- GATT_CONFIGURE_MTU_OP_CB cb = p_clcb->p_q_cmd->api_mtu.mtu_cb;
- void* my_cb_data = p_clcb->p_q_cmd->api_mtu.mtu_cb_data;
- tBTA_GATTC cb_data;
-
- osi_free_and_reset((void**)&p_clcb->p_q_cmd);
-
- if (p_data->p_cmpl && p_data->status == GATT_SUCCESS)
- p_clcb->p_srcb->mtu = p_data->p_cmpl->mtu;
-
- /* configure MTU complete, callback */
- p_clcb->status = p_data->status;
- cb_data.cfg_mtu.conn_id = p_clcb->bta_conn_id;
- cb_data.cfg_mtu.status = p_data->status;
- cb_data.cfg_mtu.mtu = p_clcb->p_srcb->mtu;
-
- if (cb) {
- cb(p_clcb->bta_conn_id, p_data->status, my_cb_data);
- }
-
- (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CFG_MTU_EVT, &cb_data);
-}
-
-/** operation completed */
-void bta_gattc_op_cmpl(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
- if (p_clcb->p_q_cmd == NULL) {
- LOG_ERROR("No pending command gatt client command");
- return;
- }
-
- const tGATTC_OPTYPE op = p_data->op_cmpl.op_code;
- switch (op) {
- case GATTC_OPTYPE_READ:
- case GATTC_OPTYPE_WRITE:
- case GATTC_OPTYPE_EXE_WRITE:
- case GATTC_OPTYPE_CONFIG:
- break;
-
- case GATTC_OPTYPE_NONE:
- case GATTC_OPTYPE_DISCOVERY:
- case GATTC_OPTYPE_NOTIFICATION:
- case GATTC_OPTYPE_INDICATION:
- default:
- LOG(ERROR) << "unexpected operation, ignored";
- return;
- }
-
- if (p_clcb->p_q_cmd->hdr.event !=
- bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ]) {
- uint8_t mapped_op =
- p_clcb->p_q_cmd->hdr.event - BTA_GATTC_API_READ_EVT + GATTC_OPTYPE_READ;
- if (mapped_op > GATTC_OPTYPE_INDICATION) mapped_op = 0;
-
- LOG(ERROR) << StringPrintf(
- "expect op:(%s :0x%04x), receive unexpected operation (%s).",
- bta_gattc_op_code_name[mapped_op], p_clcb->p_q_cmd->hdr.event,
- bta_gattc_op_code_name[op]);
- return;
- }
-
- /* Except for MTU configuration, discard responses if service change
- * indication is received before operation completed
- */
- if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING &&
- p_clcb->p_srcb->srvc_hdl_chg && op != GATTC_OPTYPE_CONFIG) {
- VLOG(1) << "Discard all responses when service change indication is "
- "received.";
- // TODO Fix constness
- const_cast<tBTA_GATTC_DATA*>(p_data)->op_cmpl.status = GATT_ERROR;
- }
-
- /* service handle change void the response, discard it */
- if (op == GATTC_OPTYPE_READ)
- bta_gattc_read_cmpl(p_clcb, &p_data->op_cmpl);
-
- else if (op == GATTC_OPTYPE_WRITE)
- bta_gattc_write_cmpl(p_clcb, &p_data->op_cmpl);
-
- else if (op == GATTC_OPTYPE_EXE_WRITE)
- bta_gattc_exec_cmpl(p_clcb, &p_data->op_cmpl);
-
- else if (op == GATTC_OPTYPE_CONFIG)
- bta_gattc_cfg_mtu_cmpl(p_clcb, &p_data->op_cmpl);
-
- // If receive DATABASE_OUT_OF_SYNC error code, bta_gattc should start service
- // discovery immediately
- if (bta_gattc_is_robust_caching_enabled() &&
- p_data->op_cmpl.status == GATT_DATABASE_OUT_OF_SYNC) {
- LOG(INFO) << __func__ << ": DATABASE_OUT_OF_SYNC, re-discover service";
- p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
- /* request read db hash first */
- p_clcb->p_srcb->srvc_hdl_db_hash = true;
- bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
- return;
- }
-
- if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
- p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
-
- /* request read db hash first */
- if (bta_gattc_is_robust_caching_enabled()) {
- p_clcb->p_srcb->srvc_hdl_db_hash = true;
- }
-
- bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
- }
-}
-
-/** start a search in the local server cache */
-void bta_gattc_search(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
- tGATT_STATUS status = GATT_INTERNAL_ERROR;
- tBTA_GATTC cb_data;
- VLOG(1) << __func__ << ": conn_id=" << loghex(p_clcb->bta_conn_id);
- if (p_clcb->p_srcb && !p_clcb->p_srcb->gatt_database.IsEmpty()) {
- status = GATT_SUCCESS;
- /* search the local cache of a server device */
- bta_gattc_search_service(p_clcb, p_data->api_search.p_srvc_uuid);
- }
- cb_data.search_cmpl.status = status;
- cb_data.search_cmpl.conn_id = p_clcb->bta_conn_id;
-
- /* end of search or no server cache available */
- (*p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_CMPL_EVT, &cb_data);
-}
-
-/** enqueue a command into control block, usually because discovery operation is
- * busy */
-void bta_gattc_q_cmd(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
- bta_gattc_enqueue(p_clcb, p_data);
-}
-
-/** report API call failure back to apps */
-void bta_gattc_fail(tBTA_GATTC_CLCB* p_clcb,
- UNUSED_ATTR const tBTA_GATTC_DATA* p_data) {
- if (p_clcb->status == GATT_SUCCESS) {
- LOG(ERROR) << "operation not supported at current state " << +p_clcb->state;
- }
-}
-
-/* De-Register a GATT client application with BTA completed */
-static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB* p_clreg) {
- tGATT_IF client_if = p_clreg->client_if;
- tBTA_GATTC cb_data;
- tBTA_GATTC_CBACK* p_cback = p_clreg->p_cback;
-
- memset(&cb_data, 0, sizeof(tBTA_GATTC));
-
- GATT_Deregister(p_clreg->client_if);
- memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB));
-
- cb_data.reg_oper.client_if = client_if;
- cb_data.reg_oper.status = GATT_SUCCESS;
-
- if (p_cback) /* callback with de-register event */
- (*p_cback)(BTA_GATTC_DEREG_EVT, &cb_data);
-
- if (bta_gattc_num_reg_app() == 0 &&
- bta_gattc_cb.state == BTA_GATTC_STATE_DISABLING) {
- bta_gattc_cb.state = BTA_GATTC_STATE_DISABLED;
- }
-}
-
-/** callback functions to GATT client stack */
-static void bta_gattc_conn_cback(tGATT_IF gattc_if, const RawAddress& bdaddr,
- uint16_t conn_id, bool connected,
- tGATT_DISCONN_REASON reason,
- tBT_TRANSPORT transport) {
- if (connected) {
- LOG_INFO("Connected att_id:%hhu transport:%s reason:%s", gattc_if,
- bt_transport_text(transport).c_str(),
- gatt_disconnection_reason_text(reason).c_str());
- btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_OK);
- } else {
- LOG_INFO("Disconnected att_id:%hhu transport:%s reason:%s", gattc_if,
- bt_transport_text(transport).c_str(),
- gatt_disconnection_reason_text(reason).c_str());
- btif_debug_conn_state(bdaddr, BTIF_DEBUG_DISCONNECTED, GATT_CONN_OK);
- }
-
- tBTA_GATTC_DATA* p_buf =
- (tBTA_GATTC_DATA*)osi_calloc(sizeof(tBTA_GATTC_DATA));
- p_buf->int_conn.hdr.event =
- connected ? BTA_GATTC_INT_CONN_EVT : BTA_GATTC_INT_DISCONN_EVT;
- p_buf->int_conn.hdr.layer_specific = conn_id;
- p_buf->int_conn.client_if = gattc_if;
- p_buf->int_conn.role = L2CA_GetBleConnRole(bdaddr);
- p_buf->int_conn.reason = reason;
- p_buf->int_conn.transport = transport;
- p_buf->int_conn.remote_bda = bdaddr;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/** encryption complete callback function to GATT client stack */
-static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, const RawAddress& bda) {
- tBTA_GATTC_CLCB* p_clcb =
- bta_gattc_find_clcb_by_cif(gattc_if, bda, BT_TRANSPORT_LE);
-
- if (p_clcb == NULL) return;
-
- VLOG(1) << __func__ << ": cif:" << +gattc_if;
-
- do_in_main_thread(FROM_HERE,
- base::Bind(&bta_gattc_process_enc_cmpl, gattc_if, bda));
-}
-
-/** process refresh API to delete cache and start a new discovery if currently
- * connected */
-void bta_gattc_process_api_refresh(const RawAddress& remote_bda) {
- tBTA_GATTC_SERV* p_srvc_cb = bta_gattc_find_srvr_cache(remote_bda);
- if (p_srvc_cb) {
- /* try to find a CLCB */
- if (p_srvc_cb->connected && p_srvc_cb->num_clcb != 0) {
- bool found = false;
- tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0];
- for (uint8_t i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) {
- if (p_clcb->in_use && p_clcb->p_srcb == p_srvc_cb) {
- found = true;
- break;
- }
- }
- if (found) {
- bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
- return;
- }
- }
- /* in all other cases, mark it and delete the cache */
-
- p_srvc_cb->gatt_database.Clear();
- }
-
- /* used to reset cache in application */
- bta_gattc_cache_reset(remote_bda);
-}
-
-/** process service change indication */
-static bool bta_gattc_process_srvc_chg_ind(uint16_t conn_id,
- tBTA_GATTC_RCB* p_clrcb,
- tBTA_GATTC_SERV* p_srcb,
- tBTA_GATTC_CLCB* p_clcb,
- tBTA_GATTC_NOTIFY* p_notify,
- tGATT_VALUE* att_value) {
- Uuid gattp_uuid = Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER);
- Uuid srvc_chg_uuid = Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD);
-
- if (p_srcb->gatt_database.IsEmpty() && p_srcb->state == BTA_GATTC_SERV_IDLE) {
- bta_gattc_cache_load(p_srcb);
- }
-
- const gatt::Characteristic* p_char =
- bta_gattc_get_characteristic_srcb(p_srcb, p_notify->handle);
- if (!p_char) return false;
- const gatt::Service* p_svc =
- bta_gattc_get_service_for_handle_srcb(p_srcb, p_char->value_handle);
- if (!p_svc || p_svc->uuid != gattp_uuid || p_char->uuid != srvc_chg_uuid) {
- return false;
- }
-
- if (att_value->len != BTA_GATTC_SERVICE_CHANGED_LEN) {
- LOG(ERROR) << __func__
- << ": received malformed service changed indication, skipping";
- return false;
- }
-
- uint8_t* p = att_value->value;
- uint16_t s_handle = ((uint16_t)(*(p)) + (((uint16_t)(*(p + 1))) << 8));
- uint16_t e_handle = ((uint16_t)(*(p + 2)) + (((uint16_t)(*(p + 3))) << 8));
-
- LOG(ERROR) << __func__ << ": service changed s_handle=" << loghex(s_handle)
- << ", e_handle=" << loghex(e_handle);
-
- /* mark service handle change pending */
- p_srcb->srvc_hdl_chg = true;
- /* clear up all notification/indication registration */
- bta_gattc_clear_notif_registration(p_srcb, conn_id, s_handle, e_handle);
- /* service change indication all received, do discovery update */
- if (++p_srcb->update_count == bta_gattc_num_reg_app()) {
- /* not an opened connection; or connection busy */
- /* search for first available clcb and start discovery */
- if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL)) {
- for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
- if (bta_gattc_cb.clcb[i].in_use &&
- bta_gattc_cb.clcb[i].p_srcb == p_srcb &&
- bta_gattc_cb.clcb[i].p_q_cmd == NULL) {
- p_clcb = &bta_gattc_cb.clcb[i];
- break;
- }
- }
- }
- /* send confirmation here if this is an indication, it should always be */
- GATTC_SendHandleValueConfirm(conn_id, p_notify->cid);
-
- /* if connection available, refresh cache by doing discovery now */
- if (p_clcb) {
- /* request read db hash first */
- if (bta_gattc_is_robust_caching_enabled()) {
- p_srcb->srvc_hdl_db_hash = true;
- }
- bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
- }
- }
-
- /* notify applicationf or service change */
- if (p_clrcb->p_cback) {
- tBTA_GATTC bta_gattc;
- bta_gattc.service_changed.remote_bda = p_srcb->server_bda;
- bta_gattc.service_changed.conn_id = conn_id;
- (*p_clrcb->p_cback)(BTA_GATTC_SRVC_CHG_EVT, &bta_gattc);
- }
-
- return true;
-}
-
-/** process all non-service change indication/notification */
-static void bta_gattc_proc_other_indication(tBTA_GATTC_CLCB* p_clcb, uint8_t op,
- tGATT_CL_COMPLETE* p_data,
- tBTA_GATTC_NOTIFY* p_notify) {
- VLOG(1) << __func__
- << StringPrintf(
- ": check p_data->att_value.handle=%d p_data->handle=%d",
- p_data->att_value.handle, p_data->handle);
- VLOG(1) << "is_notify " << p_notify->is_notify;
-
- p_notify->is_notify = (op == GATTC_OPTYPE_INDICATION) ? false : true;
- p_notify->len = p_data->att_value.len;
- p_notify->bda = p_clcb->bda;
- memcpy(p_notify->value, p_data->att_value.value, p_data->att_value.len);
- p_notify->conn_id = p_clcb->bta_conn_id;
-
- if (p_clcb->p_rcb->p_cback) {
- tBTA_GATTC bta_gattc;
- bta_gattc.notify = *p_notify;
- (*p_clcb->p_rcb->p_cback)(BTA_GATTC_NOTIF_EVT, &bta_gattc);
- }
-}
-
-/** process indication/notification */
-static void bta_gattc_process_indicate(uint16_t conn_id, tGATTC_OPTYPE op,
- tGATT_CL_COMPLETE* p_data) {
- uint16_t handle = p_data->att_value.handle;
- tBTA_GATTC_NOTIFY notify;
- RawAddress remote_bda;
- tGATT_IF gatt_if;
- tBT_TRANSPORT transport;
-
- if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
- LOG(ERROR) << __func__ << ": indication/notif for unknown app";
- if (op == GATTC_OPTYPE_INDICATION)
- GATTC_SendHandleValueConfirm(conn_id, p_data->cid);
- return;
- }
-
- tBTA_GATTC_RCB* p_clrcb = bta_gattc_cl_get_regcb(gatt_if);
- if (p_clrcb == NULL) {
- LOG(ERROR) << __func__ << ": indication/notif for unregistered app";
- if (op == GATTC_OPTYPE_INDICATION)
- GATTC_SendHandleValueConfirm(conn_id, p_data->cid);
- return;
- }
-
- tBTA_GATTC_SERV* p_srcb = bta_gattc_find_srcb(remote_bda);
- if (p_srcb == NULL) {
- LOG(ERROR) << __func__ << ": indication/notif for unknown device, ignore";
- if (op == GATTC_OPTYPE_INDICATION)
- GATTC_SendHandleValueConfirm(conn_id, p_data->cid);
- return;
- }
-
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
-
- notify.handle = handle;
- notify.cid = p_data->cid;
-
- /* if service change indication/notification, don't forward to application */
- if (bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, ¬ify,
- &p_data->att_value))
- return;
-
- /* if app registered for the notification */
- if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, ¬ify)) {
- /* connection not open yet */
- if (p_clcb == NULL) {
- p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport);
-
- if (p_clcb == NULL) {
- LOG(ERROR) << "No resources";
- return;
- }
-
- p_clcb->bta_conn_id = conn_id;
- p_clcb->transport = transport;
-
- bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL);
- }
-
- if (p_clcb != NULL)
- bta_gattc_proc_other_indication(p_clcb, op, p_data, ¬ify);
- }
- /* no one intersted and need ack? */
- else if (op == GATTC_OPTYPE_INDICATION) {
- VLOG(1) << __func__ << " no one interested, ack now";
- GATTC_SendHandleValueConfirm(conn_id, p_data->cid);
- }
-}
-
-/** client operation complete callback register with BTE GATT */
-static void bta_gattc_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op,
- tGATT_STATUS status,
- tGATT_CL_COMPLETE* p_data) {
- VLOG(1) << __func__ << ": conn_id:" << +conn_id << " op:" << +op
- << " status:" << +status;
-
- /* notification and indication processed right away */
- if (op == GATTC_OPTYPE_NOTIFICATION || op == GATTC_OPTYPE_INDICATION) {
- bta_gattc_process_indicate(conn_id, op, p_data);
- return;
- }
- /* for all other operation, not expected if w/o connection */
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
- if (!p_clcb) {
- LOG(ERROR) << __func__ << ": unknown conn_id=" << loghex(conn_id)
- << " ignore data";
- return;
- }
-
- /* if over BR_EDR, inform PM for mode change */
- if (p_clcb->transport == BT_TRANSPORT_BR_EDR) {
- bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
- bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
- }
-
- bta_gattc_cmpl_sendmsg(conn_id, op, status, p_data);
-}
-
-/** client operation complete send message */
-static void bta_gattc_cmpl_sendmsg(uint16_t conn_id, tGATTC_OPTYPE op,
- tGATT_STATUS status,
- tGATT_CL_COMPLETE* p_data) {
- const size_t len = sizeof(tBTA_GATTC_OP_CMPL) + sizeof(tGATT_CL_COMPLETE);
- tBTA_GATTC_OP_CMPL* p_buf = (tBTA_GATTC_OP_CMPL*)osi_calloc(len);
-
- p_buf->hdr.event = BTA_GATTC_OP_CMPL_EVT;
- p_buf->hdr.layer_specific = conn_id;
- p_buf->status = status;
- p_buf->op_code = op;
-
- if (p_data) {
- p_buf->p_cmpl = (tGATT_CL_COMPLETE*)(p_buf + 1);
- memcpy(p_buf->p_cmpl, p_data, sizeof(tGATT_CL_COMPLETE));
- }
-
- bta_sys_sendmsg(p_buf);
-}
-
-/** congestion callback for BTA GATT client */
-static void bta_gattc_cong_cback(uint16_t conn_id, bool congested) {
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
- if (!p_clcb || !p_clcb->p_rcb->p_cback) return;
-
- tBTA_GATTC cb_data;
- cb_data.congest.conn_id = conn_id;
- cb_data.congest.congested = congested;
-
- (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CONGEST_EVT, &cb_data);
-}
-
-static void bta_gattc_phy_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
- uint8_t tx_phy, uint8_t rx_phy,
- tGATT_STATUS status) {
- tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(gatt_if);
-
- if (!p_clreg || !p_clreg->p_cback) {
- LOG(ERROR) << __func__ << ": client_if=" << +gatt_if << " not found";
- return;
- }
-
- tBTA_GATTC cb_data;
- cb_data.phy_update.conn_id = conn_id;
- cb_data.phy_update.server_if = gatt_if;
- cb_data.phy_update.tx_phy = tx_phy;
- cb_data.phy_update.rx_phy = rx_phy;
- cb_data.phy_update.status = status;
- (*p_clreg->p_cback)(BTA_GATTC_PHY_UPDATE_EVT, &cb_data);
-}
-
-static void bta_gattc_conn_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
- uint16_t interval, uint16_t latency,
- uint16_t timeout, tGATT_STATUS status) {
- tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(gatt_if);
-
- if (!p_clreg || !p_clreg->p_cback) {
- LOG(ERROR) << __func__ << ": client_if=" << gatt_if << " not found";
- return;
- }
-
- tBTA_GATTC cb_data;
- cb_data.conn_update.conn_id = conn_id;
- cb_data.conn_update.interval = interval;
- cb_data.conn_update.latency = latency;
- cb_data.conn_update.timeout = timeout;
- cb_data.conn_update.status = status;
- (*p_clreg->p_cback)(BTA_GATTC_CONN_UPDATE_EVT, &cb_data);
-}
diff --git a/bta/gatt/bta_gattc_api.cc b/bta/gatt/bta_gattc_api.cc
deleted file mode 100644
index 83735de..0000000
--- a/bta/gatt/bta_gattc_api.cc
+++ /dev/null
@@ -1,756 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2010-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the implementation of the API for GATT module of BTA.
- *
- ******************************************************************************/
-
-#include <base/bind.h>
-#include <base/logging.h>
-
-#include <ios>
-#include <list>
-#include <memory>
-#include <vector>
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bta/gatt/bta_gattc_int.h"
-#include "device/include/controller.h"
-#include "osi/include/allocator.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/btu.h" // do_in_main_thread
-#include "types/bluetooth/uuid.h"
-#include "types/bt_transport.h"
-#include "types/raw_address.h"
-
-using bluetooth::Uuid;
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-
-static const tBTA_SYS_REG bta_gattc_reg = {bta_gattc_hdl_event,
- BTA_GATTC_Disable};
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_Disable
- *
- * Description This function is called to disable GATTC module
- *
- * Parameters None.
- *
- * Returns None
- *
- ******************************************************************************/
-void BTA_GATTC_Disable(void) {
- if (!bta_sys_is_register(BTA_ID_GATTC)) {
- LOG(WARNING) << "GATTC Module not enabled/already disabled";
- return;
- }
-
- do_in_main_thread(FROM_HERE, base::Bind(&bta_gattc_disable));
- bta_sys_deregister(BTA_ID_GATTC);
-}
-
-/**
- * This function is called to register application callbacks with BTA GATTC
- * module. |client_cb| pointer to the application callback function.
- * |cb| one time callback when registration is finished
- */
-void BTA_GATTC_AppRegister(tBTA_GATTC_CBACK* p_client_cb,
- BtaAppRegisterCallback cb, bool eatt_support) {
- if (!bta_sys_is_register(BTA_ID_GATTC))
- bta_sys_register(BTA_ID_GATTC, &bta_gattc_reg);
-
- do_in_main_thread(
- FROM_HERE, base::Bind(&bta_gattc_register, Uuid::GetRandom(), p_client_cb,
- std::move(cb), eatt_support));
-}
-
-static void app_deregister_impl(tGATT_IF client_if) {
- bta_gattc_deregister(bta_gattc_cl_get_regcb(client_if));
-}
-/*******************************************************************************
- *
- * Function BTA_GATTC_AppDeregister
- *
- * Description This function is called to deregister an application
- * from BTA GATTC module.
- *
- * Parameters client_if - client interface identifier.
- *
- * Returns None
- *
- ******************************************************************************/
-void BTA_GATTC_AppDeregister(tGATT_IF client_if) {
- do_in_main_thread(FROM_HERE, base::Bind(&app_deregister_impl, client_if));
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_Open
- *
- * Description Open a direct connection or add a background auto connection
- * bd address
- *
- * Parameters client_if: server interface.
- * remote_bda: remote device BD address.
- * is_direct: direct connection or background auto connection
- * transport: Transport to be used for GATT connection
- * (BREDR/LE)
- * initiating_phys: LE PHY to use, optional
- * opportunistic: wether the connection shall be opportunistic,
- * and don't impact the disconnection timer
- *
- ******************************************************************************/
-void BTA_GATTC_Open(tGATT_IF client_if, const RawAddress& remote_bda,
- bool is_direct, bool opportunistic) {
- uint8_t phy = controller_get_interface()->get_le_all_initiating_phys();
- BTA_GATTC_Open(client_if, remote_bda, is_direct, BT_TRANSPORT_LE,
- opportunistic, phy);
-}
-
-void BTA_GATTC_Open(tGATT_IF client_if, const RawAddress& remote_bda,
- bool is_direct, tBT_TRANSPORT transport, bool opportunistic,
- uint8_t initiating_phys) {
- tBTA_GATTC_DATA data = {
- .api_conn =
- {
- .hdr =
- {
- .event = BTA_GATTC_API_OPEN_EVT,
- },
- .remote_bda = remote_bda,
- .client_if = client_if,
- .is_direct = is_direct,
- .transport = transport,
- .initiating_phys = initiating_phys,
- .opportunistic = opportunistic,
- },
- };
-
- post_on_bt_main([data]() { bta_gattc_process_api_open(&data); });
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_CancelOpen
- *
- * Description Cancel a direct open connection or remove a background auto
- * connection
- * bd address
- *
- * Parameters client_if: server interface.
- * remote_bda: remote device BD address.
- * is_direct: direct connection or background auto connection
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_GATTC_CancelOpen(tGATT_IF client_if, const RawAddress& remote_bda,
- bool is_direct) {
- tBTA_GATTC_API_CANCEL_OPEN* p_buf = (tBTA_GATTC_API_CANCEL_OPEN*)osi_malloc(
- sizeof(tBTA_GATTC_API_CANCEL_OPEN));
-
- p_buf->hdr.event = BTA_GATTC_API_CANCEL_OPEN_EVT;
- p_buf->client_if = client_if;
- p_buf->is_direct = is_direct;
- p_buf->remote_bda = remote_bda;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_Close
- *
- * Description Close a connection to a GATT server.
- *
- * Parameters conn_id: connectino ID to be closed.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_GATTC_Close(uint16_t conn_id) {
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
-
- p_buf->event = BTA_GATTC_API_CLOSE_EVT;
- p_buf->layer_specific = conn_id;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_ConfigureMTU
- *
- * Description Configure the MTU size in the GATT channel. This can be done
- * only once per connection.
- *
- * Parameters conn_id: connection ID.
- * mtu: desired MTU size to use.
- *
- * Returns void
- *
- ******************************************************************************/
-
-void BTA_GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu) {
- BTA_GATTC_ConfigureMTU(conn_id, mtu, NULL, NULL);
-}
-
-void BTA_GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu,
- GATT_CONFIGURE_MTU_OP_CB callback, void* cb_data) {
- tBTA_GATTC_API_CFG_MTU* p_buf =
- (tBTA_GATTC_API_CFG_MTU*)osi_malloc(sizeof(tBTA_GATTC_API_CFG_MTU));
-
- p_buf->hdr.event = BTA_GATTC_API_CFG_MTU_EVT;
- p_buf->hdr.layer_specific = conn_id;
- p_buf->mtu = mtu;
- p_buf->mtu_cb = callback;
- p_buf->mtu_cb_data = cb_data;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_ServiceSearchRequest
- *
- * Description This function is called to request a GATT service discovery
- * on a GATT server. This function report service search
- * result by a callback event, and followed by a service search
- * complete event.
- *
- * Parameters conn_id: connection ID.
- * p_srvc_uuid: a UUID of the service application is interested
- * in.
- * If Null, discover for all services.
- *
- * Returns None
- *
- ******************************************************************************/
-void BTA_GATTC_ServiceSearchRequest(uint16_t conn_id, const Uuid* p_srvc_uuid) {
- const size_t len = sizeof(tBTA_GATTC_API_SEARCH) + sizeof(Uuid);
- tBTA_GATTC_API_SEARCH* p_buf = (tBTA_GATTC_API_SEARCH*)osi_calloc(len);
-
- p_buf->hdr.event = BTA_GATTC_API_SEARCH_EVT;
- p_buf->hdr.layer_specific = conn_id;
- if (p_srvc_uuid) {
- p_buf->p_srvc_uuid = (Uuid*)(p_buf + 1);
- *p_buf->p_srvc_uuid = *p_srvc_uuid;
- } else {
- p_buf->p_srvc_uuid = NULL;
- }
-
- bta_sys_sendmsg(p_buf);
-}
-
-void BTA_GATTC_DiscoverServiceByUuid(uint16_t conn_id, const Uuid& srvc_uuid) {
- do_in_main_thread(
- FROM_HERE,
- base::Bind(
- base::IgnoreResult<tGATT_STATUS (*)(uint16_t, tGATT_DISC_TYPE,
- uint16_t, uint16_t, const Uuid&)>(
- &GATTC_Discover),
- conn_id, GATT_DISC_SRVC_BY_UUID, 0x0001, 0xFFFF, srvc_uuid));
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_GetServices
- *
- * Description This function is called to find the services on the given
- * server.
- *
- * Parameters conn_id: connection ID which identify the server.
- *
- * Returns returns list of gatt::Service or NULL.
- *
- ******************************************************************************/
-const std::list<gatt::Service>* BTA_GATTC_GetServices(uint16_t conn_id) {
- return bta_gattc_get_services(conn_id);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_GetCharacteristic
- *
- * Description This function is called to find the characteristic on the
- * given server.
- *
- * Parameters conn_id - connection ID which identify the server.
- * handle - characteristic handle
- *
- * Returns returns pointer to gatt::Characteristic or NULL.
- *
- ******************************************************************************/
-const gatt::Characteristic* BTA_GATTC_GetCharacteristic(uint16_t conn_id,
- uint16_t handle) {
- return bta_gattc_get_characteristic(conn_id, handle);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_GetDescriptor
- *
- * Description This function is called to find the characteristic on the
- * given server.
- *
- * Parameters conn_id - connection ID which identify the server.
- * handle - descriptor handle
- *
- * Returns returns pointer to gatt::Descriptor or NULL.
- *
- ******************************************************************************/
-const gatt::Descriptor* BTA_GATTC_GetDescriptor(uint16_t conn_id,
- uint16_t handle) {
- return bta_gattc_get_descriptor(conn_id, handle);
-}
-
-/* Return characteristic that owns descriptor with handle equal to |handle|, or
- * NULL */
-const gatt::Characteristic* BTA_GATTC_GetOwningCharacteristic(uint16_t conn_id,
- uint16_t handle) {
- return bta_gattc_get_owning_characteristic(conn_id, handle);
-}
-
-/* Return service that owns descriptor or characteristic with handle equal to
- * |handle|, or NULL */
-const gatt::Service* BTA_GATTC_GetOwningService(uint16_t conn_id,
- uint16_t handle) {
- return bta_gattc_get_service_for_handle(conn_id, handle);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_GetGattDb
- *
- * Description This function is called to get the GATT database.
- *
- * Parameters conn_id: connection ID which identify the server.
- * db: output parameter which will contain the GATT database
- * copy. Caller is responsible for freeing it.
- * count: number of elements in database.
- *
- ******************************************************************************/
-void BTA_GATTC_GetGattDb(uint16_t conn_id, uint16_t start_handle,
- uint16_t end_handle, btgatt_db_element_t** db,
- int* count) {
- bta_gattc_get_gatt_db(conn_id, start_handle, end_handle, db, count);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_ReadCharacteristic
- *
- * Description This function is called to read a characteristics value
- *
- * Parameters conn_id - connection ID.
- * handle - characteritic handle to read.
- *
- * Returns None
- *
- ******************************************************************************/
-void BTA_GATTC_ReadCharacteristic(uint16_t conn_id, uint16_t handle,
- tGATT_AUTH_REQ auth_req,
- GATT_READ_OP_CB callback, void* cb_data) {
- tBTA_GATTC_API_READ* p_buf =
- (tBTA_GATTC_API_READ*)osi_calloc(sizeof(tBTA_GATTC_API_READ));
-
- p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
- p_buf->hdr.layer_specific = conn_id;
- p_buf->auth_req = auth_req;
- p_buf->handle = handle;
- p_buf->read_cb = callback;
- p_buf->read_cb_data = cb_data;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/**
- * This function is called to read a value of characteristic with uuid equal to
- * |uuid|
- */
-void BTA_GATTC_ReadUsingCharUuid(uint16_t conn_id, const Uuid& uuid,
- uint16_t s_handle, uint16_t e_handle,
- tGATT_AUTH_REQ auth_req,
- GATT_READ_OP_CB callback, void* cb_data) {
- tBTA_GATTC_API_READ* p_buf =
- (tBTA_GATTC_API_READ*)osi_calloc(sizeof(tBTA_GATTC_API_READ));
-
- p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
- p_buf->hdr.layer_specific = conn_id;
- p_buf->auth_req = auth_req;
- p_buf->handle = 0;
- p_buf->uuid = uuid;
- p_buf->s_handle = s_handle;
- p_buf->e_handle = e_handle;
- p_buf->read_cb = callback;
- p_buf->read_cb_data = cb_data;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_ReadCharDescr
- *
- * Description This function is called to read a descriptor value.
- *
- * Parameters conn_id - connection ID.
- * handle - descriptor handle to read.
- *
- * Returns None
- *
- ******************************************************************************/
-void BTA_GATTC_ReadCharDescr(uint16_t conn_id, uint16_t handle,
- tGATT_AUTH_REQ auth_req, GATT_READ_OP_CB callback,
- void* cb_data) {
- tBTA_GATTC_API_READ* p_buf =
- (tBTA_GATTC_API_READ*)osi_calloc(sizeof(tBTA_GATTC_API_READ));
-
- p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
- p_buf->hdr.layer_specific = conn_id;
- p_buf->auth_req = auth_req;
- p_buf->handle = handle;
- p_buf->read_cb = callback;
- p_buf->read_cb_data = cb_data;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_ReadMultiple
- *
- * Description This function is called to read multiple characteristic or
- * characteristic descriptors.
- *
- * Parameters conn_id - connectino ID.
- * p_read_multi - pointer to the read multiple parameter.
- *
- * Returns None
- *
- ******************************************************************************/
-void BTA_GATTC_ReadMultiple(uint16_t conn_id, tBTA_GATTC_MULTI* p_read_multi,
- tGATT_AUTH_REQ auth_req) {
- tBTA_GATTC_API_READ_MULTI* p_buf =
- (tBTA_GATTC_API_READ_MULTI*)osi_calloc(sizeof(tBTA_GATTC_API_READ_MULTI));
-
- p_buf->hdr.event = BTA_GATTC_API_READ_MULTI_EVT;
- p_buf->hdr.layer_specific = conn_id;
- p_buf->auth_req = auth_req;
- p_buf->num_attr = p_read_multi->num_attr;
-
- if (p_buf->num_attr > 0)
- memcpy(p_buf->handles, p_read_multi->handles,
- sizeof(uint16_t) * p_read_multi->num_attr);
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_WriteCharValue
- *
- * Description This function is called to write characteristic value.
- *
- * Parameters conn_id - connection ID.
- * handle - characteristic handle to write.
- * write_type - type of write.
- * value - the value to be written.
- *
- * Returns None
- *
- ******************************************************************************/
-void BTA_GATTC_WriteCharValue(uint16_t conn_id, uint16_t handle,
- tGATT_WRITE_TYPE write_type,
- std::vector<uint8_t> value,
- tGATT_AUTH_REQ auth_req,
- GATT_WRITE_OP_CB callback, void* cb_data) {
- tBTA_GATTC_API_WRITE* p_buf = (tBTA_GATTC_API_WRITE*)osi_calloc(
- sizeof(tBTA_GATTC_API_WRITE) + value.size());
-
- p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
- p_buf->hdr.layer_specific = conn_id;
- p_buf->auth_req = auth_req;
- p_buf->handle = handle;
- p_buf->write_type = write_type;
- p_buf->len = value.size();
- p_buf->write_cb = callback;
- p_buf->write_cb_data = cb_data;
-
- if (value.size() > 0) {
- p_buf->p_value = (uint8_t*)(p_buf + 1);
- memcpy(p_buf->p_value, value.data(), value.size());
- }
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_WriteCharDescr
- *
- * Description This function is called to write descriptor value.
- *
- * Parameters conn_id - connection ID
- * handle - descriptor hadle to write.
- * value - the value to be written.
- *
- * Returns None
- *
- ******************************************************************************/
-void BTA_GATTC_WriteCharDescr(uint16_t conn_id, uint16_t handle,
- std::vector<uint8_t> value,
- tGATT_AUTH_REQ auth_req,
- GATT_WRITE_OP_CB callback, void* cb_data) {
- tBTA_GATTC_API_WRITE* p_buf = (tBTA_GATTC_API_WRITE*)osi_calloc(
- sizeof(tBTA_GATTC_API_WRITE) + value.size());
-
- p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
- p_buf->hdr.layer_specific = conn_id;
- p_buf->auth_req = auth_req;
- p_buf->handle = handle;
- p_buf->write_type = GATT_WRITE;
- p_buf->write_cb = callback;
- p_buf->write_cb_data = cb_data;
-
- if (value.size() != 0) {
- p_buf->p_value = (uint8_t*)(p_buf + 1);
- p_buf->len = value.size();
- memcpy(p_buf->p_value, value.data(), value.size());
- }
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_PrepareWrite
- *
- * Description This function is called to prepare write a characteristic
- * value.
- *
- * Parameters conn_id - connection ID.
- * p_char_id - GATT characteritic ID of the service.
- * offset - offset of the write value.
- * value - the value to be written.
- *
- * Returns None
- *
- ******************************************************************************/
-void BTA_GATTC_PrepareWrite(uint16_t conn_id, uint16_t handle, uint16_t offset,
- std::vector<uint8_t> value, tGATT_AUTH_REQ auth_req,
- GATT_WRITE_OP_CB callback, void* cb_data) {
- tBTA_GATTC_API_WRITE* p_buf = (tBTA_GATTC_API_WRITE*)osi_calloc(
- sizeof(tBTA_GATTC_API_WRITE) + value.size());
-
- p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
- p_buf->hdr.layer_specific = conn_id;
- p_buf->auth_req = auth_req;
- p_buf->handle = handle;
- p_buf->write_cb = callback;
- p_buf->write_cb_data = cb_data;
-
- p_buf->write_type = BTA_GATTC_WRITE_PREPARE;
- p_buf->offset = offset;
- p_buf->len = value.size();
-
- if (value.size() > 0) {
- p_buf->p_value = (uint8_t*)(p_buf + 1);
- memcpy(p_buf->p_value, value.data(), value.size());
- }
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_ExecuteWrite
- *
- * Description This function is called to execute write a prepare write
- * sequence.
- *
- * Parameters conn_id - connection ID.
- * is_execute - execute or cancel.
- *
- * Returns None
- *
- ******************************************************************************/
-void BTA_GATTC_ExecuteWrite(uint16_t conn_id, bool is_execute) {
- tBTA_GATTC_API_EXEC* p_buf =
- (tBTA_GATTC_API_EXEC*)osi_calloc(sizeof(tBTA_GATTC_API_EXEC));
-
- p_buf->hdr.event = BTA_GATTC_API_EXEC_EVT;
- p_buf->hdr.layer_specific = conn_id;
- p_buf->is_execute = is_execute;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_SendIndConfirm
- *
- * Description This function is called to send handle value confirmation.
- *
- * Parameters conn_id - connection ID.
- * cid
- *
- * Returns None
- *
- ******************************************************************************/
-void BTA_GATTC_SendIndConfirm(uint16_t conn_id, uint16_t cid) {
- tBTA_GATTC_API_CONFIRM* p_buf =
- (tBTA_GATTC_API_CONFIRM*)osi_calloc(sizeof(tBTA_GATTC_API_CONFIRM));
-
- VLOG(1) << __func__ << ": conn_id=" << +conn_id << " cid=0x" << std::hex
- << +cid;
-
- p_buf->hdr.event = BTA_GATTC_API_CONFIRM_EVT;
- p_buf->hdr.layer_specific = conn_id;
- p_buf->cid = cid;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_RegisterForNotifications
- *
- * Description This function is called to register for notification of a
- * service.
- *
- * Parameters client_if - client interface.
- * bda - target GATT server.
- * handle - GATT characteristic handle.
- *
- * Returns OK if registration succeed, otherwise failed.
- *
- ******************************************************************************/
-tGATT_STATUS BTA_GATTC_RegisterForNotifications(tGATT_IF client_if,
- const RawAddress& bda,
- uint16_t handle) {
- tBTA_GATTC_RCB* p_clreg;
- tGATT_STATUS status = GATT_ILLEGAL_PARAMETER;
- uint8_t i;
-
- if (!handle) {
- LOG(ERROR) << __func__ << ": registration failed, handle is 0";
- return status;
- }
-
- p_clreg = bta_gattc_cl_get_regcb(client_if);
- if (p_clreg != NULL) {
- for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
- if (p_clreg->notif_reg[i].in_use &&
- p_clreg->notif_reg[i].remote_bda == bda &&
- p_clreg->notif_reg[i].handle == handle) {
- LOG(WARNING) << "notification already registered";
- status = GATT_SUCCESS;
- break;
- }
- }
- if (status != GATT_SUCCESS) {
- for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
- if (!p_clreg->notif_reg[i].in_use) {
- memset((void*)&p_clreg->notif_reg[i], 0,
- sizeof(tBTA_GATTC_NOTIF_REG));
-
- p_clreg->notif_reg[i].in_use = true;
- p_clreg->notif_reg[i].remote_bda = bda;
-
- p_clreg->notif_reg[i].handle = handle;
- status = GATT_SUCCESS;
- break;
- }
- }
- if (i == BTA_GATTC_NOTIF_REG_MAX) {
- status = GATT_NO_RESOURCES;
- LOG(ERROR) << "Max Notification Reached, registration failed.";
- }
- }
- } else {
- LOG(ERROR) << "client_if=" << +client_if << " Not Registered";
- }
-
- return status;
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_DeregisterForNotifications
- *
- * Description This function is called to de-register for notification of a
- * service.
- *
- * Parameters client_if - client interface.
- * remote_bda - target GATT server.
- * handle - GATT characteristic handle.
- *
- * Returns OK if deregistration succeed, otherwise failed.
- *
- ******************************************************************************/
-tGATT_STATUS BTA_GATTC_DeregisterForNotifications(tGATT_IF client_if,
- const RawAddress& bda,
- uint16_t handle) {
- if (!handle) {
- LOG(ERROR) << __func__ << ": deregistration failed, handle is 0";
- return GATT_ILLEGAL_PARAMETER;
- }
-
- tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(client_if);
- if (p_clreg == NULL) {
- LOG(ERROR) << __func__ << " client_if=" << +client_if
- << " not registered bd_addr=" << bda;
- return GATT_ILLEGAL_PARAMETER;
- }
-
- for (int i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
- if (p_clreg->notif_reg[i].in_use &&
- p_clreg->notif_reg[i].remote_bda == bda &&
- p_clreg->notif_reg[i].handle == handle) {
- VLOG(1) << __func__ << " deregistered bd_addr=" << bda;
- memset(&p_clreg->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
- return GATT_SUCCESS;
- }
- }
-
- LOG(ERROR) << __func__ << " registration not found bd_addr=" << bda;
- return GATT_ERROR;
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTC_Refresh
- *
- * Description Refresh the server cache of the remote device
- *
- * Parameters remote_bda: remote device BD address.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_GATTC_Refresh(const RawAddress& remote_bda) {
- do_in_main_thread(FROM_HERE,
- base::Bind(&bta_gattc_process_api_refresh, remote_bda));
-}
diff --git a/bta/gatt/bta_gattc_cache.cc b/bta/gatt/bta_gattc_cache.cc
deleted file mode 100644
index 93d7d37..0000000
--- a/bta/gatt/bta_gattc_cache.cc
+++ /dev/null
@@ -1,1049 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains the GATT client discovery procedures and cache
- * related functions.
- *
- ******************************************************************************/
-
-#define LOG_TAG "bt_bta_gattc"
-
-#include <base/logging.h>
-#include <base/strings/stringprintf.h>
-
-#include <cstdint>
-#include <cstdio>
-#include <sstream>
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bta/gatt/bta_gattc_int.h"
-#include "bta/gatt/database.h"
-#include "osi/include/allocator.h"
-#include "osi/include/log.h"
-#include "stack/btm/btm_sec.h"
-#include "stack/include/gatt_api.h"
-#include "types/bluetooth/uuid.h"
-#include "types/raw_address.h"
-
-using base::StringPrintf;
-using bluetooth::Uuid;
-using gatt::Characteristic;
-using gatt::Database;
-using gatt::DatabaseBuilder;
-using gatt::Descriptor;
-using gatt::IncludedService;
-using gatt::Service;
-using gatt::StoredAttribute;
-
-static void bta_gattc_cache_write(const RawAddress& server_bda,
- const std::vector<StoredAttribute>& attr);
-static tGATT_STATUS bta_gattc_sdp_service_disc(uint16_t conn_id,
- tBTA_GATTC_SERV* p_server_cb);
-const Descriptor* bta_gattc_get_descriptor_srcb(tBTA_GATTC_SERV* p_srcb,
- uint16_t handle);
-const Characteristic* bta_gattc_get_characteristic_srcb(tBTA_GATTC_SERV* p_srcb,
- uint16_t handle);
-static void bta_gattc_explore_srvc_finished(uint16_t conn_id,
- tBTA_GATTC_SERV* p_srvc_cb);
-
-static void bta_gattc_read_db_hash_cmpl(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_OP_CMPL* p_data);
-
-static void bta_gattc_read_ext_prop_desc_cmpl(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_OP_CMPL* p_data);
-
-// define the max retry count for DATABASE_OUT_OF_SYNC
-#define BTA_GATTC_DISCOVER_RETRY_COUNT 2
-
-#define BTA_GATT_SDP_DB_SIZE 4096
-
-#define GATT_CACHE_PREFIX "/data/misc/bluetooth/gatt_cache_"
-#define GATT_CACHE_VERSION 6
-
-static void bta_gattc_generate_cache_file_name(char* buffer, size_t buffer_len,
- const RawAddress& bda) {
- snprintf(buffer, buffer_len, "%s%02x%02x%02x%02x%02x%02x", GATT_CACHE_PREFIX,
- bda.address[0], bda.address[1], bda.address[2], bda.address[3],
- bda.address[4], bda.address[5]);
-}
-
-/*****************************************************************************
- * Constants and data types
- ****************************************************************************/
-
-typedef struct {
- tSDP_DISCOVERY_DB* p_sdp_db;
- uint16_t sdp_conn_id;
-} tBTA_GATTC_CB_DATA;
-
-#if (BTA_GATT_DEBUG == TRUE)
-/* utility functions */
-
-/* debug function to display the server cache */
-static void bta_gattc_display_cache_server(const Database& database) {
- LOG(INFO) << "<=--------------=Start Server Cache =-----------=>";
- std::istringstream iss(database.ToString());
- for (std::string line; std::getline(iss, line);) {
- LOG(INFO) << line;
- }
- LOG(INFO) << "<=--------------=End Server Cache =-----------=>";
-}
-
-/** debug function to display the exploration list */
-static void bta_gattc_display_explore_record(const DatabaseBuilder& database) {
- LOG(INFO) << "<=--------------=Start Explore Queue =-----------=>";
- std::istringstream iss(database.ToString());
- for (std::string line; std::getline(iss, line);) {
- LOG(INFO) << line;
- }
- LOG(INFO) << "<=--------------= End Explore Queue =-----------=>";
-}
-#endif /* BTA_GATT_DEBUG == TRUE */
-
-/** Initialize the database cache and discovery related resources */
-void bta_gattc_init_cache(tBTA_GATTC_SERV* p_srvc_cb) {
- p_srvc_cb->gatt_database = gatt::Database();
- p_srvc_cb->pending_discovery.Clear();
-}
-
-const Service* bta_gattc_find_matching_service(
- const std::list<Service>& services, uint16_t handle) {
- for (const Service& service : services) {
- if (handle >= service.handle && handle <= service.end_handle)
- return &service;
- }
-
- return nullptr;
-}
-
-/** Start primary service discovery */
-tGATT_STATUS bta_gattc_discover_pri_service(uint16_t conn_id,
- tBTA_GATTC_SERV* p_server_cb,
- tGATT_DISC_TYPE disc_type) {
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
- if (!p_clcb) return GATT_ERROR;
-
- if (p_clcb->transport == BT_TRANSPORT_LE) {
- return GATTC_Discover(conn_id, disc_type, 0x0001, 0xFFFF);
- }
-
- // only for Classic transport
- return bta_gattc_sdp_service_disc(conn_id, p_server_cb);
-}
-
-/** start exploring next service, or finish discovery if no more services left
- */
-static void bta_gattc_explore_next_service(uint16_t conn_id,
- tBTA_GATTC_SERV* p_srvc_cb) {
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
- if (!p_clcb) {
- LOG(ERROR) << "unknown conn_id=" << loghex(conn_id);
- return;
- }
-
- if (p_srvc_cb->pending_discovery.StartNextServiceExploration()) {
- const auto& service =
- p_srvc_cb->pending_discovery.CurrentlyExploredService();
- VLOG(1) << "Start service discovery";
-
- /* start discovering included services */
- GATTC_Discover(conn_id, GATT_DISC_INC_SRVC, service.first, service.second);
- return;
- }
- // No more services to discover
-
- // As part of service discovery, read the values of "Characteristic Extended
- // Properties" descriptor
- const auto& descriptors =
- p_srvc_cb->pending_discovery.DescriptorHandlesToRead();
- if (!descriptors.empty()) {
- // set request field to READ_EXT_PROP_DESC
- p_clcb->request_during_discovery =
- BTA_GATTC_DISCOVER_REQ_READ_EXT_PROP_DESC;
-
- if (p_srvc_cb->read_multiple_not_supported || descriptors.size() == 1) {
- tGATT_READ_PARAM read_param{
- .by_handle = {.handle = descriptors.front(),
- .auth_req = GATT_AUTH_REQ_NONE}};
- GATTC_Read(conn_id, GATT_READ_BY_HANDLE, &read_param);
- // asynchronous continuation in bta_gattc_op_cmpl_during_discovery
- return;
- }
-
- // TODO(jpawlowski): as a limit we should use MTU/2 rather than
- // GATT_MAX_READ_MULTI_HANDLES
- /* each descriptor contains just 2 bytes, so response size is same as
- * request size */
- size_t num_handles =
- std::min(descriptors.size(), (size_t)GATT_MAX_READ_MULTI_HANDLES);
-
- tGATT_READ_PARAM read_param;
- memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
-
- read_param.read_multiple.num_handles = num_handles;
- read_param.read_multiple.auth_req = GATT_AUTH_REQ_NONE;
- memcpy(&read_param.read_multiple.handles, descriptors.data(),
- sizeof(uint16_t) * num_handles);
- GATTC_Read(conn_id, GATT_READ_MULTIPLE, &read_param);
-
- // asynchronous continuation in bta_gattc_op_cmpl_during_discovery
- return;
- }
-
- bta_gattc_explore_srvc_finished(conn_id, p_srvc_cb);
-}
-
-static void bta_gattc_explore_srvc_finished(uint16_t conn_id,
- tBTA_GATTC_SERV* p_srvc_cb) {
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
- if (!p_clcb) {
- LOG(ERROR) << "unknown conn_id=" << loghex(conn_id);
- return;
- }
-
- /* no service found at all, the end of server discovery*/
- LOG(INFO) << __func__ << ": service discovery finished";
-
- p_srvc_cb->gatt_database = p_srvc_cb->pending_discovery.Build();
-
-#if (BTA_GATT_DEBUG == TRUE)
- bta_gattc_display_cache_server(p_srvc_cb->gatt_database);
-#endif
- /* save cache to NV */
- p_clcb->p_srcb->state = BTA_GATTC_SERV_SAVE;
-
- if (btm_sec_is_a_bonded_dev(p_srvc_cb->server_bda)) {
- bta_gattc_cache_write(p_clcb->p_srcb->server_bda,
- p_clcb->p_srcb->gatt_database.Serialize());
- }
-
- // After success, reset the count.
- if (bta_gattc_is_robust_caching_enabled()) {
- LOG(INFO) << __func__
- << ": service discovery succeed, reset count to zero, conn_id="
- << loghex(conn_id);
- p_srvc_cb->srvc_disc_count = 0;
- }
-
- bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_SUCCESS);
-}
-
-/** Start discovery for characteristic descriptor */
-void bta_gattc_start_disc_char_dscp(uint16_t conn_id,
- tBTA_GATTC_SERV* p_srvc_cb) {
- VLOG(1) << "starting discover characteristics descriptor";
-
- std::pair<uint16_t, uint16_t> range =
- p_srvc_cb->pending_discovery.NextDescriptorRangeToExplore();
- if (range == DatabaseBuilder::EXPLORE_END) {
- goto descriptor_discovery_done;
- }
-
- if (GATTC_Discover(conn_id, GATT_DISC_CHAR_DSCPT, range.first,
- range.second) != 0) {
- goto descriptor_discovery_done;
- }
- return;
-
-descriptor_discovery_done:
- /* all characteristic has been explored, start with next service if any */
- DVLOG(3) << "all characteristics explored";
-
- bta_gattc_explore_next_service(conn_id, p_srvc_cb);
- return;
-}
-
-/* Process the discovery result from sdp */
-void bta_gattc_sdp_callback(tSDP_STATUS sdp_status, const void* user_data) {
- tBTA_GATTC_CB_DATA* cb_data = (tBTA_GATTC_CB_DATA*)user_data;
- tBTA_GATTC_SERV* p_srvc_cb = bta_gattc_find_scb_by_cid(cb_data->sdp_conn_id);
-
- if (p_srvc_cb == nullptr) {
- LOG(ERROR) << "GATT service discovery is done on unknown connection";
- /* allocated in bta_gattc_sdp_service_disc */
- osi_free(cb_data);
- return;
- }
-
- if ((sdp_status != SDP_SUCCESS) && (sdp_status != SDP_DB_FULL)) {
- bta_gattc_explore_srvc_finished(cb_data->sdp_conn_id, p_srvc_cb);
-
- /* allocated in bta_gattc_sdp_service_disc */
- osi_free(cb_data);
- return;
- }
-
- bool no_pending_disc = !p_srvc_cb->pending_discovery.InProgress();
-
- tSDP_DISC_REC* p_sdp_rec = SDP_FindServiceInDb(cb_data->p_sdp_db, 0, nullptr);
- while (p_sdp_rec != nullptr) {
- /* find a service record, report it */
- Uuid service_uuid;
- if (!SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) continue;
-
- tSDP_PROTOCOL_ELEM pe;
- if (!SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_ATT, &pe))
- continue;
-
- uint16_t start_handle = (uint16_t)pe.params[0];
- uint16_t end_handle = (uint16_t)pe.params[1];
-
-#if (BTA_GATT_DEBUG == TRUE)
- VLOG(1) << "Found ATT service uuid=" << service_uuid
- << ", s_handle=" << loghex(start_handle)
- << ", e_handle=" << loghex(end_handle);
-#endif
-
- if (!GATT_HANDLE_IS_VALID(start_handle) ||
- !GATT_HANDLE_IS_VALID(end_handle)) {
- LOG(ERROR) << "invalid start_handle=" << loghex(start_handle)
- << ", end_handle=" << loghex(end_handle);
- continue;
- }
-
- /* discover services result, add services into a service list */
- p_srvc_cb->pending_discovery.AddService(start_handle, end_handle,
- service_uuid, true);
-
- p_sdp_rec = SDP_FindServiceInDb(cb_data->p_sdp_db, 0, p_sdp_rec);
- }
-
- // If discovery is already pending, no need to call
- // bta_gattc_explore_next_service. Next service will be picked up to discovery
- // once current one is discovered. If discovery is not pending, start one
- if (no_pending_disc) {
- bta_gattc_explore_next_service(cb_data->sdp_conn_id, p_srvc_cb);
- }
-
- /* allocated in bta_gattc_sdp_service_disc */
- osi_free(cb_data);
-}
-
-/* Start DSP Service Discovery */
-static tGATT_STATUS bta_gattc_sdp_service_disc(uint16_t conn_id,
- tBTA_GATTC_SERV* p_server_cb) {
- uint16_t num_attrs = 2;
- uint16_t attr_list[2];
-
- /*
- * On success, cb_data will be freed inside bta_gattc_sdp_callback,
- * otherwise it will be freed within this function.
- */
- tBTA_GATTC_CB_DATA* cb_data = (tBTA_GATTC_CB_DATA*)osi_malloc(
- sizeof(tBTA_GATTC_CB_DATA) + BTA_GATT_SDP_DB_SIZE);
-
- cb_data->p_sdp_db = (tSDP_DISCOVERY_DB*)(cb_data + 1);
- attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
- attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
-
- Uuid uuid = Uuid::From16Bit(UUID_PROTOCOL_ATT);
- SDP_InitDiscoveryDb(cb_data->p_sdp_db, BTA_GATT_SDP_DB_SIZE, 1, &uuid,
- num_attrs, attr_list);
-
- if (!SDP_ServiceSearchAttributeRequest2(
- p_server_cb->server_bda, cb_data->p_sdp_db, &bta_gattc_sdp_callback,
- const_cast<const void*>(static_cast<void*>(cb_data)))) {
- osi_free(cb_data);
- return GATT_ERROR;
- }
-
- cb_data->sdp_conn_id = conn_id;
- return GATT_SUCCESS;
-}
-
-/** operation completed */
-void bta_gattc_op_cmpl_during_discovery(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data) {
- // Currently, there are two cases needed to be handled.
- // 1. Read ext prop descriptor value after service discovery
- // 2. Read db hash before starting service discovery
- switch (p_clcb->request_during_discovery) {
- case BTA_GATTC_DISCOVER_REQ_READ_EXT_PROP_DESC:
- bta_gattc_read_ext_prop_desc_cmpl(p_clcb, &p_data->op_cmpl);
- break;
- case BTA_GATTC_DISCOVER_REQ_READ_DB_HASH:
- if (bta_gattc_is_robust_caching_enabled()) {
- bta_gattc_read_db_hash_cmpl(p_clcb, &p_data->op_cmpl);
- } else {
- // it is not possible here if flag is off, but just in case
- p_clcb->request_during_discovery = BTA_GATTC_DISCOVER_REQ_NONE;
- }
- break;
- case BTA_GATTC_DISCOVER_REQ_NONE:
- default:
- break;
- }
-}
-
-/** callback function to GATT client stack */
-void bta_gattc_disc_res_cback(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
- tGATT_DISC_RES* p_data) {
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
- tBTA_GATTC_SERV* p_srvc_cb = bta_gattc_find_scb_by_cid(conn_id);
-
- if (!p_srvc_cb || !p_clcb || p_clcb->state != BTA_GATTC_DISCOVER_ST) return;
-
- switch (disc_type) {
- case GATT_DISC_SRVC_ALL:
- case GATT_DISC_SRVC_BY_UUID:
- p_srvc_cb->pending_discovery.AddService(
- p_data->handle, p_data->value.group_value.e_handle,
- p_data->value.group_value.service_type, true);
- break;
-
- case GATT_DISC_INC_SRVC:
- p_srvc_cb->pending_discovery.AddIncludedService(
- p_data->handle, p_data->value.incl_service.service_type,
- p_data->value.incl_service.s_handle,
- p_data->value.incl_service.e_handle);
- break;
-
- case GATT_DISC_CHAR:
- p_srvc_cb->pending_discovery.AddCharacteristic(
- p_data->handle, p_data->value.dclr_value.val_handle,
- p_data->value.dclr_value.char_uuid,
- p_data->value.dclr_value.char_prop);
- break;
-
- case GATT_DISC_CHAR_DSCPT:
- p_srvc_cb->pending_discovery.AddDescriptor(p_data->handle, p_data->type);
- break;
-
- case GATT_DISC_MAX:
- default:
- LOG_ERROR("Received illegal discovery item");
- break;
- }
-}
-
-void bta_gattc_disc_cmpl_cback(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
- tGATT_STATUS status) {
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
- tBTA_GATTC_SERV* p_srvc_cb = bta_gattc_find_scb_by_cid(conn_id);
-
- if (p_clcb && (status != GATT_SUCCESS || p_clcb->status != GATT_SUCCESS)) {
- if (status == GATT_SUCCESS) p_clcb->status = status;
-
- // if db out of sync is received, try to start service discovery if possible
- if (bta_gattc_is_robust_caching_enabled() &&
- status == GATT_DATABASE_OUT_OF_SYNC) {
- if (p_srvc_cb &&
- p_srvc_cb->srvc_disc_count < BTA_GATTC_DISCOVER_RETRY_COUNT) {
- p_srvc_cb->srvc_disc_count++;
- p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
- } else {
- LOG(ERROR) << __func__
- << ": retry limit exceeds for db out of sync, conn_id="
- << conn_id;
- }
- }
-
- bta_gattc_sm_execute(p_clcb, BTA_GATTC_DISCOVER_CMPL_EVT, NULL);
- return;
- }
-
- if (!p_srvc_cb) return;
-
- switch (disc_type) {
- case GATT_DISC_SRVC_ALL:
- case GATT_DISC_SRVC_BY_UUID:
-// definition of all services are discovered, now it's time to discover
-// their content
-#if (BTA_GATT_DEBUG == TRUE)
- bta_gattc_display_explore_record(p_srvc_cb->pending_discovery);
-#endif
- bta_gattc_explore_next_service(conn_id, p_srvc_cb);
- break;
-
- case GATT_DISC_INC_SRVC: {
- auto& service = p_srvc_cb->pending_discovery.CurrentlyExploredService();
- /* start discovering characteristic */
- GATTC_Discover(conn_id, GATT_DISC_CHAR, service.first, service.second);
- break;
- }
-
- case GATT_DISC_CHAR: {
-#if (BTA_GATT_DEBUG == TRUE)
- bta_gattc_display_explore_record(p_srvc_cb->pending_discovery);
-#endif
- bta_gattc_start_disc_char_dscp(conn_id, p_srvc_cb);
- break;
- }
-
- case GATT_DISC_CHAR_DSCPT:
- /* start discovering next characteristic for char descriptor */
- bta_gattc_start_disc_char_dscp(conn_id, p_srvc_cb);
- break;
-
- case GATT_DISC_MAX:
- default:
- LOG_ERROR("Received illegal discovery item");
- break;
- }
-}
-
-/** search local cache for matching service record */
-void bta_gattc_search_service(tBTA_GATTC_CLCB* p_clcb, Uuid* p_uuid) {
- for (const Service& service : p_clcb->p_srcb->gatt_database.Services()) {
- if (p_uuid && *p_uuid != service.uuid) continue;
-
-#if (BTA_GATT_DEBUG == TRUE)
- VLOG(1) << __func__ << "found service " << service.uuid
- << " handle:" << +service.handle;
-#endif
- if (!p_clcb->p_rcb->p_cback) continue;
-
- tBTA_GATTC cb_data;
- memset(&cb_data, 0, sizeof(tBTA_GATTC));
- cb_data.srvc_res.conn_id = p_clcb->bta_conn_id;
- cb_data.srvc_res.service_uuid.inst_id = service.handle;
- cb_data.srvc_res.service_uuid.uuid = service.uuid;
-
- (*p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_RES_EVT, &cb_data);
- }
-}
-
-const std::list<Service>* bta_gattc_get_services_srcb(tBTA_GATTC_SERV* p_srcb) {
- if (!p_srcb || p_srcb->gatt_database.IsEmpty()) return NULL;
-
- return &p_srcb->gatt_database.Services();
-}
-
-const std::list<Service>* bta_gattc_get_services(uint16_t conn_id) {
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
-
- if (p_clcb == NULL) return NULL;
-
- tBTA_GATTC_SERV* p_srcb = p_clcb->p_srcb;
-
- return bta_gattc_get_services_srcb(p_srcb);
-}
-
-const Service* bta_gattc_get_service_for_handle_srcb(tBTA_GATTC_SERV* p_srcb,
- uint16_t handle) {
- const std::list<Service>* services = bta_gattc_get_services_srcb(p_srcb);
- if (services == NULL) return NULL;
- return bta_gattc_find_matching_service(*services, handle);
-}
-
-const Service* bta_gattc_get_service_for_handle(uint16_t conn_id,
- uint16_t handle) {
- const std::list<Service>* services = bta_gattc_get_services(conn_id);
- if (services == NULL) return NULL;
-
- return bta_gattc_find_matching_service(*services, handle);
-}
-
-const Characteristic* bta_gattc_get_characteristic_srcb(tBTA_GATTC_SERV* p_srcb,
- uint16_t handle) {
- const Service* service =
- bta_gattc_get_service_for_handle_srcb(p_srcb, handle);
-
- if (!service) return NULL;
-
- for (const Characteristic& charac : service->characteristics) {
- if (handle == charac.value_handle) return &charac;
- }
-
- return NULL;
-}
-
-const Characteristic* bta_gattc_get_characteristic(uint16_t conn_id,
- uint16_t handle) {
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
-
- if (p_clcb == NULL) return NULL;
-
- tBTA_GATTC_SERV* p_srcb = p_clcb->p_srcb;
- return bta_gattc_get_characteristic_srcb(p_srcb, handle);
-}
-
-const Descriptor* bta_gattc_get_descriptor_srcb(tBTA_GATTC_SERV* p_srcb,
- uint16_t handle) {
- const Service* service =
- bta_gattc_get_service_for_handle_srcb(p_srcb, handle);
-
- if (!service) {
- return NULL;
- }
-
- for (const Characteristic& charac : service->characteristics) {
- for (const Descriptor& desc : charac.descriptors) {
- if (handle == desc.handle) return &desc;
- }
- }
-
- return NULL;
-}
-
-const Descriptor* bta_gattc_get_descriptor(uint16_t conn_id, uint16_t handle) {
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
-
- if (p_clcb == NULL) return NULL;
-
- tBTA_GATTC_SERV* p_srcb = p_clcb->p_srcb;
- return bta_gattc_get_descriptor_srcb(p_srcb, handle);
-}
-
-const Characteristic* bta_gattc_get_owning_characteristic_srcb(
- tBTA_GATTC_SERV* p_srcb, uint16_t handle) {
- const Service* service =
- bta_gattc_get_service_for_handle_srcb(p_srcb, handle);
-
- if (!service) return NULL;
-
- for (const Characteristic& charac : service->characteristics) {
- for (const Descriptor& desc : charac.descriptors) {
- if (handle == desc.handle) return &charac;
- }
- }
-
- return NULL;
-}
-
-const Characteristic* bta_gattc_get_owning_characteristic(uint16_t conn_id,
- uint16_t handle) {
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
- if (!p_clcb) return NULL;
-
- return bta_gattc_get_owning_characteristic_srcb(p_clcb->p_srcb, handle);
-}
-
-/* request reading database hash */
-bool bta_gattc_read_db_hash(tBTA_GATTC_CLCB* p_clcb) {
- tGATT_READ_PARAM read_param;
- memset(&read_param, 0, sizeof(tGATT_READ_BY_TYPE));
-
- read_param.char_type.s_handle = 0x0001;
- read_param.char_type.e_handle = 0xFFFF;
- read_param.char_type.uuid = Uuid::From16Bit(GATT_UUID_DATABASE_HASH);
- read_param.char_type.auth_req = GATT_AUTH_REQ_NONE;
- tGATT_STATUS status =
- GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_TYPE, &read_param);
-
- if (status != GATT_SUCCESS) return false;
- p_clcb->request_during_discovery = BTA_GATTC_DISCOVER_REQ_READ_DB_HASH;
-
- return true;
-}
-
-/* handle response of reading database hash */
-static void bta_gattc_read_db_hash_cmpl(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_OP_CMPL* p_data) {
- uint8_t op = (uint8_t)p_data->op_code;
- if (op != GATTC_OPTYPE_READ) {
- VLOG(1) << __func__ << ": op = " << +p_data->hdr.layer_specific;
- return;
- }
- p_clcb->request_during_discovery = BTA_GATTC_DISCOVER_REQ_NONE;
-
- // run match flow only if the status is success
- bool matched = false;
- if (p_data->status == GATT_SUCCESS) {
- // start to compare local hash and remote hash
- uint16_t len = p_data->p_cmpl->att_value.len;
- uint8_t* data = p_data->p_cmpl->att_value.value;
-
- Octet16 remote_hash;
- if (len == remote_hash.size()) {
- uint8_t idx = 0;
- auto it = remote_hash.begin();
- for (; idx < len; idx++, data++, it++) *it = *data;
-
- Octet16 local_hash = p_clcb->p_srcb->gatt_database.Hash();
- matched = (local_hash == remote_hash);
- }
- }
-
- if (matched) {
- LOG(INFO) << __func__ << ": hash is the same, skip service discovery";
- p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
- bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_SUCCESS);
- } else {
- LOG(INFO) << __func__ << ": hash is not the same, start service discovery";
- bta_gattc_start_discover_internal(p_clcb);
- }
-}
-
-/* handle response of reading extended properties descriptor */
-static void bta_gattc_read_ext_prop_desc_cmpl(
- tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_OP_CMPL* p_data) {
- uint8_t op = (uint8_t)p_data->op_code;
- if (op != GATTC_OPTYPE_READ) {
- VLOG(1) << __func__ << ": op = " << +p_data->hdr.layer_specific;
- return;
- }
-
- if (!p_clcb->disc_active) {
- VLOG(1) << __func__ << ": not active in discover state";
- return;
- }
- p_clcb->request_during_discovery = BTA_GATTC_DISCOVER_REQ_NONE;
-
- tBTA_GATTC_SERV* p_srvc_cb = p_clcb->p_srcb;
- const uint8_t status = p_data->status;
-
- if (status == GATT_REQ_NOT_SUPPORTED &&
- !p_srvc_cb->read_multiple_not_supported) {
- // can't do "read multiple request", fall back to "read request"
- p_srvc_cb->read_multiple_not_supported = true;
- bta_gattc_explore_next_service(p_clcb->bta_conn_id, p_srvc_cb);
- return;
- }
-
- if (status != GATT_SUCCESS) {
- LOG(WARNING) << "Discovery on server failed: " << loghex(status);
- bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR);
- return;
- }
-
- const tGATT_VALUE& att_value = p_data->p_cmpl->att_value;
- if (p_srvc_cb->read_multiple_not_supported && att_value.len != 2) {
- // Just one Characteristic Extended Properties value at a time in Read
- // Response
- LOG(WARNING) << __func__ << " Read Response should be just 2 bytes!";
- bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR);
- return;
- }
-
- // Parsing is same for "Read Multiple Response", and for "Read Response"
- const uint8_t* p = att_value.value;
- std::vector<uint16_t> value_of_descriptors;
- while (p < att_value.value + att_value.len) {
- uint16_t extended_properties;
- STREAM_TO_UINT16(extended_properties, p);
- value_of_descriptors.push_back(extended_properties);
- }
-
- bool ret =
- p_srvc_cb->pending_discovery.SetValueOfDescriptors(value_of_descriptors);
- if (!ret) {
- LOG(WARNING) << __func__
- << " Problem setting Extended Properties descriptors values";
- bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR);
- return;
- }
-
- // Continue service discovery
- bta_gattc_explore_next_service(p_clcb->bta_conn_id, p_srvc_cb);
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_fill_gatt_db_el
- *
- * Description fill a btgatt_db_element_t value
- *
- * Returns None.
- *
- ******************************************************************************/
-void bta_gattc_fill_gatt_db_el(btgatt_db_element_t* p_attr,
- bt_gatt_db_attribute_type_t type,
- uint16_t att_handle, uint16_t s_handle,
- uint16_t e_handle, uint16_t id, const Uuid& uuid,
- uint8_t prop) {
- p_attr->type = type;
- p_attr->attribute_handle = att_handle;
- p_attr->start_handle = s_handle;
- p_attr->end_handle = e_handle;
- p_attr->id = id;
- p_attr->properties = prop;
-
- // Permissions are not discoverable using the attribute protocol.
- // Core 5.0, Part F, 3.2.5 Attribute Permissions
- p_attr->permissions = 0;
- p_attr->uuid = uuid;
-}
-
-/*******************************************************************************
- * Returns number of elements inside db from start_handle to end_handle
- ******************************************************************************/
-static size_t bta_gattc_get_db_size(const std::list<Service>& services,
- uint16_t start_handle,
- uint16_t end_handle) {
- if (services.empty()) return 0;
-
- size_t db_size = 0;
-
- for (const Service& service : services) {
- if (service.handle < start_handle) continue;
-
- if (service.end_handle > end_handle) break;
-
- db_size++;
-
- for (const Characteristic& charac : service.characteristics) {
- db_size++;
-
- db_size += charac.descriptors.size();
- }
-
- db_size += service.included_services.size();
- }
-
- return db_size;
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_get_gatt_db_impl
- *
- * Description copy the server GATT database into db parameter.
- *
- * Parameters p_srvc_cb: server.
- * db: output parameter which will contain GATT database copy.
- * Caller is responsible for freeing it.
- * count: output parameter which will contain number of
- * elements in database.
- *
- * Returns None.
- *
- ******************************************************************************/
-static void bta_gattc_get_gatt_db_impl(tBTA_GATTC_SERV* p_srvc_cb,
- uint16_t start_handle,
- uint16_t end_handle,
- btgatt_db_element_t** db, int* count) {
- VLOG(1) << __func__
- << StringPrintf(": start_handle 0x%04x, end_handle 0x%04x",
- start_handle, end_handle);
-
- if (p_srvc_cb->gatt_database.IsEmpty()) {
- *count = 0;
- *db = NULL;
- return;
- }
-
- size_t db_size = bta_gattc_get_db_size(p_srvc_cb->gatt_database.Services(),
- start_handle, end_handle);
-
- void* buffer = osi_malloc(db_size * sizeof(btgatt_db_element_t));
- btgatt_db_element_t* curr_db_attr = (btgatt_db_element_t*)buffer;
-
- for (const Service& service : p_srvc_cb->gatt_database.Services()) {
- if (service.handle < start_handle) continue;
-
- if (service.end_handle > end_handle) break;
-
- bta_gattc_fill_gatt_db_el(curr_db_attr,
- service.is_primary ? BTGATT_DB_PRIMARY_SERVICE
- : BTGATT_DB_SECONDARY_SERVICE,
- 0 /* att_handle */, service.handle,
- service.end_handle, service.handle, service.uuid,
- 0 /* prop */);
- curr_db_attr++;
-
- for (const Characteristic& charac : service.characteristics) {
- bta_gattc_fill_gatt_db_el(curr_db_attr, BTGATT_DB_CHARACTERISTIC,
- charac.value_handle, 0 /* s_handle */,
- 0 /* e_handle */, charac.value_handle,
- charac.uuid, charac.properties);
- btgatt_db_element_t* characteristic = curr_db_attr;
- curr_db_attr++;
-
- for (const Descriptor& desc : charac.descriptors) {
- bta_gattc_fill_gatt_db_el(
- curr_db_attr, BTGATT_DB_DESCRIPTOR, desc.handle, 0 /* s_handle */,
- 0 /* e_handle */, desc.handle, desc.uuid, 0 /* property */);
-
- if (desc.uuid == Uuid::From16Bit(GATT_UUID_CHAR_EXT_PROP)) {
- characteristic->extended_properties =
- desc.characteristic_extended_properties;
- }
- curr_db_attr++;
- }
- }
-
- for (const IncludedService& p_isvc : service.included_services) {
- bta_gattc_fill_gatt_db_el(curr_db_attr, BTGATT_DB_INCLUDED_SERVICE,
- p_isvc.handle, p_isvc.start_handle,
- 0 /* e_handle */, p_isvc.handle, p_isvc.uuid,
- 0 /* property */);
- curr_db_attr++;
- }
- }
-
- *db = (btgatt_db_element_t*)buffer;
- *count = db_size;
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_get_gatt_db
- *
- * Description copy the server GATT database into db parameter.
- *
- * Parameters conn_id: connection ID which identify the server.
- * db: output parameter which will contain GATT database copy.
- * Caller is responsible for freeing it.
- * count: number of elements in database.
- *
- * Returns None.
- *
- ******************************************************************************/
-void bta_gattc_get_gatt_db(uint16_t conn_id, uint16_t start_handle,
- uint16_t end_handle, btgatt_db_element_t** db,
- int* count) {
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
-
- LOG_INFO("%s", __func__);
- if (p_clcb == NULL) {
- LOG(ERROR) << "Unknown conn_id=" << loghex(conn_id);
- return;
- }
-
- if (p_clcb->state != BTA_GATTC_CONN_ST) {
- LOG(ERROR) << "server cache not available, CLCB state=" << +p_clcb->state;
- return;
- }
-
- if (!p_clcb->p_srcb || p_clcb->p_srcb->pending_discovery.InProgress() ||
- p_clcb->p_srcb->gatt_database.IsEmpty()) {
- LOG(ERROR) << "No server cache available";
- return;
- }
-
- bta_gattc_get_gatt_db_impl(p_clcb->p_srcb, start_handle, end_handle, db,
- count);
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_cache_load
- *
- * Description Load GATT cache from storage for server.
- *
- * Parameter p_srcb: pointer to server cache, that will
- * be filled from storage
- * Returns true on success, false otherwise
- *
- ******************************************************************************/
-bool bta_gattc_cache_load(tBTA_GATTC_SERV* p_srcb) {
- char fname[255] = {0};
- bta_gattc_generate_cache_file_name(fname, sizeof(fname), p_srcb->server_bda);
-
- FILE* fd = fopen(fname, "rb");
- if (!fd) {
- LOG(ERROR) << __func__ << ": can't open GATT cache file " << fname
- << " for reading, error: " << strerror(errno);
- return false;
- }
-
- uint16_t cache_ver = 0;
- bool success = false;
- uint16_t num_attr = 0;
-
- if (fread(&cache_ver, sizeof(uint16_t), 1, fd) != 1) {
- LOG(ERROR) << __func__ << ": can't read GATT cache version from: " << fname;
- goto done;
- }
-
- if (cache_ver != GATT_CACHE_VERSION) {
- LOG(ERROR) << __func__ << ": wrong GATT cache version: " << fname;
- goto done;
- }
-
- if (fread(&num_attr, sizeof(uint16_t), 1, fd) != 1) {
- LOG(ERROR) << __func__
- << ": can't read number of GATT attributes: " << fname;
- goto done;
- }
-
- {
- std::vector<StoredAttribute> attr(num_attr);
-
- if (fread(attr.data(), sizeof(StoredAttribute), num_attr, fd) != num_attr) {
- LOG(ERROR) << __func__ << "s: can't read GATT attributes: " << fname;
- goto done;
- }
-
- p_srcb->gatt_database = gatt::Database::Deserialize(attr, &success);
- }
-
-done:
- fclose(fd);
- return success;
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_cache_write
- *
- * Description This callout function is executed by GATT when a server
- * cache is available to save.
- *
- * Parameter server_bda: server bd address of this cache belongs to
- * attr: attributes to save.
- * Returns
- *
- ******************************************************************************/
-static void bta_gattc_cache_write(const RawAddress& server_bda,
- const std::vector<StoredAttribute>& attr) {
- char fname[255] = {0};
- bta_gattc_generate_cache_file_name(fname, sizeof(fname), server_bda);
-
- FILE* fd = fopen(fname, "wb");
- if (!fd) {
- LOG(ERROR) << __func__
- << ": can't open GATT cache file for writing: " << fname;
- return;
- }
-
- uint16_t cache_ver = GATT_CACHE_VERSION;
- if (fwrite(&cache_ver, sizeof(uint16_t), 1, fd) != 1) {
- LOG(ERROR) << __func__ << ": can't write GATT cache version: " << fname;
- fclose(fd);
- return;
- }
-
- uint16_t num_attr = attr.size();
- if (fwrite(&num_attr, sizeof(uint16_t), 1, fd) != 1) {
- LOG(ERROR) << __func__
- << ": can't write GATT cache attribute count: " << fname;
- fclose(fd);
- return;
- }
-
- if (fwrite(attr.data(), sizeof(StoredAttribute), num_attr, fd) != num_attr) {
- LOG(ERROR) << __func__ << ": can't write GATT cache attributes: " << fname;
- fclose(fd);
- return;
- }
-
- fclose(fd);
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_cache_reset
- *
- * Description This callout function is executed by GATTC to reset cache in
- * application
- *
- * Parameter server_bda: server bd address of this cache belongs to
- *
- * Returns void.
- *
- ******************************************************************************/
-void bta_gattc_cache_reset(const RawAddress& server_bda) {
- VLOG(1) << __func__;
- char fname[255] = {0};
- bta_gattc_generate_cache_file_name(fname, sizeof(fname), server_bda);
- unlink(fname);
-}
diff --git a/bta/gatt/bta_gattc_int.h b/bta/gatt/bta_gattc_int.h
deleted file mode 100644
index 06743ed..0000000
--- a/bta/gatt/bta_gattc_int.h
+++ /dev/null
@@ -1,484 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the private file for the file transfer client (FTC).
- *
- ******************************************************************************/
-#ifndef BTA_GATTC_INT_H
-#define BTA_GATTC_INT_H
-
-#include <cstdint>
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bta/gatt/database.h"
-#include "bta/gatt/database_builder.h"
-#include "bta/include/bta_gatt_api.h"
-#include "bta/sys/bta_sys.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/gatt_api.h"
-#include "types/bluetooth/uuid.h"
-#include "types/bt_transport.h"
-#include "types/raw_address.h"
-
-/*****************************************************************************
- * Constants and data types
- ****************************************************************************/
-enum {
- BTA_GATTC_API_OPEN_EVT = BTA_SYS_EVT_START(BTA_ID_GATTC),
- BTA_GATTC_INT_OPEN_FAIL_EVT,
- BTA_GATTC_API_CANCEL_OPEN_EVT,
- BTA_GATTC_INT_CANCEL_OPEN_OK_EVT,
-
- BTA_GATTC_API_READ_EVT,
- BTA_GATTC_API_WRITE_EVT,
- BTA_GATTC_API_EXEC_EVT,
- BTA_GATTC_API_CFG_MTU_EVT,
-
- BTA_GATTC_API_CLOSE_EVT,
-
- BTA_GATTC_API_SEARCH_EVT,
- BTA_GATTC_API_CONFIRM_EVT,
- BTA_GATTC_API_READ_MULTI_EVT,
-
- BTA_GATTC_INT_CONN_EVT,
- BTA_GATTC_INT_DISCOVER_EVT,
- BTA_GATTC_DISCOVER_CMPL_EVT,
- BTA_GATTC_OP_CMPL_EVT,
- BTA_GATTC_INT_DISCONN_EVT
-};
-typedef uint16_t tBTA_GATTC_INT_EVT;
-
-#define BTA_GATTC_SERVICE_CHANGED_LEN 4
-
-/* max client application GATTC can support */
-#ifndef BTA_GATTC_CL_MAX
-#define BTA_GATTC_CL_MAX 32
-#endif
-
-/* max known devices GATTC can support in Bluetooth spec */
-#ifndef BTA_GATTC_KNOWN_SR_MAX
-#define BTA_GATTC_KNOWN_SR_MAX 255
-#endif
-
-#ifndef BTA_GATTC_CLCB_MAX
-#define BTA_GATTC_CLCB_MAX GATT_CL_MAX_LCB
-#endif
-
-#define BTA_GATTC_WRITE_PREPARE GATT_WRITE_PREPARE
-
-/* internal strucutre for GATTC register API */
-typedef struct {
- BT_HDR_RIGID hdr;
- RawAddress remote_bda;
- tGATT_IF client_if;
- bool is_direct;
- tBT_TRANSPORT transport;
- uint8_t initiating_phys;
- bool opportunistic;
-} tBTA_GATTC_API_OPEN;
-
-typedef tBTA_GATTC_API_OPEN tBTA_GATTC_API_CANCEL_OPEN;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- tGATT_AUTH_REQ auth_req;
-
- // read by handle data
- uint16_t handle;
-
- // read by UUID data
- bluetooth::Uuid uuid;
- uint16_t s_handle;
- uint16_t e_handle;
-
- tBTA_GATTC_EVT cmpl_evt;
- GATT_READ_OP_CB read_cb;
- void* read_cb_data;
-} tBTA_GATTC_API_READ;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- tGATT_AUTH_REQ auth_req;
- uint16_t handle;
- tGATT_WRITE_TYPE write_type;
- uint16_t offset;
- uint16_t len;
- uint8_t* p_value;
- GATT_WRITE_OP_CB write_cb;
- void* write_cb_data;
-} tBTA_GATTC_API_WRITE;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- bool is_execute;
-} tBTA_GATTC_API_EXEC;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- uint16_t cid;
-} tBTA_GATTC_API_CONFIRM;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- tGATTC_OPTYPE op_code;
- tGATT_STATUS status;
- tGATT_CL_COMPLETE* p_cmpl;
-} tBTA_GATTC_OP_CMPL;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- bluetooth::Uuid* p_srvc_uuid;
-} tBTA_GATTC_API_SEARCH;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- tGATT_AUTH_REQ auth_req;
- uint8_t num_attr;
- uint16_t handles[GATT_MAX_READ_MULTI_HANDLES];
-} tBTA_GATTC_API_READ_MULTI;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- uint16_t mtu;
- GATT_CONFIGURE_MTU_OP_CB mtu_cb;
- void* mtu_cb_data;
-} tBTA_GATTC_API_CFG_MTU;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- RawAddress remote_bda;
- tGATT_IF client_if;
- uint8_t role;
- tBT_TRANSPORT transport;
- tGATT_DISCONN_REASON reason;
-} tBTA_GATTC_INT_CONN;
-
-typedef union {
- BT_HDR_RIGID hdr;
- tBTA_GATTC_API_OPEN api_conn;
- tBTA_GATTC_API_CANCEL_OPEN api_cancel_conn;
- tBTA_GATTC_API_READ api_read;
- tBTA_GATTC_API_SEARCH api_search;
- tBTA_GATTC_API_WRITE api_write;
- tBTA_GATTC_API_CONFIRM api_confirm;
- tBTA_GATTC_API_EXEC api_exec;
- tBTA_GATTC_API_READ_MULTI api_read_multi;
- tBTA_GATTC_API_CFG_MTU api_mtu;
- tBTA_GATTC_OP_CMPL op_cmpl;
- tBTA_GATTC_INT_CONN int_conn;
-} tBTA_GATTC_DATA;
-
-enum {
- BTA_GATTC_IDLE_ST = 0, /* Idle */
- BTA_GATTC_W4_CONN_ST, /* Wait for connection - (optional) */
- BTA_GATTC_CONN_ST, /* connected state */
- BTA_GATTC_DISCOVER_ST /* discover is in progress */
-};
-typedef uint8_t tBTA_GATTC_STATE;
-
-typedef struct {
- bool in_use;
- RawAddress server_bda;
- bool connected;
-
-#define BTA_GATTC_SERV_IDLE 0
-#define BTA_GATTC_SERV_LOAD 1
-#define BTA_GATTC_SERV_SAVE 2
-#define BTA_GATTC_SERV_DISC 3
-#define BTA_GATTC_SERV_DISC_ACT 4
-
- uint8_t state;
-
- gatt::Database gatt_database;
- uint8_t update_count; /* indication received */
- uint8_t num_clcb; /* number of associated CLCB */
-
- gatt::DatabaseBuilder pending_discovery;
-
- /* used only during service discovery, when reading Extended Characteristic
- * Properties */
- bool read_multiple_not_supported;
-
- uint8_t srvc_hdl_chg; /* service handle change indication pending */
- bool srvc_hdl_db_hash; /* read db hash pending */
- uint8_t srvc_disc_count; /* current discovery retry count */
- uint16_t attr_index; /* cahce NV saving/loading attribute index */
-
- uint16_t mtu;
-} tBTA_GATTC_SERV;
-
-#ifndef BTA_GATTC_NOTIF_REG_MAX
-#define BTA_GATTC_NOTIF_REG_MAX 64
-#endif
-
-typedef struct {
- bool in_use;
- RawAddress remote_bda;
- uint16_t handle;
-} tBTA_GATTC_NOTIF_REG;
-
-typedef struct {
- tBTA_GATTC_CBACK* p_cback;
- bool in_use;
- tGATT_IF client_if; /* client interface with BTE stack for this application */
- uint8_t num_clcb; /* number of associated CLCB */
- bool dereg_pending;
- bluetooth::Uuid app_uuid;
- tBTA_GATTC_NOTIF_REG notif_reg[BTA_GATTC_NOTIF_REG_MAX];
-} tBTA_GATTC_RCB;
-
-/* client channel is a mapping between a BTA client(cl_id) and a remote BD
- * address */
-typedef struct {
- uint16_t bta_conn_id; /* client channel ID, unique for clcb */
- RawAddress bda;
- tBT_TRANSPORT transport; /* channel transport */
- tBTA_GATTC_RCB* p_rcb; /* pointer to the registration CB */
- tBTA_GATTC_SERV* p_srcb; /* server cache CB */
- const tBTA_GATTC_DATA* p_q_cmd; /* command in queue waiting for execution */
-
-// request during discover state
-#define BTA_GATTC_DISCOVER_REQ_NONE 0
-#define BTA_GATTC_DISCOVER_REQ_READ_EXT_PROP_DESC 1
-#define BTA_GATTC_DISCOVER_REQ_READ_DB_HASH 2
-
- uint8_t request_during_discovery; /* request during discover state */
-
-#define BTA_GATTC_NO_SCHEDULE 0
-#define BTA_GATTC_DISC_WAITING 0x01
-#define BTA_GATTC_REQ_WAITING 0x10
-
- uint8_t auto_update; /* auto update is waiting */
- bool disc_active;
- bool in_use;
- tBTA_GATTC_STATE state;
- tGATT_STATUS status;
-} tBTA_GATTC_CLCB;
-
-/* back ground connection tracking information */
-#if GATT_MAX_APPS <= 8
-typedef uint8_t tBTA_GATTC_CIF_MASK;
-#elif GATT_MAX_APPS <= 16
-typedef uint16_t tBTA_GATTC_CIF_MASK;
-#elif GATT_MAX_APPS <= 32
-typedef uint32_t tBTA_GATTC_CIF_MASK;
-#endif
-
-typedef struct {
- bool in_use;
- RawAddress remote_bda;
- tBTA_GATTC_CIF_MASK cif_mask;
-
-} tBTA_GATTC_BG_TCK;
-
-typedef struct {
- bool in_use;
- RawAddress remote_bda;
-} tBTA_GATTC_CONN;
-
-enum {
- BTA_GATTC_STATE_DISABLED,
- BTA_GATTC_STATE_ENABLING,
- BTA_GATTC_STATE_ENABLED,
- BTA_GATTC_STATE_DISABLING
-};
-
-typedef struct {
- uint8_t state;
-
- tBTA_GATTC_CONN conn_track[GATT_MAX_PHY_CHANNEL];
- tBTA_GATTC_BG_TCK bg_track[BTA_GATTC_KNOWN_SR_MAX];
- tBTA_GATTC_RCB cl_rcb[BTA_GATTC_CL_MAX];
-
- tBTA_GATTC_CLCB clcb[BTA_GATTC_CLCB_MAX];
- tBTA_GATTC_SERV known_server[BTA_GATTC_KNOWN_SR_MAX];
-} tBTA_GATTC_CB;
-
-/*****************************************************************************
- * Global data
- ****************************************************************************/
-
-/* GATTC control block */
-extern tBTA_GATTC_CB bta_gattc_cb;
-
-/*****************************************************************************
- * Function prototypes
- ****************************************************************************/
-extern bool bta_gattc_hdl_event(BT_HDR_RIGID* p_msg);
-extern bool bta_gattc_sm_execute(tBTA_GATTC_CLCB* p_clcb, uint16_t event,
- const tBTA_GATTC_DATA* p_data);
-
-/* function processed outside SM */
-extern void bta_gattc_disable();
-extern void bta_gattc_register(const bluetooth::Uuid& app_uuid,
- tBTA_GATTC_CBACK* p_data,
- BtaAppRegisterCallback cb, bool eatt_support);
-extern void bta_gattc_process_api_open(const tBTA_GATTC_DATA* p_msg);
-extern void bta_gattc_process_api_open_cancel(const tBTA_GATTC_DATA* p_msg);
-extern void bta_gattc_deregister(tBTA_GATTC_RCB* p_clreg);
-
-/* function within state machine */
-extern void bta_gattc_open(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_open_fail(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_open_error(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-
-extern void bta_gattc_cancel_open(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_cancel_open_error(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-
-extern void bta_gattc_conn(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-
-extern void bta_gattc_close(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_close_fail(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_disc_close(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-
-extern void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_start_discover_internal(tBTA_GATTC_CLCB* p_clcb);
-extern void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_read(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_write(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_op_cmpl(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_q_cmd(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_search(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_fail(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_confirm(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_execute(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_read_multi(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_ci_open(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_ci_close(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_op_cmpl_during_discovery(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_restart_discover(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_msg);
-extern void bta_gattc_cancel_bk_conn(const tBTA_GATTC_API_CANCEL_OPEN* p_data);
-extern void bta_gattc_send_open_cback(tBTA_GATTC_RCB* p_clreg,
- tGATT_STATUS status,
- const RawAddress& remote_bda,
- uint16_t conn_id, tBT_TRANSPORT transport,
- uint16_t mtu);
-extern void bta_gattc_process_api_refresh(const RawAddress& remote_bda);
-extern void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-extern void bta_gattc_listen(tBTA_GATTC_DATA* p_msg);
-extern void bta_gattc_broadcast(tBTA_GATTC_DATA* p_msg);
-
-/* utility functions */
-extern tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_cif(uint8_t client_if,
- const RawAddress& remote_bda,
- tBT_TRANSPORT transport);
-extern tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_conn_id(uint16_t conn_id);
-extern tBTA_GATTC_CLCB* bta_gattc_clcb_alloc(tGATT_IF client_if,
- const RawAddress& remote_bda,
- tBT_TRANSPORT transport);
-extern void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB* p_clcb);
-extern tBTA_GATTC_CLCB* bta_gattc_find_alloc_clcb(tGATT_IF client_if,
- const RawAddress& remote_bda,
- tBT_TRANSPORT transport);
-extern tBTA_GATTC_RCB* bta_gattc_cl_get_regcb(uint8_t client_if);
-extern tBTA_GATTC_SERV* bta_gattc_find_srcb(const RawAddress& bda);
-extern tBTA_GATTC_SERV* bta_gattc_srcb_alloc(const RawAddress& bda);
-extern tBTA_GATTC_SERV* bta_gattc_find_scb_by_cid(uint16_t conn_id);
-extern tBTA_GATTC_CLCB* bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA* p_msg);
-extern tBTA_GATTC_CLCB* bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA* p_msg);
-
-extern bool bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-
-extern bool bta_gattc_check_notif_registry(tBTA_GATTC_RCB* p_clreg,
- tBTA_GATTC_SERV* p_srcb,
- tBTA_GATTC_NOTIFY* p_notify);
-extern bool bta_gattc_mark_bg_conn(tGATT_IF client_if,
- const RawAddress& remote_bda, bool add);
-extern bool bta_gattc_check_bg_conn(tGATT_IF client_if,
- const RawAddress& remote_bda, uint8_t role);
-extern uint8_t bta_gattc_num_reg_app(void);
-extern void bta_gattc_clear_notif_registration(tBTA_GATTC_SERV* p_srcb,
- uint16_t conn_id,
- uint16_t start_handle,
- uint16_t end_handle);
-extern tBTA_GATTC_SERV* bta_gattc_find_srvr_cache(const RawAddress& bda);
-extern bool bta_gattc_is_robust_caching_enabled();
-
-/* discovery functions */
-extern void bta_gattc_disc_res_cback(uint16_t conn_id,
- tGATT_DISC_TYPE disc_type,
- tGATT_DISC_RES* p_data);
-extern void bta_gattc_disc_cmpl_cback(uint16_t conn_id,
- tGATT_DISC_TYPE disc_type,
- tGATT_STATUS status);
-extern tGATT_STATUS bta_gattc_discover_pri_service(uint16_t conn_id,
- tBTA_GATTC_SERV* p_server_cb,
- tGATT_DISC_TYPE disc_type);
-extern void bta_gattc_search_service(tBTA_GATTC_CLCB* p_clcb,
- bluetooth::Uuid* p_uuid);
-extern const std::list<gatt::Service>* bta_gattc_get_services(uint16_t conn_id);
-extern const gatt::Service* bta_gattc_get_service_for_handle(uint16_t conn_id,
- uint16_t handle);
-const gatt::Characteristic* bta_gattc_get_characteristic_srcb(
- tBTA_GATTC_SERV* p_srcb, uint16_t handle);
-extern const gatt::Service* bta_gattc_get_service_for_handle_srcb(
- tBTA_GATTC_SERV* p_srcb, uint16_t handle);
-extern const gatt::Characteristic* bta_gattc_get_characteristic(
- uint16_t conn_id, uint16_t handle);
-extern const gatt::Descriptor* bta_gattc_get_descriptor(uint16_t conn_id,
- uint16_t handle);
-extern const gatt::Characteristic* bta_gattc_get_owning_characteristic(
- uint16_t conn_id, uint16_t handle);
-extern void bta_gattc_get_gatt_db(uint16_t conn_id, uint16_t start_handle,
- uint16_t end_handle, btgatt_db_element_t** db,
- int* count);
-extern void bta_gattc_init_cache(tBTA_GATTC_SERV* p_srvc_cb);
-extern void bta_gattc_reset_discover_st(tBTA_GATTC_SERV* p_srcb,
- tGATT_STATUS status);
-
-extern tBTA_GATTC_CONN* bta_gattc_conn_alloc(const RawAddress& remote_bda);
-extern tBTA_GATTC_CONN* bta_gattc_conn_find(const RawAddress& remote_bda);
-extern tBTA_GATTC_CONN* bta_gattc_conn_find_alloc(const RawAddress& remote_bda);
-extern bool bta_gattc_conn_dealloc(const RawAddress& remote_bda);
-
-extern bool bta_gattc_cache_load(tBTA_GATTC_SERV* p_srcb);
-extern void bta_gattc_cache_reset(const RawAddress& server_bda);
-
-extern bool bta_gattc_read_db_hash(tBTA_GATTC_CLCB* p_clcb);
-
-#endif /* BTA_GATTC_INT_H */
diff --git a/bta/gatt/bta_gattc_main.cc b/bta/gatt/bta_gattc_main.cc
deleted file mode 100644
index 6b4dfbb..0000000
--- a/bta/gatt/bta_gattc_main.cc
+++ /dev/null
@@ -1,481 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains the GATT client main functions and state machine.
- *
- ******************************************************************************/
-
-#include <base/logging.h>
-#include <base/strings/stringprintf.h>
-
-#include "bt_target.h" // Must be first to define build configuration"
-#include "bta/gatt/bta_gattc_int.h"
-#include "stack/include/bt_hdr.h"
-
-using base::StringPrintf;
-
-/*****************************************************************************
- * Constants and types
- ****************************************************************************/
-
-/* state machine action enumeration list */
-enum {
- BTA_GATTC_OPEN,
- BTA_GATTC_OPEN_FAIL,
- BTA_GATTC_OPEN_ERROR,
- BTA_GATTC_CANCEL_OPEN,
- BTA_GATTC_CANCEL_OPEN_OK,
- BTA_GATTC_CANCEL_OPEN_ERROR,
- BTA_GATTC_CONN,
- BTA_GATTC_START_DISCOVER,
- BTA_GATTC_DISC_CMPL,
- BTA_GATTC_Q_CMD,
- BTA_GATTC_CLOSE,
- BTA_GATTC_CLOSE_FAIL,
- BTA_GATTC_READ,
- BTA_GATTC_WRITE,
- BTA_GATTC_OP_CMPL,
- BTA_GATTC_SEARCH,
- BTA_GATTC_FAIL,
- BTA_GATTC_CONFIRM,
- BTA_GATTC_EXEC,
- BTA_GATTC_READ_MULTI,
- BTA_GATTC_OP_CMPL_DURING_DISCOVERY,
- BTA_GATTC_DISC_CLOSE,
- BTA_GATTC_RESTART_DISCOVER,
- BTA_GATTC_CFG_MTU,
-
- BTA_GATTC_IGNORE
-};
-/* type for action functions */
-typedef void (*tBTA_GATTC_ACTION)(tBTA_GATTC_CLCB* p_clcb,
- const tBTA_GATTC_DATA* p_data);
-
-/* action function list */
-const tBTA_GATTC_ACTION bta_gattc_action[] = {
- bta_gattc_open, /* BTA_GATTC_OPEN */
- bta_gattc_open_fail, /* BTA_GATTC_OPEN_FAIL */
- bta_gattc_open_error, /* BTA_GATTC_OPEN_ERROR */
- bta_gattc_cancel_open, /* BTA_GATTC_CANCEL_OPEN */
- bta_gattc_cancel_open_ok, /* BTA_GATTC_CANCEL_OPEN_OK */
- bta_gattc_cancel_open_error, /* BTA_GATTC_CANCEL_OPEN_ERROR */
- bta_gattc_conn, /* BTA_GATTC_CONN */
- bta_gattc_start_discover, /* BTA_GATTC_START_DISCOVER */
- bta_gattc_disc_cmpl, /* BTA_GATTC_DISC_CMPL */
- bta_gattc_q_cmd, /* BTA_GATTC_Q_CMD */
- bta_gattc_close, /* BTA_GATTC_CLOSE */
- bta_gattc_close_fail, /* BTA_GATTC_CLOSE_FAIL */
- bta_gattc_read, /* BTA_GATTC_READ */
- bta_gattc_write, /* BTA_GATTC_WRITE */
- bta_gattc_op_cmpl, /* BTA_GATTC_OP_CMPL */
- bta_gattc_search, /* BTA_GATTC_SEARCH */
- bta_gattc_fail, /* BTA_GATTC_FAIL */
- bta_gattc_confirm, /* BTA_GATTC_CONFIRM */
- bta_gattc_execute, /* BTA_GATTC_EXEC */
- bta_gattc_read_multi, /* BTA_GATTC_READ_MULTI */
- bta_gattc_op_cmpl_during_discovery, /* BTA_GATTC_OP_CMPL_DURING_DISCOVERY */
- bta_gattc_disc_close, /* BTA_GATTC_DISC_CLOSE */
- bta_gattc_restart_discover, /* BTA_GATTC_RESTART_DISCOVER */
- bta_gattc_cfg_mtu /* BTA_GATTC_CFG_MTU */
-};
-
-/* state table information */
-#define BTA_GATTC_ACTIONS 1 /* number of actions */
-#define BTA_GATTC_NEXT_STATE 1 /* position of next state */
-#define BTA_GATTC_NUM_COLS 2 /* number of columns in state tables */
-
-/* state table for idle state */
-static const uint8_t bta_gattc_st_idle[][BTA_GATTC_NUM_COLS] = {
- /* Event Action 1 Next state */
- /* BTA_GATTC_API_OPEN_EVT */ {BTA_GATTC_OPEN,
- BTA_GATTC_W4_CONN_ST},
- /* BTA_GATTC_INT_OPEN_FAIL_EVT */ {BTA_GATTC_IGNORE,
- BTA_GATTC_IDLE_ST},
- /* BTA_GATTC_API_CANCEL_OPEN_EVT */ {BTA_GATTC_IGNORE,
- BTA_GATTC_IDLE_ST},
- /* BTA_GATTC_INT_CANCEL_OPEN_OK_EVT */ {BTA_GATTC_IGNORE,
- BTA_GATTC_IDLE_ST},
-
- /* BTA_GATTC_API_READ_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
- /* BTA_GATTC_API_WRITE_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
- /* BTA_GATTC_API_EXEC_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
- /* BTA_GATTC_API_CFG_MTU_EVT */ {BTA_GATTC_IGNORE,
- BTA_GATTC_IDLE_ST},
-
- /* BTA_GATTC_API_CLOSE_EVT */ {BTA_GATTC_CLOSE_FAIL,
- BTA_GATTC_IDLE_ST},
-
- /* BTA_GATTC_API_SEARCH_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
- /* BTA_GATTC_API_CONFIRM_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
- /* BTA_GATTC_API_READ_MULTI_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
-
- /* BTA_GATTC_INT_CONN_EVT */ {BTA_GATTC_CONN, BTA_GATTC_CONN_ST},
- /* BTA_GATTC_INT_DISCOVER_EVT */ {BTA_GATTC_IGNORE,
- BTA_GATTC_IDLE_ST},
- /* BTA_GATTC_DISCOVER_CMPL_EVT */ {BTA_GATTC_IGNORE,
- BTA_GATTC_IDLE_ST},
- /* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_IGNORE,
- BTA_GATTC_IDLE_ST},
- /* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
-
-};
-
-/* state table for wait for open state */
-static const uint8_t bta_gattc_st_w4_conn[][BTA_GATTC_NUM_COLS] = {
- /* Event Action 1 Next state */
- /* BTA_GATTC_API_OPEN_EVT */ {BTA_GATTC_OPEN,
- BTA_GATTC_W4_CONN_ST},
- /* BTA_GATTC_INT_OPEN_FAIL_EVT */ {BTA_GATTC_OPEN_FAIL,
- BTA_GATTC_IDLE_ST},
- /* BTA_GATTC_API_CANCEL_OPEN_EVT */ {BTA_GATTC_CANCEL_OPEN,
- BTA_GATTC_W4_CONN_ST},
- /* BTA_GATTC_INT_CANCEL_OPEN_OK_EVT */ {BTA_GATTC_CANCEL_OPEN_OK,
- BTA_GATTC_IDLE_ST},
-
- /* BTA_GATTC_API_READ_EVT */ {BTA_GATTC_FAIL,
- BTA_GATTC_W4_CONN_ST},
- /* BTA_GATTC_API_WRITE_EVT */ {BTA_GATTC_FAIL,
- BTA_GATTC_W4_CONN_ST},
- /* BTA_GATTC_API_EXEC_EVT */ {BTA_GATTC_FAIL,
- BTA_GATTC_W4_CONN_ST},
- /* BTA_GATTC_API_CFG_MTU_EVT */ {BTA_GATTC_IGNORE,
- BTA_GATTC_W4_CONN_ST},
-
- /* BTA_GATTC_API_CLOSE_EVT */ {BTA_GATTC_CANCEL_OPEN,
- BTA_GATTC_W4_CONN_ST},
-
- /* BTA_GATTC_API_SEARCH_EVT */ {BTA_GATTC_FAIL,
- BTA_GATTC_W4_CONN_ST},
- /* BTA_GATTC_API_CONFIRM_EVT */ {BTA_GATTC_FAIL,
- BTA_GATTC_W4_CONN_ST},
- /* BTA_GATTC_API_READ_MULTI_EVT */ {BTA_GATTC_FAIL,
- BTA_GATTC_W4_CONN_ST},
-
- /* BTA_GATTC_INT_CONN_EVT */ {BTA_GATTC_CONN, BTA_GATTC_CONN_ST},
- /* BTA_GATTC_INT_DISCOVER_EVT */ {BTA_GATTC_IGNORE,
- BTA_GATTC_W4_CONN_ST},
- /* BTA_GATTC_DISCOVER_CMPL_EVT */ {BTA_GATTC_IGNORE,
- BTA_GATTC_W4_CONN_ST},
- /* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_IGNORE,
- BTA_GATTC_W4_CONN_ST},
- /* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_OPEN_FAIL,
- BTA_GATTC_IDLE_ST},
-
-};
-
-/* state table for open state */
-static const uint8_t bta_gattc_st_connected[][BTA_GATTC_NUM_COLS] = {
- /* Event Action 1 Next state */
- /* BTA_GATTC_API_OPEN_EVT */ {BTA_GATTC_OPEN, BTA_GATTC_CONN_ST},
- /* BTA_GATTC_INT_OPEN_FAIL_EVT */ {BTA_GATTC_IGNORE,
- BTA_GATTC_CONN_ST},
- /* BTA_GATTC_API_CANCEL_OPEN_EVT */ {BTA_GATTC_CANCEL_OPEN_ERROR,
- BTA_GATTC_CONN_ST},
- /* BTA_GATTC_INT_CANCEL_OPEN_OK_EVT */ {BTA_GATTC_IGNORE,
- BTA_GATTC_CONN_ST},
-
- /* BTA_GATTC_API_READ_EVT */ {BTA_GATTC_READ, BTA_GATTC_CONN_ST},
- /* BTA_GATTC_API_WRITE_EVT */ {BTA_GATTC_WRITE, BTA_GATTC_CONN_ST},
- /* BTA_GATTC_API_EXEC_EVT */ {BTA_GATTC_EXEC, BTA_GATTC_CONN_ST},
- /* BTA_GATTC_API_CFG_MTU_EVT */ {BTA_GATTC_CFG_MTU,
- BTA_GATTC_CONN_ST},
-
- /* BTA_GATTC_API_CLOSE_EVT */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST},
-
- /* BTA_GATTC_API_SEARCH_EVT */ {BTA_GATTC_SEARCH,
- BTA_GATTC_CONN_ST},
- /* BTA_GATTC_API_CONFIRM_EVT */ {BTA_GATTC_CONFIRM,
- BTA_GATTC_CONN_ST},
- /* BTA_GATTC_API_READ_MULTI_EVT */ {BTA_GATTC_READ_MULTI,
- BTA_GATTC_CONN_ST},
-
- /* BTA_GATTC_INT_CONN_EVT */ {BTA_GATTC_IGNORE,
- BTA_GATTC_CONN_ST},
- /* BTA_GATTC_INT_DISCOVER_EVT */ {BTA_GATTC_START_DISCOVER,
- BTA_GATTC_DISCOVER_ST},
- /* BTA_GATTC_DISCOVER_CMPL_EVT */ {BTA_GATTC_IGNORE,
- BTA_GATTC_CONN_ST},
- /* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_OP_CMPL,
- BTA_GATTC_CONN_ST},
-
- /* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST},
-
-};
-
-/* state table for discover state */
-static const uint8_t bta_gattc_st_discover[][BTA_GATTC_NUM_COLS] = {
- /* Event Action 1 Next state */
- /* BTA_GATTC_API_OPEN_EVT */ {BTA_GATTC_OPEN,
- BTA_GATTC_DISCOVER_ST},
- /* BTA_GATTC_INT_OPEN_FAIL_EVT */ {BTA_GATTC_IGNORE,
- BTA_GATTC_DISCOVER_ST},
- /* BTA_GATTC_API_CANCEL_OPEN_EVT */ {BTA_GATTC_CANCEL_OPEN_ERROR,
- BTA_GATTC_DISCOVER_ST},
- /* BTA_GATTC_INT_CANCEL_OPEN_OK_EVT */ {BTA_GATTC_FAIL,
- BTA_GATTC_DISCOVER_ST},
-
- /* BTA_GATTC_API_READ_EVT */ {BTA_GATTC_Q_CMD,
- BTA_GATTC_DISCOVER_ST},
- /* BTA_GATTC_API_WRITE_EVT */ {BTA_GATTC_Q_CMD,
- BTA_GATTC_DISCOVER_ST},
- /* BTA_GATTC_API_EXEC_EVT */ {BTA_GATTC_Q_CMD,
- BTA_GATTC_DISCOVER_ST},
- /* BTA_GATTC_API_CFG_MTU_EVT */ {BTA_GATTC_Q_CMD,
- BTA_GATTC_DISCOVER_ST},
-
- /* BTA_GATTC_API_CLOSE_EVT */ {BTA_GATTC_DISC_CLOSE,
- BTA_GATTC_DISCOVER_ST},
-
- /* BTA_GATTC_API_SEARCH_EVT */ {BTA_GATTC_Q_CMD,
- BTA_GATTC_DISCOVER_ST},
- /* BTA_GATTC_API_CONFIRM_EVT */ {BTA_GATTC_CONFIRM,
- BTA_GATTC_DISCOVER_ST},
- /* BTA_GATTC_API_READ_MULTI_EVT */ {BTA_GATTC_Q_CMD,
- BTA_GATTC_DISCOVER_ST},
-
- /* BTA_GATTC_INT_CONN_EVT */ {BTA_GATTC_CONN,
- BTA_GATTC_DISCOVER_ST},
- /* BTA_GATTC_INT_DISCOVER_EVT */ {BTA_GATTC_RESTART_DISCOVER,
- BTA_GATTC_DISCOVER_ST},
- /* BTA_GATTC_DISCOVER_CMPL_EVT */ {BTA_GATTC_DISC_CMPL,
- BTA_GATTC_CONN_ST},
- /* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_OP_CMPL_DURING_DISCOVERY,
- BTA_GATTC_DISCOVER_ST},
- /* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST},
-
-};
-
-/* type for state table */
-typedef const uint8_t (*tBTA_GATTC_ST_TBL)[BTA_GATTC_NUM_COLS];
-
-/* state table */
-const tBTA_GATTC_ST_TBL bta_gattc_st_tbl[] = {
- bta_gattc_st_idle, /* BTA_GATTC_IDLE_ST */
- bta_gattc_st_w4_conn, /* BTA_GATTC_W4_CONN_ST */
- bta_gattc_st_connected, /* BTA_GATTC_CONN_ST */
- bta_gattc_st_discover /* BTA_GATTC_DISCOVER_ST */
-};
-
-/*****************************************************************************
- * Global data
- ****************************************************************************/
-
-/* GATTC control block */
-tBTA_GATTC_CB bta_gattc_cb;
-
-#if (BTA_GATT_DEBUG == TRUE)
-static const char* gattc_evt_code(tBTA_GATTC_INT_EVT evt_code);
-static const char* gattc_state_code(tBTA_GATTC_STATE state_code);
-#endif
-
-/*******************************************************************************
- *
- * Function bta_gattc_sm_execute
- *
- * Description State machine event handling function for GATTC
- *
- *
- * Returns bool : true if queued client request buffer can be
- * immediately released, else false
- *
- ******************************************************************************/
-bool bta_gattc_sm_execute(tBTA_GATTC_CLCB* p_clcb, uint16_t event,
- const tBTA_GATTC_DATA* p_data) {
- tBTA_GATTC_ST_TBL state_table;
- uint8_t action;
- int i;
- bool rt = true;
- tBTA_GATTC_STATE in_state = p_clcb->state;
- uint16_t in_event = event;
-#if (BTA_GATT_DEBUG == TRUE)
- VLOG(1) << StringPrintf("%s: State 0x%02x [%s], Event 0x%x[%s]", __func__,
- in_state, gattc_state_code(in_state), in_event,
- gattc_evt_code(in_event));
-#else
- VLOG(1) << StringPrintf("%s: State 0x%02x, Event 0x%x", __func__, in_state,
- in_event);
-#endif
-
- /* look up the state table for the current state */
- state_table = bta_gattc_st_tbl[p_clcb->state];
-
- event &= 0x00FF;
-
- /* set next state */
- p_clcb->state = state_table[event][BTA_GATTC_NEXT_STATE];
-
- /* execute action functions */
- for (i = 0; i < BTA_GATTC_ACTIONS; i++) {
- action = state_table[event][i];
- if (action != BTA_GATTC_IGNORE) {
- (*bta_gattc_action[action])(p_clcb, p_data);
- if (p_clcb->p_q_cmd == p_data) {
- /* buffer is queued, don't free in the bta dispatcher.
- * we free it ourselves when a completion event is received.
- */
- rt = false;
- }
- } else {
- break;
- }
- }
-
-#if (BTA_GATT_DEBUG == TRUE)
- if (in_state != p_clcb->state) {
- VLOG(1) << StringPrintf("GATTC State Change: [%s] -> [%s] after Event [%s]",
- gattc_state_code(in_state),
- gattc_state_code(p_clcb->state),
- gattc_evt_code(in_event));
- }
-#else
- VLOG(1) << StringPrintf(
- "%s: GATTC State Change: 0x%02x -> 0x%02x after Event 0x%x", __func__,
- in_state, p_clcb->state, in_event);
-#endif
- return rt;
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_hdl_event
- *
- * Description GATT client main event handling function.
- *
- *
- * Returns bool
- *
- ******************************************************************************/
-bool bta_gattc_hdl_event(BT_HDR_RIGID* p_msg) {
- tBTA_GATTC_CLCB* p_clcb = NULL;
- bool rt = true;
-#if (BTA_GATT_DEBUG == TRUE)
- VLOG(1) << __func__ << ": Event:" << gattc_evt_code(p_msg->event);
-#endif
- switch (p_msg->event) {
-
- case BTA_GATTC_API_OPEN_EVT:
- bta_gattc_process_api_open((tBTA_GATTC_DATA*)p_msg);
- break;
-
- case BTA_GATTC_API_CANCEL_OPEN_EVT:
- bta_gattc_process_api_open_cancel((tBTA_GATTC_DATA*)p_msg);
- break;
-
- default:
- if (p_msg->event == BTA_GATTC_INT_CONN_EVT)
- p_clcb = bta_gattc_find_int_conn_clcb((tBTA_GATTC_DATA*)p_msg);
- else if (p_msg->event == BTA_GATTC_INT_DISCONN_EVT)
- p_clcb = bta_gattc_find_int_disconn_clcb((tBTA_GATTC_DATA*)p_msg);
- else
- p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->layer_specific);
-
- if (p_clcb != NULL) {
- rt = bta_gattc_sm_execute(p_clcb, p_msg->event,
- (const tBTA_GATTC_DATA*)p_msg);
- } else {
- VLOG(1) << "Ignore unknown conn ID: " << +p_msg->layer_specific;
- }
-
- break;
- }
-
- return rt;
-}
-
-/*****************************************************************************
- * Debug Functions
- ****************************************************************************/
-#if (BTA_GATT_DEBUG == TRUE)
-
-/*******************************************************************************
- *
- * Function gattc_evt_code
- *
- * Description
- *
- * Returns void
- *
- ******************************************************************************/
-static const char* gattc_evt_code(tBTA_GATTC_INT_EVT evt_code) {
- switch (evt_code) {
- case BTA_GATTC_API_OPEN_EVT:
- return "BTA_GATTC_API_OPEN_EVT";
- case BTA_GATTC_INT_OPEN_FAIL_EVT:
- return "BTA_GATTC_INT_OPEN_FAIL_EVT";
- case BTA_GATTC_API_CANCEL_OPEN_EVT:
- return "BTA_GATTC_API_CANCEL_OPEN_EVT";
- case BTA_GATTC_INT_CANCEL_OPEN_OK_EVT:
- return "BTA_GATTC_INT_CANCEL_OPEN_OK_EVT";
- case BTA_GATTC_API_READ_EVT:
- return "BTA_GATTC_API_READ_EVT";
- case BTA_GATTC_API_WRITE_EVT:
- return "BTA_GATTC_API_WRITE_EVT";
- case BTA_GATTC_API_EXEC_EVT:
- return "BTA_GATTC_API_EXEC_EVT";
- case BTA_GATTC_API_CLOSE_EVT:
- return "BTA_GATTC_API_CLOSE_EVT";
- case BTA_GATTC_API_SEARCH_EVT:
- return "BTA_GATTC_API_SEARCH_EVT";
- case BTA_GATTC_API_CONFIRM_EVT:
- return "BTA_GATTC_API_CONFIRM_EVT";
- case BTA_GATTC_API_READ_MULTI_EVT:
- return "BTA_GATTC_API_READ_MULTI_EVT";
- case BTA_GATTC_INT_CONN_EVT:
- return "BTA_GATTC_INT_CONN_EVT";
- case BTA_GATTC_INT_DISCOVER_EVT:
- return "BTA_GATTC_INT_DISCOVER_EVT";
- case BTA_GATTC_DISCOVER_CMPL_EVT:
- return "BTA_GATTC_DISCOVER_CMPL_EVT";
- case BTA_GATTC_OP_CMPL_EVT:
- return "BTA_GATTC_OP_CMPL_EVT";
- case BTA_GATTC_INT_DISCONN_EVT:
- return "BTA_GATTC_INT_DISCONN_EVT";
- case BTA_GATTC_API_CFG_MTU_EVT:
- return "BTA_GATTC_API_CFG_MTU_EVT";
- default:
- return "unknown GATTC event code";
- }
-}
-
-/*******************************************************************************
- *
- * Function gattc_state_code
- *
- * Description
- *
- * Returns void
- *
- ******************************************************************************/
-static const char* gattc_state_code(tBTA_GATTC_STATE state_code) {
- switch (state_code) {
- case BTA_GATTC_IDLE_ST:
- return "GATTC_IDLE_ST";
- case BTA_GATTC_W4_CONN_ST:
- return "GATTC_W4_CONN_ST";
- case BTA_GATTC_CONN_ST:
- return "GATTC_CONN_ST";
- case BTA_GATTC_DISCOVER_ST:
- return "GATTC_DISCOVER_ST";
- default:
- return "unknown GATTC state code";
- }
-}
-
-#endif /* Debug Functions */
diff --git a/bta/gatt/bta_gattc_queue.cc b/bta/gatt/bta_gattc_queue.cc
deleted file mode 100644
index b4c4f51..0000000
--- a/bta/gatt/bta_gattc_queue.cc
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#include "bta_gatt_queue.h"
-
-#include <list>
-#include <unordered_map>
-#include <unordered_set>
-
-#include "osi/include/allocator.h"
-
-#include <base/logging.h>
-
-using gatt_operation = BtaGattQueue::gatt_operation;
-
-constexpr uint8_t GATT_READ_CHAR = 1;
-constexpr uint8_t GATT_READ_DESC = 2;
-constexpr uint8_t GATT_WRITE_CHAR = 3;
-constexpr uint8_t GATT_WRITE_DESC = 4;
-constexpr uint8_t GATT_CONFIG_MTU = 5;
-
-struct gatt_read_op_data {
- GATT_READ_OP_CB cb;
- void* cb_data;
-};
-
-std::unordered_map<uint16_t, std::list<gatt_operation>>
- BtaGattQueue::gatt_op_queue;
-std::unordered_set<uint16_t> BtaGattQueue::gatt_op_queue_executing;
-
-void BtaGattQueue::mark_as_not_executing(uint16_t conn_id) {
- gatt_op_queue_executing.erase(conn_id);
-}
-
-void BtaGattQueue::gatt_read_op_finished(uint16_t conn_id, tGATT_STATUS status,
- uint16_t handle, uint16_t len,
- uint8_t* value, void* data) {
- gatt_read_op_data* tmp = (gatt_read_op_data*)data;
- GATT_READ_OP_CB tmp_cb = tmp->cb;
- void* tmp_cb_data = tmp->cb_data;
-
- osi_free(data);
-
- mark_as_not_executing(conn_id);
- gatt_execute_next_op(conn_id);
-
- if (tmp_cb) {
- tmp_cb(conn_id, status, handle, len, value, tmp_cb_data);
- return;
- }
-}
-
-struct gatt_write_op_data {
- GATT_WRITE_OP_CB cb;
- void* cb_data;
-};
-
-void BtaGattQueue::gatt_write_op_finished(uint16_t conn_id, tGATT_STATUS status,
- uint16_t handle, uint16_t len,
- const uint8_t* value, void* data) {
- gatt_write_op_data* tmp = (gatt_write_op_data*)data;
- GATT_WRITE_OP_CB tmp_cb = tmp->cb;
- void* tmp_cb_data = tmp->cb_data;
-
- osi_free(data);
-
- mark_as_not_executing(conn_id);
- gatt_execute_next_op(conn_id);
-
- if (tmp_cb) {
- tmp_cb(conn_id, status, handle, len, value, tmp_cb_data);
- return;
- }
-}
-
-struct gatt_configure_mtu_op_data {
- GATT_CONFIGURE_MTU_OP_CB cb;
- void* cb_data;
-};
-
-void BtaGattQueue::gatt_configure_mtu_op_finished(uint16_t conn_id,
- tGATT_STATUS status,
- void* data) {
- gatt_configure_mtu_op_data* tmp = (gatt_configure_mtu_op_data*)data;
- GATT_CONFIGURE_MTU_OP_CB tmp_cb = tmp->cb;
- void* tmp_cb_data = tmp->cb_data;
-
- osi_free(data);
-
- mark_as_not_executing(conn_id);
- gatt_execute_next_op(conn_id);
-
- if (tmp_cb) {
- tmp_cb(conn_id, status, tmp_cb_data);
- return;
- }
-}
-
-void BtaGattQueue::gatt_execute_next_op(uint16_t conn_id) {
- APPL_TRACE_DEBUG("%s: conn_id=0x%x", __func__, conn_id);
- if (gatt_op_queue.empty()) {
- APPL_TRACE_DEBUG("%s: op queue is empty", __func__);
- return;
- }
-
- auto map_ptr = gatt_op_queue.find(conn_id);
- if (map_ptr == gatt_op_queue.end() || map_ptr->second.empty()) {
- APPL_TRACE_DEBUG("%s: no more operations queued for conn_id %d", __func__,
- conn_id);
- return;
- }
-
- if (gatt_op_queue_executing.count(conn_id)) {
- APPL_TRACE_DEBUG("%s: can't enqueue next op, already executing", __func__);
- return;
- }
-
- gatt_op_queue_executing.insert(conn_id);
-
- std::list<gatt_operation>& gatt_ops = map_ptr->second;
-
- gatt_operation& op = gatt_ops.front();
-
- if (op.type == GATT_READ_CHAR) {
- gatt_read_op_data* data =
- (gatt_read_op_data*)osi_malloc(sizeof(gatt_read_op_data));
- data->cb = op.read_cb;
- data->cb_data = op.read_cb_data;
- BTA_GATTC_ReadCharacteristic(conn_id, op.handle, GATT_AUTH_REQ_NONE,
- gatt_read_op_finished, data);
-
- } else if (op.type == GATT_READ_DESC) {
- gatt_read_op_data* data =
- (gatt_read_op_data*)osi_malloc(sizeof(gatt_read_op_data));
- data->cb = op.read_cb;
- data->cb_data = op.read_cb_data;
- BTA_GATTC_ReadCharDescr(conn_id, op.handle, GATT_AUTH_REQ_NONE,
- gatt_read_op_finished, data);
-
- } else if (op.type == GATT_WRITE_CHAR) {
- gatt_write_op_data* data =
- (gatt_write_op_data*)osi_malloc(sizeof(gatt_write_op_data));
- data->cb = op.write_cb;
- data->cb_data = op.write_cb_data;
- BTA_GATTC_WriteCharValue(conn_id, op.handle, op.write_type,
- std::move(op.value), GATT_AUTH_REQ_NONE,
- gatt_write_op_finished, data);
-
- } else if (op.type == GATT_WRITE_DESC) {
- gatt_write_op_data* data =
- (gatt_write_op_data*)osi_malloc(sizeof(gatt_write_op_data));
- data->cb = op.write_cb;
- data->cb_data = op.write_cb_data;
- BTA_GATTC_WriteCharDescr(conn_id, op.handle, std::move(op.value),
- GATT_AUTH_REQ_NONE, gatt_write_op_finished, data);
- } else if (op.type == GATT_CONFIG_MTU) {
- gatt_configure_mtu_op_data* data =
- (gatt_configure_mtu_op_data*)osi_malloc(sizeof(gatt_configure_mtu_op_data));
- data->cb = op.mtu_cb;
- data->cb_data = op.mtu_cb_data;
- BTA_GATTC_ConfigureMTU(conn_id, static_cast<uint16_t>(op.value[0] |
- (op.value[1] << 8)),
- gatt_configure_mtu_op_finished, data);
- }
-
- gatt_ops.pop_front();
-}
-
-void BtaGattQueue::Clean(uint16_t conn_id) {
- gatt_op_queue.erase(conn_id);
- gatt_op_queue_executing.erase(conn_id);
-}
-
-void BtaGattQueue::ReadCharacteristic(uint16_t conn_id, uint16_t handle,
- GATT_READ_OP_CB cb, void* cb_data) {
- gatt_op_queue[conn_id].push_back({.type = GATT_READ_CHAR,
- .handle = handle,
- .read_cb = cb,
- .read_cb_data = cb_data});
- gatt_execute_next_op(conn_id);
-}
-
-void BtaGattQueue::ReadDescriptor(uint16_t conn_id, uint16_t handle,
- GATT_READ_OP_CB cb, void* cb_data) {
- gatt_op_queue[conn_id].push_back({.type = GATT_READ_DESC,
- .handle = handle,
- .read_cb = cb,
- .read_cb_data = cb_data});
- gatt_execute_next_op(conn_id);
-}
-
-void BtaGattQueue::WriteCharacteristic(uint16_t conn_id, uint16_t handle,
- std::vector<uint8_t> value,
- tGATT_WRITE_TYPE write_type,
- GATT_WRITE_OP_CB cb, void* cb_data) {
- gatt_op_queue[conn_id].push_back({.type = GATT_WRITE_CHAR,
- .handle = handle,
- .write_cb = cb,
- .write_cb_data = cb_data,
- .write_type = write_type,
- .value = std::move(value)});
- gatt_execute_next_op(conn_id);
-}
-
-void BtaGattQueue::WriteDescriptor(uint16_t conn_id, uint16_t handle,
- std::vector<uint8_t> value,
- tGATT_WRITE_TYPE write_type,
- GATT_WRITE_OP_CB cb, void* cb_data) {
- gatt_op_queue[conn_id].push_back({.type = GATT_WRITE_DESC,
- .handle = handle,
- .write_cb = cb,
- .write_cb_data = cb_data,
- .write_type = write_type,
- .value = std::move(value)});
- gatt_execute_next_op(conn_id);
-}
-
-void BtaGattQueue::ConfigureMtu(uint16_t conn_id, uint16_t mtu) {
- LOG(INFO) << __func__ << ", mtu: " << static_cast<int>(mtu);
- std::vector<uint8_t> value = {static_cast<uint8_t>(mtu & 0xff),
- static_cast<uint8_t>(mtu >> 8)};
- gatt_op_queue[conn_id].push_back({.type = GATT_CONFIG_MTU,
- .value = std::move(value)});
- gatt_execute_next_op(conn_id);
-}
diff --git a/bta/gatt/bta_gattc_utils.cc b/bta/gatt/bta_gattc_utils.cc
deleted file mode 100644
index ed67729..0000000
--- a/bta/gatt/bta_gattc_utils.cc
+++ /dev/null
@@ -1,680 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains the GATT client utility function.
- *
- ******************************************************************************/
-
-#define LOG_TAG "bt_bta_gattc"
-
-#include <cstdint>
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bta/gatt/bta_gattc_int.h"
-#include "device/include/controller.h"
-#include "gd/common/init_flags.h"
-#include "osi/include/allocator.h"
-#include "types/bt_transport.h"
-#include "types/hci_role.h"
-#include "types/raw_address.h"
-
-#include <base/logging.h>
-
-static uint8_t ble_acceptlist_size() {
- const controller_t* controller = controller_get_interface();
- if (!controller->supports_ble()) {
- return 0;
- }
- return controller->get_ble_acceptlist_size();
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_cl_get_regcb
- *
- * Description get registration control block by client interface.
- *
- * Returns pointer to the regcb
- *
- ******************************************************************************/
-tBTA_GATTC_RCB* bta_gattc_cl_get_regcb(uint8_t client_if) {
- uint8_t i = 0;
- tBTA_GATTC_RCB* p_clrcb = &bta_gattc_cb.cl_rcb[0];
-
- for (i = 0; i < BTA_GATTC_CL_MAX; i++, p_clrcb++) {
- if (p_clrcb->in_use && p_clrcb->client_if == client_if) return p_clrcb;
- }
- return NULL;
-}
-/*******************************************************************************
- *
- * Function bta_gattc_num_reg_app
- *
- * Description find the number of registered application.
- *
- * Returns pointer to the regcb
- *
- ******************************************************************************/
-uint8_t bta_gattc_num_reg_app(void) {
- uint8_t i = 0, j = 0;
-
- for (i = 0; i < BTA_GATTC_CL_MAX; i++) {
- if (bta_gattc_cb.cl_rcb[i].in_use) j++;
- }
- return j;
-}
-/*******************************************************************************
- *
- * Function bta_gattc_find_clcb_by_cif
- *
- * Description get clcb by client interface and remote bd adddress
- *
- * Returns pointer to the clcb
- *
- ******************************************************************************/
-tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_cif(uint8_t client_if,
- const RawAddress& remote_bda,
- tBT_TRANSPORT transport) {
- tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0];
- uint8_t i;
-
- for (i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) {
- if (p_clcb->in_use && p_clcb->p_rcb->client_if == client_if &&
- p_clcb->transport == transport && p_clcb->bda == remote_bda)
- return p_clcb;
- }
- return NULL;
-}
-/*******************************************************************************
- *
- * Function bta_gattc_find_clcb_by_conn_id
- *
- * Description get clcb by connection ID
- *
- * Returns pointer to the clcb
- *
- ******************************************************************************/
-tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_conn_id(uint16_t conn_id) {
- tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0];
- uint8_t i;
-
- for (i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) {
- if (p_clcb->in_use && p_clcb->bta_conn_id == conn_id) return p_clcb;
- }
- return NULL;
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_clcb_alloc
- *
- * Description allocate CLCB
- *
- * Returns pointer to the clcb
- *
- ******************************************************************************/
-tBTA_GATTC_CLCB* bta_gattc_clcb_alloc(tGATT_IF client_if,
- const RawAddress& remote_bda,
- tBT_TRANSPORT transport) {
- uint8_t i_clcb = 0;
- tBTA_GATTC_CLCB* p_clcb = NULL;
-
- for (i_clcb = 0; i_clcb < BTA_GATTC_CLCB_MAX; i_clcb++) {
- if (!bta_gattc_cb.clcb[i_clcb].in_use) {
-#if (BTA_GATT_DEBUG == TRUE)
- VLOG(1) << __func__ << ": found clcb:" << +i_clcb << " available";
-#endif
- p_clcb = &bta_gattc_cb.clcb[i_clcb];
- p_clcb->in_use = true;
- p_clcb->status = GATT_SUCCESS;
- p_clcb->transport = transport;
- p_clcb->bda = remote_bda;
-
- p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if);
-
- p_clcb->p_srcb = bta_gattc_find_srcb(remote_bda);
- if (p_clcb->p_srcb == NULL)
- p_clcb->p_srcb = bta_gattc_srcb_alloc(remote_bda);
-
- if (p_clcb->p_rcb != NULL && p_clcb->p_srcb != NULL) {
- p_clcb->p_srcb->num_clcb++;
- p_clcb->p_rcb->num_clcb++;
- } else {
- /* release this clcb if clcb or srcb allocation failed */
- p_clcb->in_use = false;
- p_clcb = NULL;
- }
- break;
- }
- }
- return p_clcb;
-}
-/*******************************************************************************
- *
- * Function bta_gattc_find_alloc_clcb
- *
- * Description find or allocate CLCB if not found.
- *
- * Returns pointer to the clcb
- *
- ******************************************************************************/
-tBTA_GATTC_CLCB* bta_gattc_find_alloc_clcb(tGATT_IF client_if,
- const RawAddress& remote_bda,
- tBT_TRANSPORT transport) {
- tBTA_GATTC_CLCB* p_clcb;
-
- p_clcb = bta_gattc_find_clcb_by_cif(client_if, remote_bda, transport);
- if (p_clcb == NULL) {
- p_clcb = bta_gattc_clcb_alloc(client_if, remote_bda, transport);
- }
- return p_clcb;
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_clcb_dealloc
- *
- * Description Deallocte a clcb
- *
- * Returns pointer to the clcb
- *
- ******************************************************************************/
-void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB* p_clcb) {
- if (!p_clcb) {
- LOG(ERROR) << __func__ << " p_clcb=NULL";
- return;
- }
-
- tBTA_GATTC_SERV* p_srcb = p_clcb->p_srcb;
- if (p_srcb->num_clcb) p_srcb->num_clcb--;
-
- if (p_clcb->p_rcb->num_clcb) p_clcb->p_rcb->num_clcb--;
-
- /* if the srcb is no longer needed, reset the state */
- if (p_srcb->num_clcb == 0) {
- p_srcb->connected = false;
- p_srcb->state = BTA_GATTC_SERV_IDLE;
- p_srcb->mtu = 0;
-
- // clear reallocating
- p_srcb->gatt_database.Clear();
- }
-
- osi_free_and_reset((void**)&p_clcb->p_q_cmd);
- memset(p_clcb, 0, sizeof(tBTA_GATTC_CLCB));
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_find_srcb
- *
- * Description find server cache by remote bd address currently in use
- *
- * Returns pointer to the server cache.
- *
- ******************************************************************************/
-tBTA_GATTC_SERV* bta_gattc_find_srcb(const RawAddress& bda) {
- tBTA_GATTC_SERV* p_srcb = &bta_gattc_cb.known_server[0];
- uint8_t i;
-
- for (i = 0; i < ble_acceptlist_size(); i++, p_srcb++) {
- if (p_srcb->in_use && p_srcb->server_bda == bda) return p_srcb;
- }
- return NULL;
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_find_srvr_cache
- *
- * Description find server cache by remote bd address
- *
- * Returns pointer to the server cache.
- *
- ******************************************************************************/
-tBTA_GATTC_SERV* bta_gattc_find_srvr_cache(const RawAddress& bda) {
- tBTA_GATTC_SERV* p_srcb = &bta_gattc_cb.known_server[0];
- uint8_t i;
-
- for (i = 0; i < ble_acceptlist_size(); i++, p_srcb++) {
- if (p_srcb->server_bda == bda) return p_srcb;
- }
- return NULL;
-}
-/*******************************************************************************
- *
- * Function bta_gattc_find_scb_by_cid
- *
- * Description find server control block by connection ID
- *
- * Returns pointer to the server cache.
- *
- ******************************************************************************/
-tBTA_GATTC_SERV* bta_gattc_find_scb_by_cid(uint16_t conn_id) {
- tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
-
- if (p_clcb)
- return p_clcb->p_srcb;
- else
- return NULL;
-}
-/*******************************************************************************
- *
- * Function bta_gattc_srcb_alloc
- *
- * Description allocate server cache control block
- *
- * Returns pointer to the server cache.
- *
- ******************************************************************************/
-tBTA_GATTC_SERV* bta_gattc_srcb_alloc(const RawAddress& bda) {
- tBTA_GATTC_SERV *p_tcb = &bta_gattc_cb.known_server[0], *p_recycle = NULL;
- bool found = false;
- uint8_t i;
-
- for (i = 0; i < ble_acceptlist_size(); i++, p_tcb++) {
- if (!p_tcb->in_use) {
- found = true;
- break;
- } else if (!p_tcb->connected) {
- p_recycle = p_tcb;
- }
- }
-
- /* if not found, try to recycle one known device */
- if (!found && !p_recycle)
- p_tcb = NULL;
- else if (!found && p_recycle)
- p_tcb = p_recycle;
-
- if (p_tcb != NULL) {
- // clear reallocating
- p_tcb->gatt_database.Clear();
- p_tcb->pending_discovery.Clear();
- *p_tcb = tBTA_GATTC_SERV();
-
- p_tcb->in_use = true;
- p_tcb->server_bda = bda;
- }
- return p_tcb;
-}
-/*******************************************************************************
- *
- * Function bta_gattc_enqueue
- *
- * Description enqueue a client request in clcb.
- *
- * Returns success or failure.
- *
- ******************************************************************************/
-bool bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
- if (p_clcb->p_q_cmd == NULL) {
- p_clcb->p_q_cmd = p_data;
- return true;
- }
-
- LOG(ERROR) << __func__ << ": already has a pending command";
- /* skip the callback now. ----- need to send callback ? */
- return false;
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_check_notif_registry
- *
- * Description check if the service notificaition has been registered.
- *
- * Returns
- *
- ******************************************************************************/
-bool bta_gattc_check_notif_registry(tBTA_GATTC_RCB* p_clreg,
- tBTA_GATTC_SERV* p_srcb,
- tBTA_GATTC_NOTIFY* p_notify) {
- uint8_t i;
-
- for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
- if (p_clreg->notif_reg[i].in_use &&
- p_clreg->notif_reg[i].remote_bda == p_srcb->server_bda &&
- p_clreg->notif_reg[i].handle == p_notify->handle) {
- VLOG(1) << "Notification registered!";
- return true;
- }
- }
- return false;
-}
-/*******************************************************************************
- *
- * Function bta_gattc_clear_notif_registration
- *
- * Description Clear up the notification registration information by
- * RawAddress.
- * Where handle is between start_handle and end_handle, and
- * start_handle and end_handle are boundaries of service
- * containing characteristic.
- *
- * Returns None.
- *
- ******************************************************************************/
-void bta_gattc_clear_notif_registration(tBTA_GATTC_SERV* p_srcb,
- uint16_t conn_id, uint16_t start_handle,
- uint16_t end_handle) {
- RawAddress remote_bda;
- tGATT_IF gatt_if;
- tBTA_GATTC_RCB* p_clrcb;
- uint8_t i;
- tBT_TRANSPORT transport;
- uint16_t handle;
-
- if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
- p_clrcb = bta_gattc_cl_get_regcb(gatt_if);
- if (p_clrcb != NULL) {
- for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
- if (p_clrcb->notif_reg[i].in_use &&
- p_clrcb->notif_reg[i].remote_bda == remote_bda) {
- /* It's enough to get service or characteristic handle, as
- * clear boundaries are always around service.
- */
- handle = p_clrcb->notif_reg[i].handle;
- if (handle >= start_handle && handle <= end_handle)
- memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
- }
- }
- }
- } else {
- LOG(ERROR) << "can not clear indication/notif registration for unknown app";
- }
- return;
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_mark_bg_conn
- *
- * Description mark background connection status when a bg connection is
- * initiated or terminated.
- *
- * Returns true if success; false otherwise.
- *
- ******************************************************************************/
-bool bta_gattc_mark_bg_conn(tGATT_IF client_if,
- const RawAddress& remote_bda_ptr, bool add) {
- tBTA_GATTC_BG_TCK* p_bg_tck = &bta_gattc_cb.bg_track[0];
- uint8_t i = 0;
- tBTA_GATTC_CIF_MASK* p_cif_mask;
-
- for (i = 0; i < ble_acceptlist_size(); i++, p_bg_tck++) {
- if (p_bg_tck->in_use && ((p_bg_tck->remote_bda == remote_bda_ptr) ||
- (p_bg_tck->remote_bda.IsEmpty()))) {
- p_cif_mask = &p_bg_tck->cif_mask;
-
- if (add) /* mask on the cif bit */
- *p_cif_mask |= (1 << (client_if - 1));
- else {
- if (client_if != 0)
- *p_cif_mask &= (~(1 << (client_if - 1)));
- else
- *p_cif_mask = 0;
- }
- /* no BG connection for this device, make it available */
- if (p_bg_tck->cif_mask == 0) {
- memset(p_bg_tck, 0, sizeof(tBTA_GATTC_BG_TCK));
- }
- return true;
- }
- }
- if (!add) {
- LOG(ERROR) << __func__
- << " unable to find the bg connection mask for bd_addr="
- << remote_bda_ptr;
- return false;
- } else /* adding a new device mask */
- {
- for (i = 0, p_bg_tck = &bta_gattc_cb.bg_track[0]; i < ble_acceptlist_size();
- i++, p_bg_tck++) {
- if (!p_bg_tck->in_use) {
- p_bg_tck->in_use = true;
- p_bg_tck->remote_bda = remote_bda_ptr;
-
- p_cif_mask = &p_bg_tck->cif_mask;
-
- *p_cif_mask = (1 << (client_if - 1));
- return true;
- }
- }
- LOG(ERROR) << "no available space to mark the bg connection status";
- return false;
- }
-}
-/*******************************************************************************
- *
- * Function bta_gattc_check_bg_conn
- *
- * Description check if this is a background connection background
- * connection.
- *
- * Returns true if success; false otherwise.
- *
- ******************************************************************************/
-bool bta_gattc_check_bg_conn(tGATT_IF client_if, const RawAddress& remote_bda,
- uint8_t role) {
- tBTA_GATTC_BG_TCK* p_bg_tck = &bta_gattc_cb.bg_track[0];
- uint8_t i = 0;
- bool is_bg_conn = false;
-
- for (i = 0; i < ble_acceptlist_size() && !is_bg_conn; i++, p_bg_tck++) {
- if (p_bg_tck->in_use && (p_bg_tck->remote_bda == remote_bda ||
- p_bg_tck->remote_bda.IsEmpty())) {
- if (((p_bg_tck->cif_mask & (1 << (client_if - 1))) != 0) &&
- role == HCI_ROLE_CENTRAL)
- is_bg_conn = true;
- }
- }
- return is_bg_conn;
-}
-/*******************************************************************************
- *
- * Function bta_gattc_send_open_cback
- *
- * Description send open callback
- *
- * Returns
- *
- ******************************************************************************/
-void bta_gattc_send_open_cback(tBTA_GATTC_RCB* p_clreg, tGATT_STATUS status,
- const RawAddress& remote_bda, uint16_t conn_id,
- tBT_TRANSPORT transport, uint16_t mtu) {
- tBTA_GATTC cb_data;
-
- if (p_clreg->p_cback) {
- memset(&cb_data, 0, sizeof(tBTA_GATTC));
-
- cb_data.open.status = status;
- cb_data.open.client_if = p_clreg->client_if;
- cb_data.open.conn_id = conn_id;
- cb_data.open.mtu = mtu;
- cb_data.open.transport = transport;
- cb_data.open.remote_bda = remote_bda;
-
- (*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data);
- }
-}
-/*******************************************************************************
- *
- * Function bta_gattc_conn_alloc
- *
- * Description allocate connection tracking spot
- *
- * Returns pointer to the clcb
- *
- ******************************************************************************/
-tBTA_GATTC_CONN* bta_gattc_conn_alloc(const RawAddress& remote_bda) {
- uint8_t i_conn = 0;
- tBTA_GATTC_CONN* p_conn = &bta_gattc_cb.conn_track[0];
-
- for (i_conn = 0; i_conn < GATT_MAX_PHY_CHANNEL; i_conn++, p_conn++) {
- if (!p_conn->in_use) {
-#if (BTA_GATT_DEBUG == TRUE)
- VLOG(1) << __func__ << ": found conn_track:" << +i_conn << " available";
-#endif
- p_conn->in_use = true;
- p_conn->remote_bda = remote_bda;
- return p_conn;
- }
- }
- return NULL;
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_conn_find
- *
- * Description allocate connection tracking spot
- *
- * Returns pointer to the clcb
- *
- ******************************************************************************/
-tBTA_GATTC_CONN* bta_gattc_conn_find(const RawAddress& remote_bda) {
- uint8_t i_conn = 0;
- tBTA_GATTC_CONN* p_conn = &bta_gattc_cb.conn_track[0];
-
- for (i_conn = 0; i_conn < GATT_MAX_PHY_CHANNEL; i_conn++, p_conn++) {
- if (p_conn->in_use && remote_bda == p_conn->remote_bda) {
-#if (BTA_GATT_DEBUG == TRUE)
- VLOG(1) << __func__ << ": found conn_track:" << +i_conn << " matched";
-#endif
- return p_conn;
- }
- }
- return NULL;
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_conn_find_alloc
- *
- * Description find or allocate connection tracking spot
- *
- * Returns pointer to the clcb
- *
- ******************************************************************************/
-tBTA_GATTC_CONN* bta_gattc_conn_find_alloc(const RawAddress& remote_bda) {
- tBTA_GATTC_CONN* p_conn = bta_gattc_conn_find(remote_bda);
-
- if (p_conn == NULL) {
- p_conn = bta_gattc_conn_alloc(remote_bda);
- }
- return p_conn;
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_conn_dealloc
- *
- * Description de-allocate connection tracking spot
- *
- * Returns pointer to the clcb
- *
- ******************************************************************************/
-bool bta_gattc_conn_dealloc(const RawAddress& remote_bda) {
- tBTA_GATTC_CONN* p_conn = bta_gattc_conn_find(remote_bda);
-
- if (p_conn != NULL) {
- p_conn->in_use = false;
- p_conn->remote_bda = RawAddress::kEmpty;
- return true;
- }
- return false;
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_find_int_conn_clcb
- *
- * Description try to locate a clcb when an internal connecion event
- * arrives.
- *
- * Returns pointer to the clcb
- *
- ******************************************************************************/
-tBTA_GATTC_CLCB* bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA* p_msg) {
- tBTA_GATTC_CLCB* p_clcb = NULL;
-
- if (p_msg->int_conn.role == HCI_ROLE_PERIPHERAL)
- bta_gattc_conn_find_alloc(p_msg->int_conn.remote_bda);
-
- /* try to locate a logic channel */
- p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
- p_msg->int_conn.remote_bda,
- p_msg->int_conn.transport);
- if (p_clcb == NULL) {
- /* for a background connection or listening connection */
- if (/*p_msg->int_conn.role == HCI_ROLE_PERIPHERAL || */
- bta_gattc_check_bg_conn(p_msg->int_conn.client_if,
- p_msg->int_conn.remote_bda,
- p_msg->int_conn.role)) {
- /* allocate a new channel */
- p_clcb = bta_gattc_clcb_alloc(p_msg->int_conn.client_if,
- p_msg->int_conn.remote_bda,
- p_msg->int_conn.transport);
- }
- }
- return p_clcb;
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_find_int_disconn_clcb
- *
- * Description try to locate a clcb when an internal disconnect callback
- * arrives.
- *
- * Returns pointer to the clcb
- *
- ******************************************************************************/
-tBTA_GATTC_CLCB* bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA* p_msg) {
- tBTA_GATTC_CLCB* p_clcb = NULL;
-
- bta_gattc_conn_dealloc(p_msg->int_conn.remote_bda);
- p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific);
- if (p_clcb == NULL) {
- /* connection attempt failed, send connection callback event */
- p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
- p_msg->int_conn.remote_bda,
- p_msg->int_conn.transport);
- }
- if (p_clcb == NULL) {
- VLOG(1) << " disconnection ID:" << +p_msg->int_conn.hdr.layer_specific
- << " not used by BTA";
- }
- return p_clcb;
-}
-
-/*******************************************************************************
- *
- * Function bta_gattc_is_robust_caching_enabled
- *
- * Description check if robust caching is enabled
- *
- * Returns true if enabled; otherwise false
- *
- ******************************************************************************/
-bool bta_gattc_is_robust_caching_enabled() {
- return bluetooth::common::init_flags::gatt_robust_caching_is_enabled();
-}
diff --git a/bta/gatt/bta_gatts_act.cc b/bta/gatt/bta_gatts_act.cc
deleted file mode 100644
index 3cd7b34..0000000
--- a/bta/gatt/bta_gatts_act.cc
+++ /dev/null
@@ -1,670 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains the GATT Server action functions for the state
- * machine.
- *
- ******************************************************************************/
-
-#include <cstdint>
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bta/gatt/bta_gatts_int.h"
-#include "bta/include/bta_api.h"
-#include "btif/include/btif_debug_conn.h"
-#include "osi/include/allocator.h"
-#include "osi/include/osi.h"
-#include "stack/include/gatt_api.h"
-#include "types/raw_address.h"
-
-#include <base/logging.h>
-
-static void bta_gatts_nv_save_cback(bool is_saved,
- tGATTS_HNDL_RANGE* p_hndl_range);
-static bool bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd,
- tGATTS_SRV_CHG_REQ* p_req,
- tGATTS_SRV_CHG_RSP* p_rsp);
-
-static void bta_gatts_conn_cback(tGATT_IF gatt_if, const RawAddress& bda,
- uint16_t conn_id, bool connected,
- tGATT_DISCONN_REASON reason,
- tBT_TRANSPORT transport);
-static void bta_gatts_send_request_cback(uint16_t conn_id, uint32_t trans_id,
- tGATTS_REQ_TYPE req_type,
- tGATTS_DATA* p_data);
-static void bta_gatts_cong_cback(uint16_t conn_id, bool congested);
-static void bta_gatts_phy_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
- uint8_t tx_phy, uint8_t rx_phy,
- tGATT_STATUS status);
-static void bta_gatts_conn_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
- uint16_t interval, uint16_t latency,
- uint16_t timeout, tGATT_STATUS status);
-
-static tGATT_CBACK bta_gatts_cback = {
- .p_conn_cb = bta_gatts_conn_cback,
- .p_cmpl_cb = nullptr,
- .p_disc_res_cb = nullptr,
- .p_disc_cmpl_cb = nullptr,
- .p_req_cb = bta_gatts_send_request_cback,
- .p_enc_cmpl_cb = nullptr,
- .p_congestion_cb = bta_gatts_cong_cback,
- .p_phy_update_cb = bta_gatts_phy_update_cback,
- .p_conn_update_cb = bta_gatts_conn_update_cback,
-};
-
-tGATT_APPL_INFO bta_gatts_nv_cback = {bta_gatts_nv_save_cback,
- bta_gatts_nv_srv_chg_cback};
-
-/*******************************************************************************
- *
- * Function bta_gatts_nv_save_cback
- *
- * Description NV save callback function.
- *
- * Parameter is_add: true is to add a handle range; otherwise is to
- * delete.
- * Returns none.
- *
- ******************************************************************************/
-static void bta_gatts_nv_save_cback(bool is_add,
- tGATTS_HNDL_RANGE* p_hndl_range) {}
-
-/*******************************************************************************
- *
- * Function bta_gatts_nv_srv_chg_cback
- *
- * Description NV save callback function.
- *
- * Parameter is_add: true is to add a handle range; otherwise is to
- * delete.
- * Returns none.
- *
- ******************************************************************************/
-static bool bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd,
- tGATTS_SRV_CHG_REQ* p_req,
- tGATTS_SRV_CHG_RSP* p_rsp) {
- return false;
-}
-
-/*******************************************************************************
- *
- * Function bta_gatts_enable
- *
- * Description enable BTA GATTS module.
- *
- * Returns none.
- *
- ******************************************************************************/
-void bta_gatts_enable(tBTA_GATTS_CB* p_cb) {
- if (p_cb->enabled) {
- VLOG(1) << "GATTS already enabled.";
- } else {
- memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
-
- p_cb->enabled = true;
-
- if (!GATTS_NVRegister(&bta_gatts_nv_cback)) {
- LOG(ERROR) << "BTA GATTS NV register failed.";
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_gatts_api_disable
- *
- * Description disable BTA GATTS module.
- *
- * Returns none.
- *
- ******************************************************************************/
-void bta_gatts_api_disable(tBTA_GATTS_CB* p_cb) {
- uint8_t i;
-
- if (p_cb->enabled) {
- for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i++) {
- if (p_cb->rcb[i].in_use) {
- GATT_Deregister(p_cb->rcb[i].gatt_if);
- }
- }
- memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
- } else {
- LOG(ERROR) << "GATTS not enabled";
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_gatts_register
- *
- * Description register an application.
- *
- * Returns none.
- *
- ******************************************************************************/
-void bta_gatts_register(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) {
- tBTA_GATTS cb_data;
- tGATT_STATUS status = GATT_SUCCESS;
- uint8_t i, first_unuse = 0xff;
-
- if (!p_cb->enabled) {
- bta_gatts_enable(p_cb);
- }
-
- for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i++) {
- if (p_cb->rcb[i].in_use) {
- if (p_cb->rcb[i].app_uuid == p_msg->api_reg.app_uuid) {
- LOG(ERROR) << "application already registered.";
- status = GATT_DUP_REG;
- break;
- }
- }
- }
-
- if (status == GATT_SUCCESS) {
- for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i++) {
- if (first_unuse == 0xff && !p_cb->rcb[i].in_use) {
- first_unuse = i;
- break;
- }
- }
-
- cb_data.reg_oper.server_if = BTA_GATTS_INVALID_IF;
- cb_data.reg_oper.uuid = p_msg->api_reg.app_uuid;
- if (first_unuse != 0xff) {
- LOG(INFO) << "register application first_unuse rcb_idx=" << +first_unuse;
-
- p_cb->rcb[first_unuse].in_use = true;
- p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback;
- p_cb->rcb[first_unuse].app_uuid = p_msg->api_reg.app_uuid;
- cb_data.reg_oper.server_if = p_cb->rcb[first_unuse].gatt_if =
- GATT_Register(p_msg->api_reg.app_uuid, "GattServer", &bta_gatts_cback,
- p_msg->api_reg.eatt_support);
- if (!p_cb->rcb[first_unuse].gatt_if) {
- status = GATT_NO_RESOURCES;
- } else {
- tBTA_GATTS_INT_START_IF* p_buf = (tBTA_GATTS_INT_START_IF*)osi_malloc(
- sizeof(tBTA_GATTS_INT_START_IF));
- p_buf->hdr.event = BTA_GATTS_INT_START_IF_EVT;
- p_buf->server_if = p_cb->rcb[first_unuse].gatt_if;
-
- bta_sys_sendmsg(p_buf);
- }
- } else {
- status = GATT_NO_RESOURCES;
- }
- }
- cb_data.reg_oper.status = status;
- if (p_msg->api_reg.p_cback)
- (*p_msg->api_reg.p_cback)(BTA_GATTS_REG_EVT, &cb_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_gatts_start_if
- *
- * Description start an application interface.
- *
- * Returns none.
- *
- ******************************************************************************/
-void bta_gatts_start_if(UNUSED_ATTR tBTA_GATTS_CB* p_cb,
- tBTA_GATTS_DATA* p_msg) {
- if (bta_gatts_find_app_rcb_by_app_if(p_msg->int_start_if.server_if)) {
- GATT_StartIf(p_msg->int_start_if.server_if);
- } else {
- LOG(ERROR) << "Unable to start app.: Unknown interface="
- << +p_msg->int_start_if.server_if;
- }
-}
-/*******************************************************************************
- *
- * Function bta_gatts_deregister
- *
- * Description deregister an application.
- *
- * Returns none.
- *
- ******************************************************************************/
-void bta_gatts_deregister(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) {
- tGATT_STATUS status = GATT_ERROR;
- tBTA_GATTS_CBACK* p_cback = NULL;
- uint8_t i;
- tBTA_GATTS cb_data;
-
- cb_data.reg_oper.server_if = p_msg->api_dereg.server_if;
- cb_data.reg_oper.status = status;
-
- for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i++) {
- if (p_cb->rcb[i].in_use &&
- p_cb->rcb[i].gatt_if == p_msg->api_dereg.server_if) {
- p_cback = p_cb->rcb[i].p_cback;
- status = GATT_SUCCESS;
-
- /* deregister the app */
- GATT_Deregister(p_cb->rcb[i].gatt_if);
-
- /* reset cb */
- memset(&p_cb->rcb[i], 0, sizeof(tBTA_GATTS_RCB));
- cb_data.reg_oper.status = status;
- break;
- }
- }
-
- if (p_cback) {
- (*p_cback)(BTA_GATTS_DEREG_EVT, &cb_data);
- } else {
- LOG(ERROR) << "application not registered.";
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_gatts_delete_service
- *
- * Description action function to delete a service.
- *
- * Returns none.
- *
- ******************************************************************************/
-void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB* p_srvc_cb,
- tBTA_GATTS_DATA* p_msg) {
- tBTA_GATTS_RCB* p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
- tBTA_GATTS cb_data;
-
- cb_data.srvc_oper.server_if = p_rcb->gatt_if;
- cb_data.srvc_oper.service_id = p_srvc_cb->service_id;
-
- if (GATTS_DeleteService(p_rcb->gatt_if, &p_srvc_cb->service_uuid,
- p_srvc_cb->service_id)) {
- cb_data.srvc_oper.status = GATT_SUCCESS;
- memset(p_srvc_cb, 0, sizeof(tBTA_GATTS_SRVC_CB));
- } else {
- cb_data.srvc_oper.status = GATT_ERROR;
- }
-
- if (p_rcb->p_cback) (*p_rcb->p_cback)(BTA_GATTS_DELELTE_EVT, &cb_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_gatts_stop_service
- *
- * Description action function to stop a service.
- *
- * Returns none.
- *
- ******************************************************************************/
-void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB* p_srvc_cb,
- UNUSED_ATTR tBTA_GATTS_DATA* p_msg) {
- tBTA_GATTS_RCB* p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
- tBTA_GATTS cb_data;
-
- GATTS_StopService(p_srvc_cb->service_id);
- cb_data.srvc_oper.server_if = p_rcb->gatt_if;
- cb_data.srvc_oper.service_id = p_srvc_cb->service_id;
- cb_data.srvc_oper.status = GATT_SUCCESS;
- LOG(ERROR) << __func__ << " service_id=" << +p_srvc_cb->service_id;
-
- if (p_rcb->p_cback) (*p_rcb->p_cback)(BTA_GATTS_STOP_EVT, &cb_data);
-}
-/*******************************************************************************
- *
- * Function bta_gatts_send_rsp
- *
- * Description GATTS send response.
- *
- * Returns none.
- *
- ******************************************************************************/
-void bta_gatts_send_rsp(UNUSED_ATTR tBTA_GATTS_CB* p_cb,
- tBTA_GATTS_DATA* p_msg) {
- if (GATTS_SendRsp(p_msg->api_rsp.hdr.layer_specific, p_msg->api_rsp.trans_id,
- p_msg->api_rsp.status,
- (tGATTS_RSP*)p_msg->api_rsp.p_rsp) != GATT_SUCCESS) {
- LOG(ERROR) << "Sending response failed";
- }
-}
-/*******************************************************************************
- *
- * Function bta_gatts_indicate_handle
- *
- * Description GATTS send handle value indication or notification.
- *
- * Returns none.
- *
- ******************************************************************************/
-void bta_gatts_indicate_handle(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) {
- tBTA_GATTS_SRVC_CB* p_srvc_cb;
- tBTA_GATTS_RCB* p_rcb = NULL;
- tGATT_STATUS status = GATT_ILLEGAL_PARAMETER;
- tGATT_IF gatt_if;
- RawAddress remote_bda;
- tBT_TRANSPORT transport;
- tBTA_GATTS cb_data;
-
- p_srvc_cb =
- bta_gatts_find_srvc_cb_by_attr_id(p_cb, p_msg->api_indicate.attr_id);
-
- if (p_srvc_cb) {
- if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific,
- &gatt_if, remote_bda, &transport)) {
- p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
-
- if (p_msg->api_indicate.need_confirm)
-
- status = GATTS_HandleValueIndication(
- p_msg->api_indicate.hdr.layer_specific, p_msg->api_indicate.attr_id,
- p_msg->api_indicate.len, p_msg->api_indicate.value);
- else
- status = GATTS_HandleValueNotification(
- p_msg->api_indicate.hdr.layer_specific, p_msg->api_indicate.attr_id,
- p_msg->api_indicate.len, p_msg->api_indicate.value);
-
- /* if over BR_EDR, inform PM for mode change */
- if (transport == BT_TRANSPORT_BR_EDR) {
- bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
- bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
- }
- } else {
- LOG(ERROR) << "Unknown connection_id="
- << loghex(p_msg->api_indicate.hdr.layer_specific)
- << " fail sending notification";
- }
-
- if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) &&
- p_rcb && p_cb->rcb[p_srvc_cb->rcb_idx].p_cback) {
- cb_data.req_data.status = status;
- cb_data.req_data.conn_id = p_msg->api_indicate.hdr.layer_specific;
-
- (*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data);
- }
- } else {
- LOG(ERROR) << "Not an registered servce attribute ID: "
- << loghex(p_msg->api_indicate.attr_id);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_gatts_open
- *
- * Description
- *
- * Returns none.
- *
- ******************************************************************************/
-void bta_gatts_open(UNUSED_ATTR tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) {
- tBTA_GATTS_RCB* p_rcb = NULL;
- tGATT_STATUS status = GATT_ERROR;
- uint16_t conn_id;
-
- p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if);
- if (p_rcb != NULL) {
- /* should always get the connection ID */
- if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda,
- p_msg->api_open.is_direct, p_msg->api_open.transport,
- false)) {
- status = GATT_SUCCESS;
-
- if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda,
- &conn_id, p_msg->api_open.transport)) {
- status = GATT_ALREADY_OPEN;
- }
- }
- } else {
- LOG(ERROR) << "Inavlid server_if=" << p_msg->api_open.server_if;
- }
-
- if (p_rcb && p_rcb->p_cback) {
- tBTA_GATTS bta_gatts;
- bta_gatts.status = status;
- (*p_rcb->p_cback)(BTA_GATTS_OPEN_EVT, &bta_gatts);
- }
-}
-/*******************************************************************************
- *
- * Function bta_gatts_cancel_open
- *
- * Description
- *
- * Returns none.
- *
- ******************************************************************************/
-void bta_gatts_cancel_open(UNUSED_ATTR tBTA_GATTS_CB* p_cb,
- tBTA_GATTS_DATA* p_msg) {
- tBTA_GATTS_RCB* p_rcb;
- tGATT_STATUS status = GATT_ERROR;
-
- p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if);
- if (p_rcb != NULL) {
- if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda,
- p_msg->api_cancel_open.is_direct)) {
- LOG(ERROR) << __func__ << ": failed for open request";
- } else {
- status = GATT_SUCCESS;
- }
- } else {
- LOG(ERROR) << "Inavlid server_if=" << +p_msg->api_cancel_open.server_if;
- }
-
- if (p_rcb && p_rcb->p_cback) {
- tBTA_GATTS bta_gatts;
- bta_gatts.status = status;
- (*p_rcb->p_cback)(BTA_GATTS_CANCEL_OPEN_EVT, &bta_gatts);
- }
-}
-/*******************************************************************************
- *
- * Function bta_gatts_close
- *
- * Description
- *
- * Returns none.
- *
- ******************************************************************************/
-void bta_gatts_close(UNUSED_ATTR tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) {
- tBTA_GATTS_RCB* p_rcb;
- tGATT_STATUS status = GATT_ERROR;
- tGATT_IF gatt_if;
- RawAddress remote_bda;
- tBT_TRANSPORT transport;
-
- if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda,
- &transport)) {
- if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS) {
- LOG(ERROR) << __func__
- << ": fail conn_id=" << loghex(p_msg->hdr.layer_specific);
- } else {
- status = GATT_SUCCESS;
- }
-
- p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
-
- if (p_rcb && p_rcb->p_cback) {
- if (transport == BT_TRANSPORT_BR_EDR)
- bta_sys_conn_close(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
-
- tBTA_GATTS bta_gatts;
- bta_gatts.status = status;
- (*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT, &bta_gatts);
- }
- } else {
- LOG(ERROR) << "Unknown connection_id=" << loghex(p_msg->hdr.layer_specific);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_gatts_request_cback
- *
- * Description GATTS attribute request callback.
- *
- * Returns none.
- *
- ******************************************************************************/
-static void bta_gatts_send_request_cback(uint16_t conn_id, uint32_t trans_id,
- tGATTS_REQ_TYPE req_type,
- tGATTS_DATA* p_data) {
- tBTA_GATTS cb_data;
- tBTA_GATTS_RCB* p_rcb;
- tGATT_IF gatt_if;
- tBT_TRANSPORT transport;
-
- memset(&cb_data, 0, sizeof(tBTA_GATTS));
-
- if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda,
- &transport)) {
- p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
-
- VLOG(1) << __func__ << ": conn_id=" << loghex(conn_id)
- << ", trans_id=" << +trans_id << ", req_type=" << +req_type;
-
- if (p_rcb && p_rcb->p_cback) {
- /* if over BR_EDR, inform PM for mode change */
- if (transport == BT_TRANSPORT_BR_EDR) {
- bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
- bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
- }
-
- cb_data.req_data.conn_id = conn_id;
- cb_data.req_data.trans_id = trans_id;
- cb_data.req_data.p_data = (tGATTS_DATA*)p_data;
-
- (*p_rcb->p_cback)(req_type, &cb_data);
- } else {
- LOG(ERROR) << "connection request on gatt_if=" << +gatt_if
- << " is not interested";
- }
- } else {
- LOG(ERROR) << "request received on unknown conn_id=" << loghex(conn_id);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_gatts_conn_cback
- *
- * Description connection callback.
- *
- * Returns none.
- *
- ******************************************************************************/
-static void bta_gatts_conn_cback(tGATT_IF gatt_if, const RawAddress& bdaddr,
- uint16_t conn_id, bool connected,
- tGATT_DISCONN_REASON,
- tBT_TRANSPORT transport) {
- tBTA_GATTS cb_data;
- uint8_t evt = connected ? BTA_GATTS_CONNECT_EVT : BTA_GATTS_DISCONNECT_EVT;
- tBTA_GATTS_RCB* p_reg;
-
- VLOG(1) << __func__ << " bda=" << bdaddr << " gatt_if= " << gatt_if
- << ", conn_id=" << loghex(conn_id) << " connected=" << connected;
-
- if (connected)
- btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_OK);
- else
- btif_debug_conn_state(bdaddr, BTIF_DEBUG_DISCONNECTED, GATT_CONN_OK);
-
- p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if);
-
- if (p_reg && p_reg->p_cback) {
- /* there is no RM for GATT */
- if (transport == BT_TRANSPORT_BR_EDR) {
- if (connected)
- bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bdaddr);
- else
- bta_sys_conn_close(BTA_ID_GATTS, BTA_ALL_APP_ID, bdaddr);
- }
-
- cb_data.conn.conn_id = conn_id;
- cb_data.conn.server_if = gatt_if;
- cb_data.conn.transport = transport;
- cb_data.conn.remote_bda = bdaddr;
- (*p_reg->p_cback)(evt, &cb_data);
- } else {
- LOG(ERROR) << __func__ << " server_if=" << +gatt_if << " not found";
- }
-}
-
-static void bta_gatts_phy_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
- uint8_t tx_phy, uint8_t rx_phy,
- tGATT_STATUS status) {
- tBTA_GATTS_RCB* p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if);
- if (!p_reg || !p_reg->p_cback) {
- LOG(ERROR) << __func__ << ": server_if=" << +gatt_if << " not found";
- return;
- }
-
- tBTA_GATTS cb_data;
- cb_data.phy_update.conn_id = conn_id;
- cb_data.phy_update.server_if = gatt_if;
- cb_data.phy_update.tx_phy = tx_phy;
- cb_data.phy_update.rx_phy = rx_phy;
- cb_data.phy_update.status = status;
- (*p_reg->p_cback)(BTA_GATTS_PHY_UPDATE_EVT, &cb_data);
-}
-
-static void bta_gatts_conn_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
- uint16_t interval, uint16_t latency,
- uint16_t timeout, tGATT_STATUS status) {
- tBTA_GATTS_RCB* p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if);
- if (!p_reg || !p_reg->p_cback) {
- LOG(ERROR) << __func__ << ": server_if=" << +gatt_if << " not found";
- return;
- }
-
- tBTA_GATTS cb_data;
- cb_data.conn_update.conn_id = conn_id;
- cb_data.conn_update.server_if = gatt_if;
- cb_data.conn_update.interval = interval;
- cb_data.conn_update.latency = latency;
- cb_data.conn_update.timeout = timeout;
- cb_data.conn_update.status = status;
- (*p_reg->p_cback)(BTA_GATTS_CONN_UPDATE_EVT, &cb_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_gatts_cong_cback
- *
- * Description congestion callback.
- *
- * Returns none.
- *
- ******************************************************************************/
-static void bta_gatts_cong_cback(uint16_t conn_id, bool congested) {
- tBTA_GATTS_RCB* p_rcb;
- tGATT_IF gatt_if;
- tBT_TRANSPORT transport;
- tBTA_GATTS cb_data;
-
- if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda,
- &transport)) {
- p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
-
- if (p_rcb && p_rcb->p_cback) {
- cb_data.congest.conn_id = conn_id;
- cb_data.congest.congested = congested;
-
- (*p_rcb->p_cback)(BTA_GATTS_CONGEST_EVT, &cb_data);
- }
- }
-}
diff --git a/bta/gatt/bta_gatts_api.cc b/bta/gatt/bta_gatts_api.cc
deleted file mode 100644
index 74ef835..0000000
--- a/bta/gatt/bta_gatts_api.cc
+++ /dev/null
@@ -1,366 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2010-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the implementation of the API for GATT server of BTA.
- *
- ******************************************************************************/
-
-#include <base/bind.h>
-#include <base/location.h>
-#include <base/logging.h>
-
-#include <cstdint>
-#include <memory>
-#include <vector>
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bta/gatt/bta_gatts_int.h"
-#include "osi/include/allocator.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/btu.h" // do_in_main_thread
-#include "types/bluetooth/uuid.h"
-#include "types/bt_transport.h"
-#include "types/raw_address.h"
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-
-static const tBTA_SYS_REG bta_gatts_reg = {bta_gatts_hdl_event,
- BTA_GATTS_Disable};
-
-/*******************************************************************************
- *
- * Function BTA_GATTS_Disable
- *
- * Description This function is called to disable GATTS module
- *
- * Parameters None.
- *
- * Returns None
- *
- ******************************************************************************/
-void BTA_GATTS_Disable(void) {
- if (!bta_sys_is_register(BTA_ID_GATTS)) {
- LOG(WARNING) << "GATTS Module not enabled/already disabled";
- return;
- }
-
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
- p_buf->event = BTA_GATTS_API_DISABLE_EVT;
- bta_sys_sendmsg(p_buf);
- bta_sys_deregister(BTA_ID_GATTS);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTS_AppRegister
- *
- * Description This function is called to register application callbacks
- * with BTA GATTS module.
- *
- * Parameters p_app_uuid - applicaiton UUID
- * p_cback - pointer to the application callback function.
- *
- * Returns None
- *
- ******************************************************************************/
-void BTA_GATTS_AppRegister(const bluetooth::Uuid& app_uuid,
- tBTA_GATTS_CBACK* p_cback, bool eatt_support) {
- tBTA_GATTS_API_REG* p_buf =
- (tBTA_GATTS_API_REG*)osi_malloc(sizeof(tBTA_GATTS_API_REG));
-
- /* register with BTA system manager */
- if (!bta_sys_is_register(BTA_ID_GATTS))
- bta_sys_register(BTA_ID_GATTS, &bta_gatts_reg);
-
- p_buf->hdr.event = BTA_GATTS_API_REG_EVT;
- p_buf->app_uuid = app_uuid;
- p_buf->p_cback = p_cback;
- p_buf->eatt_support = eatt_support;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTS_AppDeregister
- *
- * Description De-register with GATT Server.
- *
- * Parameters app_id: applicatino ID.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_GATTS_AppDeregister(tGATT_IF server_if) {
- tBTA_GATTS_API_DEREG* p_buf =
- (tBTA_GATTS_API_DEREG*)osi_malloc(sizeof(tBTA_GATTS_API_DEREG));
-
- p_buf->hdr.event = BTA_GATTS_API_DEREG_EVT;
- p_buf->server_if = server_if;
-
- bta_sys_sendmsg(p_buf);
-}
-
-void bta_gatts_add_service_impl(tGATT_IF server_if,
- std::vector<btgatt_db_element_t> service,
- BTA_GATTS_AddServiceCb cb) {
- uint8_t rcb_idx =
- bta_gatts_find_app_rcb_idx_by_app_if(&bta_gatts_cb, server_if);
-
- LOG(INFO) << __func__ << ": rcb_idx=" << +rcb_idx;
-
- if (rcb_idx == BTA_GATTS_INVALID_APP) {
- cb.Run(GATT_ERROR, server_if, std::move(service));
- return;
- }
-
- uint8_t srvc_idx = bta_gatts_alloc_srvc_cb(&bta_gatts_cb, rcb_idx);
- if (srvc_idx == BTA_GATTS_INVALID_APP) {
- cb.Run(GATT_ERROR, server_if, std::move(service));
- return;
- }
-
- tGATT_STATUS status =
- GATTS_AddService(server_if, service.data(), service.size());
- if (status != GATT_SERVICE_STARTED) {
- memset(&bta_gatts_cb.srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB));
- LOG(ERROR) << __func__ << ": service creation failed.";
- cb.Run(GATT_ERROR, server_if, std::move(service));
- return;
- }
-
- bta_gatts_cb.srvc_cb[srvc_idx].service_uuid = service[0].uuid;
-
- // service_id is equal to service start handle
- bta_gatts_cb.srvc_cb[srvc_idx].service_id = service[0].attribute_handle;
- bta_gatts_cb.srvc_cb[srvc_idx].idx = srvc_idx;
-
- cb.Run(GATT_SUCCESS, server_if, std::move(service));
- return;
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTS_AddService
- *
- * Description Add the given |service| and all included elements to the
- * GATT database. a |BTA_GATTS_ADD_SRVC_EVT| is triggered to
- * report the status and attribute handles.
- *
- * Parameters server_if: server interface.
- * service: pointer vector describing service.
- *
- * Returns Returns |GATT_SUCCESS| on success or |GATT_ERROR| if the
- * service cannot be added.
- *
- ******************************************************************************/
-extern void BTA_GATTS_AddService(tGATT_IF server_if,
- std::vector<btgatt_db_element_t> service,
- BTA_GATTS_AddServiceCb cb) {
- do_in_main_thread(FROM_HERE,
- base::Bind(&bta_gatts_add_service_impl, server_if,
- std::move(service), std::move(cb)));
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTS_DeleteService
- *
- * Description This function is called to delete a service. When this is
- * done, a callback event BTA_GATTS_DELETE_EVT is report with
- * the status.
- *
- * Parameters service_id: service_id to be deleted.
- *
- * Returns returns none.
- *
- ******************************************************************************/
-void BTA_GATTS_DeleteService(uint16_t service_id) {
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
-
- p_buf->event = BTA_GATTS_API_DEL_SRVC_EVT;
- p_buf->layer_specific = service_id;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTS_StopService
- *
- * Description This function is called to stop a service.
- *
- * Parameters service_id - service to be topped.
- *
- * Returns None
- *
- ******************************************************************************/
-void BTA_GATTS_StopService(uint16_t service_id) {
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
-
- p_buf->event = BTA_GATTS_API_STOP_SRVC_EVT;
- p_buf->layer_specific = service_id;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTS_HandleValueIndication
- *
- * Description This function is called to read a characteristics
- * descriptor.
- *
- * Parameters bda - remote device bd address to indicate.
- * attr_id - attribute ID to indicate.
- * value - data to indicate.
- * need_confirm - if this indication expects a confirmation or
- * not.
- *
- * Returns None
- *
- ******************************************************************************/
-void BTA_GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_id,
- std::vector<uint8_t> value,
- bool need_confirm) {
- tBTA_GATTS_API_INDICATION* p_buf =
- (tBTA_GATTS_API_INDICATION*)osi_calloc(sizeof(tBTA_GATTS_API_INDICATION));
-
- p_buf->hdr.event = BTA_GATTS_API_INDICATION_EVT;
- p_buf->hdr.layer_specific = conn_id;
- p_buf->attr_id = attr_id;
- p_buf->need_confirm = need_confirm;
- if (value.size() > 0) {
- p_buf->len = value.size();
- memcpy(p_buf->value, value.data(), value.size());
- }
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTS_SendRsp
- *
- * Description This function is called to send a response to a request.
- *
- * Parameters conn_id - connection identifier.
- * trans_id - transaction ID.
- * status - response status
- * p_msg - response data.
- *
- * Returns None
- *
- ******************************************************************************/
-void BTA_GATTS_SendRsp(uint16_t conn_id, uint32_t trans_id, tGATT_STATUS status,
- tGATTS_RSP* p_msg) {
- const size_t len = sizeof(tBTA_GATTS_API_RSP) + sizeof(tGATTS_RSP);
- tBTA_GATTS_API_RSP* p_buf = (tBTA_GATTS_API_RSP*)osi_calloc(len);
-
- p_buf->hdr.event = BTA_GATTS_API_RSP_EVT;
- p_buf->hdr.layer_specific = conn_id;
- p_buf->trans_id = trans_id;
- p_buf->status = status;
- if (p_msg != NULL) {
- p_buf->p_rsp = (tGATTS_RSP*)(p_buf + 1);
- memcpy(p_buf->p_rsp, p_msg, sizeof(tGATTS_RSP));
- }
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTS_Open
- *
- * Description Open a direct open connection or add a background auto
- * connection bd address
- *
- * Parameters server_if: server interface.
- * remote_bda: remote device BD address.
- * is_direct: direct connection or background auto connection
- * transport : Transport on which GATT connection to be opened
- * (BR/EDR or LE)
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_GATTS_Open(tGATT_IF server_if, const RawAddress& remote_bda,
- bool is_direct, tBT_TRANSPORT transport) {
- tBTA_GATTS_API_OPEN* p_buf =
- (tBTA_GATTS_API_OPEN*)osi_malloc(sizeof(tBTA_GATTS_API_OPEN));
-
- p_buf->hdr.event = BTA_GATTS_API_OPEN_EVT;
- p_buf->server_if = server_if;
- p_buf->is_direct = is_direct;
- p_buf->transport = transport;
- p_buf->remote_bda = remote_bda;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTS_CancelOpen
- *
- * Description Cancel a direct open connection or remove a background auto
- * connection bd address
- *
- * Parameters server_if: server interface.
- * remote_bda: remote device BD address.
- * is_direct: direct connection or background auto connection
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_GATTS_CancelOpen(tGATT_IF server_if, const RawAddress& remote_bda,
- bool is_direct) {
- tBTA_GATTS_API_CANCEL_OPEN* p_buf = (tBTA_GATTS_API_CANCEL_OPEN*)osi_malloc(
- sizeof(tBTA_GATTS_API_CANCEL_OPEN));
-
- p_buf->hdr.event = BTA_GATTS_API_CANCEL_OPEN_EVT;
- p_buf->server_if = server_if;
- p_buf->is_direct = is_direct;
- p_buf->remote_bda = remote_bda;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_GATTS_Close
- *
- * Description Close a connection a remote device.
- *
- * Parameters conn_id: connectino ID to be closed.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_GATTS_Close(uint16_t conn_id) {
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
-
- p_buf->event = BTA_GATTS_API_CLOSE_EVT;
- p_buf->layer_specific = conn_id;
-
- bta_sys_sendmsg(p_buf);
-}
diff --git a/bta/gatt/bta_gatts_int.h b/bta/gatt/bta_gatts_int.h
deleted file mode 100644
index 74f5a2d..0000000
--- a/bta/gatt/bta_gatts_int.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the private file for the BTA GATT server.
- *
- ******************************************************************************/
-#ifndef BTA_GATTS_INT_H
-#define BTA_GATTS_INT_H
-
-#include <cstdint>
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bta/include/bta_gatt_api.h"
-#include "bta/sys/bta_sys.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/bt_types.h"
-#include "stack/include/btm_ble_api_types.h"
-#include "stack/include/gatt_api.h"
-#include "types/bluetooth/uuid.h"
-#include "types/raw_address.h"
-
-/*****************************************************************************
- * Constants and data types
- ****************************************************************************/
-enum {
- BTA_GATTS_API_REG_EVT = BTA_SYS_EVT_START(BTA_ID_GATTS),
- BTA_GATTS_INT_START_IF_EVT,
- BTA_GATTS_API_DEREG_EVT,
- BTA_GATTS_API_INDICATION_EVT,
-
- BTA_GATTS_API_DEL_SRVC_EVT,
- BTA_GATTS_API_STOP_SRVC_EVT,
- BTA_GATTS_API_RSP_EVT,
- BTA_GATTS_API_OPEN_EVT,
- BTA_GATTS_API_CANCEL_OPEN_EVT,
- BTA_GATTS_API_CLOSE_EVT,
- BTA_GATTS_API_DISABLE_EVT
-};
-typedef uint16_t tBTA_GATTS_INT_EVT;
-
-/* max number of application allowed on device */
-#define BTA_GATTS_MAX_APP_NUM GATT_MAX_SR_PROFILES
-
-/* max number of services allowed in the device */
-#define BTA_GATTS_MAX_SRVC_NUM GATT_MAX_SR_PROFILES
-
-/* internal strucutre for GATTC register API */
-typedef struct {
- BT_HDR_RIGID hdr;
- bluetooth::Uuid app_uuid;
- tBTA_GATTS_CBACK* p_cback;
- bool eatt_support;
-} tBTA_GATTS_API_REG;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- tGATT_IF server_if;
-} tBTA_GATTS_INT_START_IF;
-
-typedef tBTA_GATTS_INT_START_IF tBTA_GATTS_API_DEREG;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- tGATT_IF server_if;
- btgatt_db_element_t* service;
- uint16_t count;
-} tBTA_GATTS_API_ADD_SERVICE;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- uint16_t attr_id;
- uint16_t len;
- bool need_confirm;
- uint8_t value[GATT_MAX_ATTR_LEN];
-} tBTA_GATTS_API_INDICATION;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- uint32_t trans_id;
- tGATT_STATUS status;
- tGATTS_RSP* p_rsp;
-} tBTA_GATTS_API_RSP;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- tBT_TRANSPORT transport;
-} tBTA_GATTS_API_START;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- RawAddress remote_bda;
- tGATT_IF server_if;
- bool is_direct;
- tBT_TRANSPORT transport;
-
-} tBTA_GATTS_API_OPEN;
-
-typedef tBTA_GATTS_API_OPEN tBTA_GATTS_API_CANCEL_OPEN;
-
-typedef union {
- BT_HDR_RIGID hdr;
- tBTA_GATTS_API_REG api_reg;
- tBTA_GATTS_API_DEREG api_dereg;
- tBTA_GATTS_API_ADD_SERVICE api_add_service;
- tBTA_GATTS_API_INDICATION api_indicate;
- tBTA_GATTS_API_RSP api_rsp;
- tBTA_GATTS_API_OPEN api_open;
- tBTA_GATTS_API_CANCEL_OPEN api_cancel_open;
-
- tBTA_GATTS_INT_START_IF int_start_if;
-} tBTA_GATTS_DATA;
-
-/* application registration control block */
-typedef struct {
- bool in_use;
- bluetooth::Uuid app_uuid;
- tBTA_GATTS_CBACK* p_cback;
- tGATT_IF gatt_if;
-} tBTA_GATTS_RCB;
-
-/* service registration control block */
-typedef struct {
- bluetooth::Uuid service_uuid; /* service UUID */
- uint16_t service_id; /* service start handle */
- uint8_t rcb_idx;
- uint8_t idx; /* self index of serviec CB */
- bool in_use;
-} tBTA_GATTS_SRVC_CB;
-
-/* GATT server control block */
-typedef struct {
- bool enabled;
- tBTA_GATTS_RCB rcb[BTA_GATTS_MAX_APP_NUM];
- tBTA_GATTS_SRVC_CB srvc_cb[BTA_GATTS_MAX_SRVC_NUM];
-} tBTA_GATTS_CB;
-
-/*****************************************************************************
- * Global data
- ****************************************************************************/
-
-/* GATTC control block */
-extern tBTA_GATTS_CB bta_gatts_cb;
-
-/*****************************************************************************
- * Function prototypes
- ****************************************************************************/
-extern bool bta_gatts_hdl_event(BT_HDR_RIGID* p_msg);
-
-extern void bta_gatts_api_disable(tBTA_GATTS_CB* p_cb);
-extern void bta_gatts_api_enable(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_data);
-extern void bta_gatts_register(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg);
-extern void bta_gatts_start_if(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg);
-extern void bta_gatts_deregister(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg);
-extern void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB* p_srvc_cb,
- tBTA_GATTS_DATA* p_msg);
-extern void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB* p_srvc_cb,
- tBTA_GATTS_DATA* p_msg);
-
-extern void bta_gatts_send_rsp(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg);
-extern void bta_gatts_indicate_handle(tBTA_GATTS_CB* p_cb,
- tBTA_GATTS_DATA* p_msg);
-
-extern void bta_gatts_open(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg);
-extern void bta_gatts_cancel_open(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg);
-extern void bta_gatts_close(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg);
-
-extern tBTA_GATTS_RCB* bta_gatts_find_app_rcb_by_app_if(tGATT_IF server_if);
-extern uint8_t bta_gatts_find_app_rcb_idx_by_app_if(tBTA_GATTS_CB* p_cb,
- tGATT_IF server_if);
-extern uint8_t bta_gatts_alloc_srvc_cb(tBTA_GATTS_CB* p_cb, uint8_t rcb_idx);
-extern tBTA_GATTS_SRVC_CB* bta_gatts_find_srvc_cb_by_srvc_id(
- tBTA_GATTS_CB* p_cb, uint16_t service_id);
-extern tBTA_GATTS_SRVC_CB* bta_gatts_find_srvc_cb_by_attr_id(
- tBTA_GATTS_CB* p_cb, uint16_t attr_id);
-
-#endif /* BTA_GATTS_INT_H */
diff --git a/bta/gatt/bta_gatts_main.cc b/bta/gatt/bta_gatts_main.cc
deleted file mode 100644
index 97e9a3d..0000000
--- a/bta/gatt/bta_gatts_main.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains the GATT server main functions and state machine.
- *
- ******************************************************************************/
-
-#include "bt_target.h" // Must be first to define build configuration
-#include "bta/gatt/bta_gatts_int.h"
-#include "stack/include/bt_hdr.h"
-
-#include <base/logging.h>
-
-/* GATTS control block */
-tBTA_GATTS_CB bta_gatts_cb;
-
-/*******************************************************************************
- *
- * Function bta_gatts_hdl_event
- *
- * Description BTA GATT server main event handling function.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-bool bta_gatts_hdl_event(BT_HDR_RIGID* p_msg) {
- tBTA_GATTS_CB* p_cb = &bta_gatts_cb;
-
- switch (p_msg->event) {
- case BTA_GATTS_API_DISABLE_EVT:
- bta_gatts_api_disable(p_cb);
- break;
-
- case BTA_GATTS_API_REG_EVT:
- bta_gatts_register(p_cb, (tBTA_GATTS_DATA*)p_msg);
- break;
-
- case BTA_GATTS_INT_START_IF_EVT:
- bta_gatts_start_if(p_cb, (tBTA_GATTS_DATA*)p_msg);
- break;
-
- case BTA_GATTS_API_DEREG_EVT:
- bta_gatts_deregister(p_cb, (tBTA_GATTS_DATA*)p_msg);
- break;
-
- case BTA_GATTS_API_INDICATION_EVT:
- bta_gatts_indicate_handle(p_cb, (tBTA_GATTS_DATA*)p_msg);
- break;
-
- case BTA_GATTS_API_OPEN_EVT:
- bta_gatts_open(p_cb, (tBTA_GATTS_DATA*)p_msg);
- break;
-
- case BTA_GATTS_API_CANCEL_OPEN_EVT:
- bta_gatts_cancel_open(p_cb, (tBTA_GATTS_DATA*)p_msg);
- break;
-
- case BTA_GATTS_API_CLOSE_EVT:
- bta_gatts_close(p_cb, (tBTA_GATTS_DATA*)p_msg);
- break;
-
- case BTA_GATTS_API_RSP_EVT:
- bta_gatts_send_rsp(p_cb, (tBTA_GATTS_DATA*)p_msg);
- break;
-
- case BTA_GATTS_API_DEL_SRVC_EVT: {
- tBTA_GATTS_SRVC_CB* p_srvc_cb = bta_gatts_find_srvc_cb_by_srvc_id(
- p_cb, ((tBTA_GATTS_DATA*)p_msg)->api_add_service.hdr.layer_specific);
-
- if (p_srvc_cb != NULL)
- bta_gatts_delete_service(p_srvc_cb, (tBTA_GATTS_DATA*)p_msg);
- else
- LOG(ERROR) << __func__ << ": can't delete service - no srvc_cb found";
-
- break;
- }
-
- case BTA_GATTS_API_STOP_SRVC_EVT: {
- tBTA_GATTS_SRVC_CB* p_srvc_cb = bta_gatts_find_srvc_cb_by_srvc_id(
- p_cb, ((tBTA_GATTS_DATA*)p_msg)->api_add_service.hdr.layer_specific);
-
- if (p_srvc_cb != NULL)
- bta_gatts_stop_service(p_srvc_cb, (tBTA_GATTS_DATA*)p_msg);
- else
- LOG(ERROR) << __func__ << ": can't stop service - no srvc_cb found";
-
- break;
- }
-
- default:
- break;
- }
-
- return (true);
-}
diff --git a/bta/gatt/bta_gatts_utils.cc b/bta/gatt/bta_gatts_utils.cc
deleted file mode 100644
index 966dd23..0000000
--- a/bta/gatt/bta_gatts_utils.cc
+++ /dev/null
@@ -1,146 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains the GATT client utility function.
- *
- ******************************************************************************/
-
-#include <cstdint>
-
-#include "bt_target.h" // Must be first to define build configuration
-
-#include "bta/gatt/bta_gatts_int.h"
-
-#include <base/logging.h>
-
-/*******************************************************************************
- *
- * Function bta_gatts_alloc_srvc_cb
- *
- * Description allocate a service control block.
- *
- * Returns pointer to the control block, or otherwise NULL when failed.
- *
- ******************************************************************************/
-uint8_t bta_gatts_alloc_srvc_cb(tBTA_GATTS_CB* p_cb, uint8_t rcb_idx) {
- uint8_t i;
-
- for (i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i++) {
- if (!p_cb->srvc_cb[i].in_use) {
- p_cb->srvc_cb[i].in_use = true;
- p_cb->srvc_cb[i].rcb_idx = rcb_idx;
- return i;
- }
- }
- return BTA_GATTS_INVALID_APP;
-}
-
-/*******************************************************************************
- *
- * Function bta_gatts_find_app_rcb_by_app_if
- *
- * Description find the index of the application control block by app ID.
- *
- * Returns pointer to the control block if success, otherwise NULL
- *
- ******************************************************************************/
-tBTA_GATTS_RCB* bta_gatts_find_app_rcb_by_app_if(tGATT_IF server_if) {
- uint8_t i;
- tBTA_GATTS_RCB* p_reg;
-
- for (i = 0, p_reg = bta_gatts_cb.rcb; i < BTA_GATTS_MAX_APP_NUM;
- i++, p_reg++) {
- if (p_reg->in_use && p_reg->gatt_if == server_if) return p_reg;
- }
- return NULL;
-}
-
-/*******************************************************************************
- *
- * Function bta_gatts_find_app_rcb_idx_by_app_if
- *
- * Description find the index of the application control block by app ID.
- *
- * Returns index of the control block, or BTA_GATTS_INVALID_APP if
- * failed.
- *
- ******************************************************************************/
-
-uint8_t bta_gatts_find_app_rcb_idx_by_app_if(tBTA_GATTS_CB* p_cb,
- tGATT_IF server_if) {
- uint8_t i;
-
- for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i++) {
- if (p_cb->rcb[i].in_use && p_cb->rcb[i].gatt_if == server_if) return i;
- }
- return BTA_GATTS_INVALID_APP;
-}
-/*******************************************************************************
- *
- * Function bta_gatts_find_srvc_cb_by_srvc_id
- *
- * Description find the service control block by service ID.
- *
- * Returns pointer to the rcb.
- *
- ******************************************************************************/
-tBTA_GATTS_SRVC_CB* bta_gatts_find_srvc_cb_by_srvc_id(tBTA_GATTS_CB* p_cb,
- uint16_t service_id) {
- uint8_t i;
- VLOG(1) << __func__ << ": service_id=" << +service_id;
- for (i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i++) {
- if (p_cb->srvc_cb[i].in_use && p_cb->srvc_cb[i].service_id == service_id) {
- VLOG(1) << __func__ << ": found service cb index=" << +i;
- return &p_cb->srvc_cb[i];
- }
- }
- return NULL;
-}
-/*******************************************************************************
- *
- * Function bta_gatts_find_srvc_cb_by_attr_id
- *
- * Description find the service control block by attribute ID.
- *
- * Returns pointer to the rcb.
- *
- ******************************************************************************/
-tBTA_GATTS_SRVC_CB* bta_gatts_find_srvc_cb_by_attr_id(tBTA_GATTS_CB* p_cb,
- uint16_t attr_id) {
- uint8_t i;
-
- for (i = 0; i < (BTA_GATTS_MAX_SRVC_NUM); i++) {
- if (/* middle service */
- (i < (BTA_GATTS_MAX_SRVC_NUM - 1) && p_cb->srvc_cb[i].in_use &&
- p_cb->srvc_cb[i + 1].in_use &&
- attr_id >= p_cb->srvc_cb[i].service_id &&
- attr_id < p_cb->srvc_cb[i + 1].service_id) ||
- /* last active service */
- (i < (BTA_GATTS_MAX_SRVC_NUM - 1) && p_cb->srvc_cb[i].in_use &&
- !p_cb->srvc_cb[i + 1].in_use &&
- attr_id >= p_cb->srvc_cb[i].service_id) ||
- /* last service incb */
- (i == (BTA_GATTS_MAX_SRVC_NUM - 1) &&
- attr_id >= p_cb->srvc_cb[i].service_id)) {
- return &p_cb->srvc_cb[i];
- }
- }
- return NULL;
-}
diff --git a/bta/gatt/database.cc b/bta/gatt/database.cc
deleted file mode 100644
index 433fd55..0000000
--- a/bta/gatt/database.cc
+++ /dev/null
@@ -1,310 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2018 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 "database.h"
-
-#include <base/logging.h>
-
-#include <list>
-#include <memory>
-#include <sstream>
-
-#include "bt_trace.h"
-#include "stack/crypto_toolbox/crypto_toolbox.h"
-#include "stack/include/gattdefs.h"
-#include "types/bluetooth/uuid.h"
-
-using bluetooth::Uuid;
-
-namespace gatt {
-
-namespace {
-const Uuid PRIMARY_SERVICE = Uuid::From16Bit(GATT_UUID_PRI_SERVICE);
-const Uuid SECONDARY_SERVICE = Uuid::From16Bit(GATT_UUID_SEC_SERVICE);
-const Uuid INCLUDE = Uuid::From16Bit(GATT_UUID_INCLUDE_SERVICE);
-const Uuid CHARACTERISTIC = Uuid::From16Bit(GATT_UUID_CHAR_DECLARE);
-const Uuid CHARACTERISTIC_EXTENDED_PROPERTIES =
- Uuid::From16Bit(GATT_UUID_CHAR_EXT_PROP);
-
-bool HandleInRange(const Service& svc, uint16_t handle) {
- return handle >= svc.handle && handle <= svc.end_handle;
-}
-} // namespace
-
-static size_t UuidSize(const Uuid& uuid) {
- size_t len = uuid.GetShortestRepresentationSize();
- return (len == Uuid::kNumBytes32) ? Uuid::kNumBytes128 : len;
-}
-
-Service* FindService(std::list<Service>& services, uint16_t handle) {
- for (Service& service : services) {
- if (handle >= service.handle && handle <= service.end_handle)
- return &service;
- }
-
- return nullptr;
-}
-
-std::string Database::ToString() const {
- std::stringstream tmp;
-
- for (const Service& service : services) {
- tmp << "Service: handle=" << loghex(service.handle)
- << ", end_handle=" << loghex(service.end_handle)
- << ", uuid=" << service.uuid << "\n";
-
- for (const auto& is : service.included_services) {
- tmp << "\t Included service: handle=" << loghex(is.handle)
- << ", start_handle=" << loghex(is.start_handle)
- << ", end_handle=" << loghex(is.end_handle) << ", uuid=" << is.uuid
- << "\n";
- }
-
- for (const Characteristic& c : service.characteristics) {
- tmp << "\t Characteristic: declaration_handle="
- << loghex(c.declaration_handle)
- << ", value_handle=" << loghex(c.value_handle) << ", uuid=" << c.uuid
- << ", prop=" << loghex(c.properties) << "\n";
-
- for (const Descriptor& d : c.descriptors) {
- tmp << "\t\t Descriptor: handle=" << loghex(d.handle)
- << ", uuid=" << d.uuid << "\n";
- }
- }
- }
- return tmp.str();
-}
-
-std::vector<StoredAttribute> Database::Serialize() const {
- std::vector<StoredAttribute> nv_attr;
-
- if (services.empty()) return std::vector<StoredAttribute>();
-
- for (const Service& service : services) {
- // TODO: add constructor to NV_ATTR, use emplace_back
- nv_attr.push_back({service.handle,
- service.is_primary ? PRIMARY_SERVICE : SECONDARY_SERVICE,
- {.service = {.uuid = service.uuid,
- .end_handle = service.end_handle}}});
- }
-
- for (const Service& service : services) {
- for (const IncludedService& p_isvc : service.included_services) {
- nv_attr.push_back({p_isvc.handle,
- INCLUDE,
- {.included_service = {.handle = p_isvc.start_handle,
- .end_handle = p_isvc.end_handle,
- .uuid = p_isvc.uuid}}});
- }
-
- for (const Characteristic& charac : service.characteristics) {
- nv_attr.push_back(
- {charac.declaration_handle,
- CHARACTERISTIC,
- {.characteristic = {.properties = charac.properties,
- .value_handle = charac.value_handle,
- .uuid = charac.uuid}}});
-
- for (const Descriptor& desc : charac.descriptors) {
- if (desc.uuid == CHARACTERISTIC_EXTENDED_PROPERTIES) {
- nv_attr.push_back({desc.handle,
- desc.uuid,
- {.characteristic_extended_properties =
- desc.characteristic_extended_properties}});
- } else {
- nv_attr.push_back({desc.handle, desc.uuid, {}});
- }
- }
- }
- }
-
- return nv_attr;
-}
-
-Database Database::Deserialize(const std::vector<StoredAttribute>& nv_attr,
- bool* success) {
- // clear reallocating
- Database result;
- auto it = nv_attr.cbegin();
-
- for (; it != nv_attr.cend(); ++it) {
- const auto& attr = *it;
- if (attr.type != PRIMARY_SERVICE && attr.type != SECONDARY_SERVICE) break;
- result.services.emplace_back(Service{
- .handle = attr.handle,
- .uuid = attr.value.service.uuid,
- .is_primary = (attr.type == PRIMARY_SERVICE),
- .end_handle = attr.value.service.end_handle,
- });
- }
-
- auto current_service_it = result.services.begin();
- for (; it != nv_attr.cend(); it++) {
- const auto& attr = *it;
-
- // go to the service this attribute belongs to; attributes are stored in
- // order, so iterating just forward is enough
- while (current_service_it != result.services.end() &&
- current_service_it->end_handle < attr.handle) {
- current_service_it++;
- }
-
- if (current_service_it == result.services.end() ||
- !HandleInRange(*current_service_it, attr.handle)) {
- LOG(ERROR) << "Can't find service for attribute with handle: "
- << loghex(attr.handle);
- *success = false;
- return result;
- }
-
- if (attr.type == INCLUDE) {
- Service* included_service =
- FindService(result.services, attr.value.included_service.handle);
- if (!included_service) {
- LOG(ERROR) << __func__ << ": Non-existing included service!";
- *success = false;
- return result;
- }
- current_service_it->included_services.push_back(IncludedService{
- .handle = attr.handle,
- .uuid = attr.value.included_service.uuid,
- .start_handle = attr.value.included_service.handle,
- .end_handle = attr.value.included_service.end_handle,
- });
- } else if (attr.type == CHARACTERISTIC) {
- current_service_it->characteristics.emplace_back(Characteristic{
- .declaration_handle = attr.handle,
- .uuid = attr.value.characteristic.uuid,
- .value_handle = attr.value.characteristic.value_handle,
- .properties = attr.value.characteristic.properties,
- });
-
- } else {
- if (attr.type == CHARACTERISTIC_EXTENDED_PROPERTIES) {
- current_service_it->characteristics.back().descriptors.emplace_back(
- Descriptor{.handle = attr.handle,
- .uuid = attr.type,
- .characteristic_extended_properties =
- attr.value.characteristic_extended_properties});
-
- } else {
- current_service_it->characteristics.back().descriptors.emplace_back(
- Descriptor{.handle = attr.handle, .uuid = attr.type});
- }
- }
- }
- *success = true;
- return result;
-}
-
-Octet16 Database::Hash() const {
- int len = 0;
- // Compute how much space we need to actually hold the data.
- for (const Service& service : services) {
- len += 4 + UuidSize(service.uuid);
-
- for (const auto& is : service.included_services) {
- len += 8 + UuidSize(is.uuid);
- }
-
- for (const Characteristic& c : service.characteristics) {
- len += 7 + UuidSize(c.uuid);
-
- for (const Descriptor& d : c.descriptors) {
- if (UuidSize(d.uuid) != Uuid::kNumBytes16) {
- continue;
- }
- uint16_t value = d.uuid.As16Bit();
- if (value == GATT_UUID_CHAR_DESCRIPTION ||
- value == GATT_UUID_CHAR_CLIENT_CONFIG ||
- value == GATT_UUID_CHAR_SRVR_CONFIG ||
- value == GATT_UUID_CHAR_PRESENT_FORMAT ||
- value == GATT_UUID_CHAR_AGG_FORMAT) {
- len += 2 + UuidSize(d.uuid);
- } else if (value == GATT_UUID_CHAR_EXT_PROP) {
- len += 4 + UuidSize(d.uuid);
- }
- }
- }
- }
-
- std::vector<uint8_t> serialized(len);
- uint8_t* p = serialized.data();
- for (const Service& service : services) {
- UINT16_TO_STREAM(p, service.handle);
- if (service.is_primary) {
- UINT16_TO_STREAM(p, GATT_UUID_PRI_SERVICE);
- } else {
- UINT16_TO_STREAM(p, GATT_UUID_SEC_SERVICE);
- }
-
- if (UuidSize(service.uuid) == Uuid::kNumBytes16) {
- UINT16_TO_STREAM(p, service.uuid.As16Bit());
- } else {
- ARRAY_TO_STREAM(p, service.uuid.To128BitLE(), (int)Uuid::kNumBytes128);
- }
-
- for (const auto& is : service.included_services) {
- UINT16_TO_STREAM(p, is.handle);
- UINT16_TO_STREAM(p, GATT_UUID_INCLUDE_SERVICE);
- UINT16_TO_STREAM(p, is.start_handle);
- UINT16_TO_STREAM(p, is.end_handle);
-
- if (UuidSize(is.uuid) == Uuid::kNumBytes16) {
- UINT16_TO_STREAM(p, is.uuid.As16Bit());
- } else {
- ARRAY_TO_STREAM(p, is.uuid.To128BitLE(), (int)Uuid::kNumBytes128);
- }
- }
-
- for (const Characteristic& c : service.characteristics) {
- UINT16_TO_STREAM(p, c.declaration_handle);
- UINT16_TO_STREAM(p, GATT_UUID_CHAR_DECLARE);
- UINT8_TO_STREAM(p, c.properties);
- UINT16_TO_STREAM(p, c.value_handle);
-
- if (UuidSize(c.uuid) == Uuid::kNumBytes16) {
- UINT16_TO_STREAM(p, c.uuid.As16Bit());
- } else {
- ARRAY_TO_STREAM(p, c.uuid.To128BitLE(), (int)Uuid::kNumBytes128);
- }
-
- for (const Descriptor& d : c.descriptors) {
- if (UuidSize(d.uuid) != Uuid::kNumBytes16) continue;
- uint16_t value = d.uuid.As16Bit();
- if (value == GATT_UUID_CHAR_DESCRIPTION ||
- value == GATT_UUID_CHAR_CLIENT_CONFIG ||
- value == GATT_UUID_CHAR_SRVR_CONFIG ||
- value == GATT_UUID_CHAR_PRESENT_FORMAT ||
- value == GATT_UUID_CHAR_AGG_FORMAT) {
- UINT16_TO_STREAM(p, d.handle);
- UINT16_TO_STREAM(p, d.uuid.As16Bit());
- } else if (value == GATT_UUID_CHAR_EXT_PROP) {
- UINT16_TO_STREAM(p, d.handle);
- UINT16_TO_STREAM(p, d.uuid.As16Bit());
- UINT16_TO_STREAM(p, d.characteristic_extended_properties);
- }
- }
- }
- }
-
- std::reverse(serialized.begin(), serialized.end());
- return crypto_toolbox::aes_cmac(Octet16{0}, serialized.data(),
- serialized.size());
-}
-} // namespace gatt
diff --git a/bta/gatt/database.h b/bta/gatt/database.h
deleted file mode 100644
index 53c03e5..0000000
--- a/bta/gatt/database.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2018 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 <list>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "stack/include/bt_types.h" /* for Octet16 */
-#include "types/bluetooth/uuid.h"
-
-namespace gatt {
-constexpr uint16_t HANDLE_MIN = 0x0001;
-constexpr uint16_t HANDLE_MAX = 0xffff;
-
-/* Representation of GATT attribute for storage */
-struct StoredAttribute {
- uint16_t handle;
- bluetooth::Uuid type;
-
- union {
- /* primary or secondary service definition */
- struct {
- bluetooth::Uuid uuid;
- uint16_t end_handle;
- } service;
-
- /* included service definition */
- struct {
- uint16_t handle;
- uint16_t end_handle;
- bluetooth::Uuid uuid;
- } included_service;
-
- /* characteristic definition */
- struct {
- uint8_t properties;
- uint16_t value_handle;
- bluetooth::Uuid uuid;
- } characteristic;
-
- /* for descriptor we store value only for
- * «Characteristic Extended Properties» */
- uint16_t characteristic_extended_properties;
- } value;
-};
-
-struct IncludedService;
-struct Characteristic;
-struct Descriptor;
-
-struct Service {
- uint16_t handle;
- bluetooth::Uuid uuid;
- bool is_primary;
- uint16_t end_handle;
- std::vector<IncludedService> included_services;
- std::vector<Characteristic> characteristics;
-};
-
-struct IncludedService {
- uint16_t handle; /* definition handle */
- bluetooth::Uuid uuid;
- uint16_t start_handle; /* start handle of included service */
- uint16_t end_handle; /* end handle of included service */
-};
-
-struct Characteristic {
- uint16_t declaration_handle;
- bluetooth::Uuid uuid;
- uint16_t value_handle;
- uint8_t properties;
- std::vector<Descriptor> descriptors;
-};
-
-struct Descriptor {
- uint16_t handle;
- bluetooth::Uuid uuid;
- /* set and used for «Characteristic Extended Properties» only */
- uint16_t characteristic_extended_properties;
-};
-
-class DatabaseBuilder;
-
-class Database {
- public:
- /* Return true if there are no services in this database. */
- bool IsEmpty() const { return services.empty(); }
-
- /* Clear the GATT database. This method forces relocation to ensure no extra
- * space is used unnecesarly */
- void Clear() { std::list<Service>().swap(services); }
-
- /* Return list of services available in this database */
- const std::list<Service>& Services() const { return services; }
-
- std::string ToString() const;
-
- std::vector<gatt::StoredAttribute> Serialize() const;
-
- static Database Deserialize(const std::vector<gatt::StoredAttribute>& nv_attr,
- bool* success);
-
- /* Return 128 bit unique identifier of this GATT database */
- Octet16 Hash() const;
-
- friend class DatabaseBuilder;
-
- private:
- std::list<Service> services;
-};
-
-/* Find a service that should contain handle. Helper method for internal use
- * inside gatt namespace.*/
-Service* FindService(std::list<Service>& services, uint16_t handle);
-
-} // namespace gatt
diff --git a/bta/gatt/database_builder.cc b/bta/gatt/database_builder.cc
deleted file mode 100644
index 27c9191..0000000
--- a/bta/gatt/database_builder.cc
+++ /dev/null
@@ -1,254 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2018 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 <algorithm>
-#include <cstdint>
-#include <list>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "bt_target.h" // Must be first to define build configuration
-
-#include "bta/gatt/database.h"
-#include "bta/gatt/database_builder.h"
-#include "stack/include/gattdefs.h"
-#include "types/bluetooth/uuid.h"
-
-#include <base/logging.h>
-
-using bluetooth::Uuid;
-
-namespace gatt {
-
-void DatabaseBuilder::AddService(uint16_t handle, uint16_t end_handle,
- const Uuid& uuid, bool is_primary) {
- // general case optimization - we add services in order
- if (database.services.empty() ||
- database.services.back().end_handle < handle) {
- database.services.emplace_back(Service{
- .handle = handle,
- .uuid = uuid,
- .is_primary = is_primary,
- .end_handle = end_handle,
- });
- } else {
- auto& vec = database.services;
-
- // Find first service whose start handle is bigger than new service handle
- auto it = std::lower_bound(
- vec.begin(), vec.end(), handle,
- [](Service s, uint16_t handle) { return s.end_handle < handle; });
-
- // Insert new service just before it
- vec.emplace(it, Service{
- .handle = handle,
- .uuid = uuid,
- .is_primary = is_primary,
- .end_handle = end_handle,
- });
- }
-
- services_to_discover.insert({handle, end_handle});
-}
-
-void DatabaseBuilder::AddIncludedService(uint16_t handle, const Uuid& uuid,
- uint16_t start_handle,
- uint16_t end_handle) {
- Service* service = FindService(database.services, handle);
- if (!service) {
- LOG(ERROR) << "Illegal action to add to non-existing service!";
- return;
- }
-
- /* We discover all Primary Services first. If included service was not seen
- * before, it must be a Secondary Service */
- if (!FindService(database.services, start_handle)) {
- AddService(start_handle, end_handle, uuid, false /* not primary */);
- }
-
- service->included_services.push_back(IncludedService{
- .handle = handle,
- .uuid = uuid,
- .start_handle = start_handle,
- .end_handle = end_handle,
- });
-}
-
-void DatabaseBuilder::AddCharacteristic(uint16_t handle, uint16_t value_handle,
- const Uuid& uuid, uint8_t properties) {
- Service* service = FindService(database.services, handle);
- if (!service) {
- LOG(ERROR) << "Illegal action to add to non-existing service!";
- return;
- }
-
- if (service->end_handle < value_handle)
- LOG(WARNING) << "Remote device violates spec: value_handle="
- << loghex(value_handle) << " is after service end_handle="
- << loghex(service->end_handle);
-
- service->characteristics.emplace_back(Characteristic{
- .declaration_handle = handle,
- .uuid = uuid,
- .value_handle = value_handle,
- .properties = properties,
- });
- return;
-}
-
-void DatabaseBuilder::AddDescriptor(uint16_t handle, const Uuid& uuid) {
- Service* service = FindService(database.services, handle);
- if (!service) {
- LOG(ERROR) << "Illegal action to add to non-existing service!";
- return;
- }
-
- if (service->characteristics.empty()) {
- LOG(ERROR) << __func__
- << ": Illegal action to add to non-existing characteristic!";
- return;
- }
-
- Characteristic* char_node = &service->characteristics.front();
- for (auto it = service->characteristics.begin();
- it != service->characteristics.end(); it++) {
- if (it->declaration_handle > handle) break;
- char_node = &(*it);
- }
-
- char_node->descriptors.emplace_back(
- gatt::Descriptor{.handle = handle, .uuid = uuid});
-
- // We must read value for Characteristic Extended Properties
- if (uuid == Uuid::From16Bit(GATT_UUID_CHAR_EXT_PROP)) {
- descriptor_handles_to_read.emplace_back(handle);
- }
-}
-
-bool DatabaseBuilder::StartNextServiceExploration() {
- while (!services_to_discover.empty()) {
- auto handle_range = services_to_discover.begin();
- pending_service = *handle_range;
- services_to_discover.erase(handle_range);
-
- // Empty service declaration, nothing to explore, skip to next.
- if (pending_service.first == pending_service.second) continue;
-
- pending_characteristic = HANDLE_MIN;
- return true;
- }
- return false;
-}
-
-const std::pair<uint16_t, uint16_t>&
-DatabaseBuilder::CurrentlyExploredService() {
- return pending_service;
-}
-
-std::pair<uint16_t, uint16_t> DatabaseBuilder::NextDescriptorRangeToExplore() {
- Service* service = FindService(database.services, pending_service.first);
- if (!service || service->characteristics.empty()) {
- return {HANDLE_MAX, HANDLE_MAX};
- }
-
- for (auto it = service->characteristics.cbegin();
- it != service->characteristics.cend(); it++) {
- if (it->declaration_handle > pending_characteristic) {
- auto next = std::next(it);
-
- /* Characteristic Declaration is followed by Characteristic Value
- * Declaration, first descriptor is after that, see BT Spect 5.0 Vol 3,
- * Part G 3.3.2 and 3.3.3 */
- uint16_t start = it->declaration_handle + 2;
- uint16_t end;
- if (next != service->characteristics.end())
- end = next->declaration_handle - 1;
- else
- end = service->end_handle;
-
- // No place for descriptor - skip to next characteristic
- if (start > end) continue;
-
- pending_characteristic = start;
- return {start, end};
- }
- }
-
- pending_characteristic = HANDLE_MAX;
- return {HANDLE_MAX, HANDLE_MAX};
-}
-
-Descriptor* FindDescriptorByHandle(std::list<Service>& services,
- uint16_t handle) {
- Service* service = FindService(services, handle);
- if (!service) return nullptr;
-
- Characteristic* char_node = &service->characteristics.front();
- for (auto it = service->characteristics.begin();
- it != service->characteristics.end(); it++) {
- if (it->declaration_handle > handle) break;
- char_node = &(*it);
- }
-
- for (auto& descriptor : char_node->descriptors) {
- if (descriptor.handle == handle) return &descriptor;
- }
-
- return nullptr;
-}
-
-bool DatabaseBuilder::SetValueOfDescriptors(
- const std::vector<uint16_t>& values) {
- if (values.size() > descriptor_handles_to_read.size()) {
- LOG(ERROR) << "values.size() <= descriptors.size() expected";
- descriptor_handles_to_read.clear();
- return false;
- }
-
- for (size_t i = 0; i < values.size(); i++) {
- Descriptor* d = FindDescriptorByHandle(database.services,
- descriptor_handles_to_read[i]);
- if (!d) {
- LOG(ERROR) << __func__ << "non-existing descriptor!";
- descriptor_handles_to_read.clear();
- return false;
- }
-
- d->characteristic_extended_properties = values[i];
- }
-
- descriptor_handles_to_read.erase(
- descriptor_handles_to_read.begin(),
- descriptor_handles_to_read.begin() + values.size());
- return true;
-}
-
-bool DatabaseBuilder::InProgress() const { return !database.services.empty(); }
-
-Database DatabaseBuilder::Build() {
- Database tmp = database;
- database.Clear();
- return tmp;
-}
-
-void DatabaseBuilder::Clear() { database.Clear(); }
-
-std::string DatabaseBuilder::ToString() const { return database.ToString(); }
-
-} // namespace gatt
diff --git a/bta/gatt/database_builder.h b/bta/gatt/database_builder.h
deleted file mode 100644
index f33b2e7..0000000
--- a/bta/gatt/database_builder.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2018 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 <utility>
-
-#include "bta/gatt/database.h"
-#include "types/bluetooth/uuid.h"
-
-namespace gatt {
-
-class DatabaseBuilder {
- public:
- constexpr static std::pair<uint16_t, uint16_t> EXPLORE_END =
- std::make_pair(0xFFFF, 0xFFFF);
-
- void AddService(uint16_t handle, uint16_t end_handle,
- const bluetooth::Uuid& uuid, bool is_primary);
- void AddIncludedService(uint16_t handle, const bluetooth::Uuid& uuid,
- uint16_t start_handle, uint16_t end_handle);
- void AddCharacteristic(uint16_t handle, uint16_t value_handle,
- const bluetooth::Uuid& uuid, uint8_t properties);
- void AddDescriptor(uint16_t handle, const bluetooth::Uuid& uuid);
-
- /* Returns true if next service exploration started, false if there are no
- * more services to explore. */
- bool StartNextServiceExploration();
-
- /* Return pair with start and end handle of the currently explored service.
- */
- const std::pair<uint16_t, uint16_t>& CurrentlyExploredService();
-
- /* Return pair with start and end handle of the descriptor range to discover,
- * or DatabaseBuilder::EXPLORE_END if no more descriptors left.
- */
- std::pair<uint16_t, uint16_t> NextDescriptorRangeToExplore();
-
- /* Return vector of "Characteristic Extended Properties" descriptors that must
- * be read as part of service discovery process */
- std::vector<uint16_t> DescriptorHandlesToRead() {
- return descriptor_handles_to_read;
- }
-
- /* Assign value to descriptors from |DescriptorHandlesToRead()|. Values must
- * be in same order. Returns |true| if all goes well, |false| if there is
- * problem mapping values to descriptors. */
- bool SetValueOfDescriptors(const std::vector<uint16_t>& values);
-
- /* Returns true, if GATT discovery is in progress, false if discovery was not
- * started, or is already finished.
- */
- // TODO(jpawlowski): in the future, we might create this object only for the
- // time of discovery, in such case InProgress won't be needed, because object
- // existence will mean discovery is pending
- bool InProgress() const;
-
- /* Call this method at end of GATT discovery, to obtain object representing
- * the database of remote device */
- Database Build();
-
- void Clear();
-
- /* Return text representation of internal state for debugging purposes */
- std::string ToString() const;
-
- private:
- Database database;
- /* Start and end handle of service that is currently being discovered on the
- * remote device */
- std::pair<uint16_t, uint16_t> pending_service;
- /* Characteristic inside pending_service that is currently being explored */
- uint16_t pending_characteristic;
-
- /* sorted, unique set of start_handle, end_handle pair of all services that
- * have not yet been discovered */
- std::set<std::pair<uint16_t, uint16_t>> services_to_discover;
-
- /* handles of "Characteristic Extended Properties" descriptors that must be
- * read as part of service discovery process */
- std::vector<uint16_t> descriptor_handles_to_read;
-};
-
-} // namespace gatt
diff --git a/bta/groups/groups.cc b/bta/groups/groups.cc
deleted file mode 100644
index dff6821..0000000
--- a/bta/groups/groups.cc
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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 <algorithm>
-#include <map>
-#include <unordered_set>
-
-#include "base/logging.h"
-#include "bta_groups.h"
-#include "btif_storage.h"
-#include "types/bluetooth/uuid.h"
-#include "types/raw_address.h"
-
-#include <base/logging.h>
-
-using bluetooth::Uuid;
-
-namespace bluetooth {
-namespace groups {
-
-class DeviceGroupsImpl;
-DeviceGroupsImpl* instance;
-static constexpr int kMaxGroupId = 0xEF;
-
-class DeviceGroup {
- public:
- DeviceGroup(int group_id, Uuid uuid)
- : group_id_(group_id), group_uuid_(uuid) {}
- void Add(const RawAddress& addr) { devices_.insert(addr); }
- void Remove(const RawAddress& addr) { devices_.erase(addr); }
- bool Contains(const RawAddress& addr) const {
- return (devices_.count(addr) != 0);
- }
-
- void ForEachDevice(std::function<void(const RawAddress&)> cb) const {
- for (auto const& addr : devices_) {
- cb(addr);
- }
- }
-
- int Size(void) const { return devices_.size(); }
- int GetGroupId(void) const { return group_id_; }
- const Uuid& GetUuid(void) const { return group_uuid_; }
-
- private:
- int group_id_;
- Uuid group_uuid_;
- std::unordered_set<RawAddress> devices_;
-};
-
-class DeviceGroupsImpl : public DeviceGroups {
- static constexpr uint8_t GROUP_STORAGE_CURRENT_LAYOUT_MAGIC = 0x10;
- static constexpr size_t GROUP_STORAGE_HEADER_SZ =
- sizeof(GROUP_STORAGE_CURRENT_LAYOUT_MAGIC) +
- sizeof(uint8_t); /* num_of_groups */
- static constexpr size_t GROUP_STORAGE_ENTRY_SZ =
- sizeof(uint8_t) /* group_id */ + Uuid::kNumBytes128;
-
- public:
- DeviceGroupsImpl(DeviceGroupsCallbacks* callbacks) {
- AddCallbacks(callbacks);
- btif_storage_load_bonded_groups();
- }
-
- int GetGroupId(const RawAddress& addr, Uuid uuid) const override {
- for (const auto& [id, g] : groups_) {
- if ((g.Contains(addr)) && (uuid == g.GetUuid())) return id;
- }
- return kGroupUnknown;
- }
-
- void add_to_group(const RawAddress& addr, DeviceGroup* group) {
- group->Add(addr);
-
- bool first_device_in_group = (group->Size() == 1);
-
- for (auto c : callbacks_) {
- if (first_device_in_group) {
- c->OnGroupAdded(addr, group->GetUuid(), group->GetGroupId());
- } else {
- c->OnGroupMemberAdded(addr, group->GetGroupId());
- }
- }
- }
-
- int AddDevice(const RawAddress& addr, Uuid uuid, int group_id) override {
- DeviceGroup* group = nullptr;
-
- if (group_id == kGroupUnknown) {
- auto gid = GetGroupId(addr, uuid);
- if (gid != kGroupUnknown) return gid;
- group = create_group(uuid);
- } else {
- group = get_or_create_group_with_id(group_id, uuid);
- if (!group) {
- return kGroupUnknown;
- }
- }
-
- LOG_ASSERT(group);
-
- if (group->Contains(addr)) {
- LOG(ERROR) << __func__ << " device " << addr
- << " already in the group: " << group_id;
- return group->GetGroupId();
- }
-
- add_to_group(addr, group);
-
- btif_storage_add_groups(addr);
- return group->GetGroupId();
- }
-
- void RemoveDevice(const RawAddress& addr, int group_id) override {
- int num_of_groups_dev_belongs = 0;
-
- /* Remove from all the groups. Usually happens on unbond */
- for (auto it = groups_.begin(); it != groups_.end();) {
- auto& [id, g] = *it;
- if (!g.Contains(addr)) {
- ++it;
- continue;
- }
-
- num_of_groups_dev_belongs++;
-
- if ((group_id != bluetooth::groups::kGroupUnknown) && (group_id != id)) {
- ++it;
- continue;
- }
-
- num_of_groups_dev_belongs--;
-
- g.Remove(addr);
- for (auto c : callbacks_) {
- c->OnGroupMemberRemoved(addr, id);
- }
-
- if (g.Size() == 0) {
- for (auto c : callbacks_) {
- c->OnGroupRemoved(g.GetUuid(), g.GetGroupId());
- }
- it = groups_.erase(it);
- } else {
- ++it;
- }
- }
-
- btif_storage_remove_groups(addr);
- if (num_of_groups_dev_belongs > 0) {
- btif_storage_add_groups(addr);
- }
- }
-
- bool SerializeGroups(const RawAddress& addr,
- std::vector<uint8_t>& out) const {
- auto num_groups = std::count_if(
- groups_.begin(), groups_.end(), [&addr](auto& id_group_pair) {
- return id_group_pair.second.Contains(addr);
- });
- if ((num_groups == 0) || (num_groups > std::numeric_limits<uint8_t>::max()))
- return false;
-
- out.resize(GROUP_STORAGE_HEADER_SZ + (num_groups * GROUP_STORAGE_ENTRY_SZ));
- auto* ptr = out.data();
-
- /* header */
- UINT8_TO_STREAM(ptr, GROUP_STORAGE_CURRENT_LAYOUT_MAGIC);
- UINT8_TO_STREAM(ptr, num_groups);
-
- /* group entries */
- for (const auto& [id, g] : groups_) {
- if (g.Contains(addr)) {
- UINT8_TO_STREAM(ptr, id);
-
- Uuid::UUID128Bit uuid128 = g.GetUuid().To128BitLE();
- memcpy(ptr, uuid128.data(), Uuid::kNumBytes128);
- ptr += Uuid::kNumBytes128;
- }
- }
-
- return true;
- }
-
- void DeserializeGroups(const RawAddress& addr,
- const std::vector<uint8_t>& in) {
- if (in.size() < GROUP_STORAGE_HEADER_SZ + GROUP_STORAGE_ENTRY_SZ) return;
-
- auto* ptr = in.data();
-
- uint8_t magic;
- STREAM_TO_UINT8(magic, ptr);
-
- if (magic == GROUP_STORAGE_CURRENT_LAYOUT_MAGIC) {
- uint8_t num_groups;
- STREAM_TO_UINT8(num_groups, ptr);
-
- if (in.size() <
- GROUP_STORAGE_HEADER_SZ + (num_groups * GROUP_STORAGE_ENTRY_SZ)) {
- LOG(ERROR) << "Invalid persistent storage data";
- return;
- }
-
- /* group entries */
- while (num_groups--) {
- uint8_t id;
- STREAM_TO_UINT8(id, ptr);
-
- Uuid::UUID128Bit uuid128;
- STREAM_TO_ARRAY(uuid128.data(), ptr, (int)Uuid::kNumBytes128);
-
- auto* group =
- get_or_create_group_with_id(id, Uuid::From128BitLE(uuid128));
- if (group) add_to_group(addr, group);
-
- for (auto c : callbacks_) {
- c->OnGroupAddFromStorage(addr, Uuid::From128BitLE(uuid128), id);
- }
- }
- }
- }
-
- void AddCallbacks(DeviceGroupsCallbacks* callbacks) {
- callbacks_.push_back(std::move(callbacks));
-
- /* Notify new user about known groups */
- for (const auto& [id, g] : groups_) {
- auto group_uuid = g.GetUuid();
- auto group_id = g.GetGroupId();
- g.ForEachDevice([&](auto& dev) {
- callbacks->OnGroupAdded(dev, group_uuid, group_id);
- });
- }
- }
-
- bool Clear(DeviceGroupsCallbacks* callbacks) {
- auto it = find_if(callbacks_.begin(), callbacks_.end(),
- [callbacks](auto c) { return c == callbacks; });
-
- if (it != callbacks_.end()) callbacks_.erase(it);
-
- if (callbacks_.size() != 0) {
- return false;
- }
- /* When all clients were unregistered */
- groups_.clear();
- return true;
- }
-
- private:
- DeviceGroup* find_device_group(int group_id) {
- return groups_.count(group_id) ? &groups_.at(group_id) : nullptr;
- }
-
- DeviceGroup* get_or_create_group_with_id(int group_id, Uuid uuid) {
- auto group = find_device_group(group_id);
- if (group) {
- if (group->GetUuid() != uuid) {
- LOG(ERROR) << __func__ << " group " << group_id
- << " exists but for different uuid: " << group->GetUuid()
- << ", user request uuid: " << uuid;
- return nullptr;
- }
-
- LOG(INFO) << __func__ << " group already exists: " << group_id;
- return group;
- }
-
- DeviceGroup new_group(group_id, uuid);
- groups_.insert({group_id, std::move(new_group)});
-
- return &groups_.at(group_id);
- }
-
- DeviceGroup* create_group(Uuid& uuid) {
- /* Generate new group id and return empty group */
- /* Find first free id */
-
- int group_id = -1;
- for (int i = 1; i < kMaxGroupId; i++) {
- if (groups_.count(i) == 0) {
- group_id = i;
- break;
- }
- }
-
- if (group_id < 0) {
- LOG(ERROR) << __func__ << " too many groups";
- return nullptr;
- }
-
- DeviceGroup group(group_id, uuid);
- groups_.insert({group_id, std::move(group)});
-
- return &groups_.at(group_id);
- }
-
- std::map<int, DeviceGroup> groups_;
- std::list<DeviceGroupsCallbacks*> callbacks_;
-};
-
-void DeviceGroups::Initialize(DeviceGroupsCallbacks* callbacks) {
- if (instance == nullptr) {
- instance = new DeviceGroupsImpl(callbacks);
- return;
- }
-
- instance->AddCallbacks(callbacks);
-}
-
-void DeviceGroups::AddFromStorage(const RawAddress& addr,
- const std::vector<uint8_t>& in) {
- if (!instance) {
- LOG(ERROR) << __func__ << ": Not initialized yet";
- return;
- }
-
- instance->DeserializeGroups(addr, in);
-}
-
-bool DeviceGroups::GetForStorage(const RawAddress& addr,
- std::vector<uint8_t>& out) {
- if (!instance) {
- LOG(ERROR) << __func__ << ": Not initialized yet";
- return false;
- }
-
- return instance->SerializeGroups(addr, out);
-}
-
-void DeviceGroups::CleanUp(DeviceGroupsCallbacks* callbacks) {
- if (!instance) return;
-
- if (instance->Clear(callbacks)) {
- delete (instance);
- instance = nullptr;
- }
-}
-DeviceGroups* DeviceGroups::Get() { return instance; }
-
-} // namespace groups
-} // namespace bluetooth
diff --git a/bta/groups/groups_test.cc b/bta/groups/groups_test.cc
deleted file mode 100644
index 8966284..0000000
--- a/bta/groups/groups_test.cc
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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 <base/logging.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "bta_groups.h"
-#include "types/bluetooth/uuid.h"
-#include "types/raw_address.h"
-
-std::map<std::string, int> mock_function_count_map;
-
-namespace bluetooth {
-namespace groups {
-
-using ::testing::_;
-using ::testing::DoAll;
-using ::testing::Invoke;
-using ::testing::Mock;
-using ::testing::Return;
-using ::testing::SaveArg;
-using ::testing::SetArgPointee;
-using ::testing::Test;
-
-using bluetooth::groups::DeviceGroups;
-using bluetooth::groups::DeviceGroupsCallbacks;
-
-DeviceGroupsCallbacks* dev_callbacks;
-
-RawAddress GetTestAddress(int index) {
- CHECK_LT(index, UINT8_MAX);
- RawAddress result = {
- {0xC0, 0xDE, 0xC0, 0xDE, 0x00, static_cast<uint8_t>(index)}};
- return result;
-}
-
-class MockGroupsCallbacks : public DeviceGroupsCallbacks {
- public:
- MockGroupsCallbacks() = default;
- ~MockGroupsCallbacks() override = default;
-
- MOCK_METHOD((void), OnGroupAdded,
- (const RawAddress& address, const bluetooth::Uuid& uuid,
- int group_id),
- (override));
- MOCK_METHOD((void), OnGroupMemberAdded,
- (const RawAddress& address, int group_id), (override));
-
- MOCK_METHOD((void), OnGroupRemoved,
- (const bluetooth::Uuid& uuid, int group_id), (override));
- MOCK_METHOD((void), OnGroupMemberRemoved,
- (const RawAddress& address, int group_id), (override));
- MOCK_METHOD((void), OnGroupAddFromStorage,
- (const RawAddress& address, const bluetooth::Uuid& uuid,
- int group_id),
- (override));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockGroupsCallbacks);
-};
-
-class GroupsTest : public ::testing::Test {
- protected:
- void SetUp() override {
- mock_function_count_map.clear();
- callbacks.reset(new MockGroupsCallbacks());
- }
-
- void TearDown() override { DeviceGroups::CleanUp(callbacks.get()); }
-
- std::unique_ptr<MockGroupsCallbacks> callbacks;
-};
-
-TEST_F(GroupsTest, test_initialize) {
- DeviceGroups::Initialize(callbacks.get());
- ASSERT_TRUE(DeviceGroups::Get());
- DeviceGroups::CleanUp(callbacks.get());
-}
-
-TEST_F(GroupsTest, test_initialize_twice) {
- DeviceGroups::Initialize(callbacks.get());
- DeviceGroups* dev_groups_p = DeviceGroups::Get();
- DeviceGroups::Initialize(callbacks.get());
- ASSERT_EQ(dev_groups_p, DeviceGroups::Get());
- DeviceGroups::CleanUp(callbacks.get());
- dev_groups_p->CleanUp(callbacks.get());
-}
-
-TEST_F(GroupsTest, test_cleanup_initialized) {
- DeviceGroups::Initialize(callbacks.get());
- DeviceGroups::CleanUp(callbacks.get());
- ASSERT_FALSE(DeviceGroups::Get());
-}
-
-TEST_F(GroupsTest, test_cleanup_uninitialized) {
- DeviceGroups::CleanUp(callbacks.get());
- ASSERT_FALSE(DeviceGroups::Get());
-}
-
-TEST_F(GroupsTest, test_groups_add_single_device) {
- EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(1), Uuid::kEmpty, 7));
- DeviceGroups::Initialize(callbacks.get());
- DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 7);
- DeviceGroups::CleanUp(callbacks.get());
-}
-
-TEST_F(GroupsTest, test_groups_add_two_devices) {
- EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(1), _, 7));
- EXPECT_CALL(*callbacks, OnGroupMemberAdded(GetTestAddress(2), 7));
- DeviceGroups::Initialize(callbacks.get());
- DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 7);
- DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 7);
- DeviceGroups::CleanUp(callbacks.get());
-}
-
-TEST_F(GroupsTest, test_groups_remove_device) {
- EXPECT_CALL(*callbacks, OnGroupMemberRemoved(GetTestAddress(2), 7));
- DeviceGroups::Initialize(callbacks.get());
- DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 7);
- DeviceGroups::Get()->RemoveDevice(GetTestAddress(2));
- ASSERT_EQ(kGroupUnknown,
- DeviceGroups::Get()->GetGroupId(GetTestAddress(2), Uuid::kEmpty));
- ASSERT_EQ(kGroupUnknown,
- DeviceGroups::Get()->GetGroupId(GetTestAddress(3), Uuid::kEmpty));
- DeviceGroups::CleanUp(callbacks.get());
-}
-
-TEST_F(GroupsTest, test_add_multiple_devices) {
- EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(2), Uuid::kEmpty, 7));
- EXPECT_CALL(*callbacks, OnGroupMemberAdded(_, 7)).Times(2);
- DeviceGroups::Initialize(callbacks.get());
- DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 7);
- DeviceGroups::Get()->AddDevice(GetTestAddress(3), Uuid::kEmpty, 7);
- DeviceGroups::Get()->AddDevice(GetTestAddress(4), Uuid::kEmpty, 7);
- DeviceGroups::CleanUp(callbacks.get());
-}
-
-TEST_F(GroupsTest, test_remove_multiple_devices) {
- EXPECT_CALL(*callbacks, OnGroupMemberRemoved(_, _)).Times(3);
- DeviceGroups::Initialize(callbacks.get());
- DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 7);
- DeviceGroups::Get()->AddDevice(GetTestAddress(3), Uuid::kEmpty, 7);
- DeviceGroups::Get()->AddDevice(GetTestAddress(4), Uuid::kEmpty, 7);
- DeviceGroups::Get()->RemoveDevice(GetTestAddress(2));
- DeviceGroups::Get()->RemoveDevice(GetTestAddress(3));
- DeviceGroups::Get()->RemoveDevice(GetTestAddress(4));
- DeviceGroups::CleanUp(callbacks.get());
-}
-
-TEST_F(GroupsTest, test_add_multiple_groups) {
- EXPECT_CALL(*callbacks, OnGroupAdded(_, _, _)).Times(2);
- DeviceGroups::Initialize(callbacks.get());
- DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 8);
- DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 9);
- DeviceGroups::CleanUp(callbacks.get());
-}
-
-TEST_F(GroupsTest, test_remove_multiple_groups) {
- Uuid uuid1 = Uuid::GetRandom();
- Uuid uuid2 = Uuid::GetRandom();
- ASSERT_NE(uuid1, uuid2);
-
- EXPECT_CALL(*callbacks, OnGroupAdded(_, _, _)).Times(2);
- DeviceGroups::Initialize(callbacks.get());
- DeviceGroups::Get()->AddDevice(GetTestAddress(1), uuid1, 8);
- DeviceGroups::Get()->AddDevice(GetTestAddress(1), uuid2, 9);
- DeviceGroups::Get()->AddDevice(GetTestAddress(2), uuid2, 9);
-
- EXPECT_CALL(*callbacks, OnGroupMemberRemoved(GetTestAddress(1), 8));
- EXPECT_CALL(*callbacks, OnGroupMemberRemoved(GetTestAddress(1), 9));
- EXPECT_CALL(*callbacks, OnGroupRemoved(uuid1, 8));
- EXPECT_CALL(*callbacks, OnGroupRemoved(uuid2, 9)).Times(0);
- DeviceGroups::Get()->RemoveDevice(GetTestAddress(1));
-
- DeviceGroups::CleanUp(callbacks.get());
-}
-
-TEST_F(GroupsTest, test_remove_device_fo_devices) {
- Uuid uuid1 = Uuid::GetRandom();
- Uuid uuid2 = Uuid::GetRandom();
- EXPECT_CALL(*callbacks, OnGroupAdded(_, _, _)).Times(2);
- DeviceGroups::Initialize(callbacks.get());
- DeviceGroups::Get()->AddDevice(GetTestAddress(1), uuid1, 8);
- DeviceGroups::Get()->AddDevice(GetTestAddress(1), uuid2, 9);
-
- EXPECT_CALL(*callbacks, OnGroupRemoved(uuid1, 8));
- EXPECT_CALL(*callbacks, OnGroupRemoved(uuid2, 9)).Times(0);
-
- DeviceGroups::Get()->RemoveDevice(GetTestAddress(1), 8);
-
- Mock::VerifyAndClearExpectations(&callbacks);
-
- EXPECT_CALL(*callbacks, OnGroupRemoved(uuid1, 8)).Times(0);
- EXPECT_CALL(*callbacks, OnGroupRemoved(uuid2, 9));
-
- DeviceGroups::Get()->RemoveDevice(GetTestAddress(1), 9);
-}
-
-TEST_F(GroupsTest, test_add_devices_different_group_id) {
- DeviceGroups::Initialize(callbacks.get());
- DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 10);
- DeviceGroups::Get()->AddDevice(GetTestAddress(3), Uuid::kEmpty, 11);
- auto group_id_1 =
- DeviceGroups::Get()->GetGroupId(GetTestAddress(2), Uuid::kEmpty);
- auto group_id_2 =
- DeviceGroups::Get()->GetGroupId(GetTestAddress(3), Uuid::kEmpty);
- ASSERT_TRUE(group_id_1 != group_id_2);
- DeviceGroups::CleanUp(callbacks.get());
-}
-
-TEST_F(GroupsTest, test_group_id_assign) {
- int captured_gid1 = kGroupUnknown;
- int captured_gid2 = kGroupUnknown;
-
- DeviceGroups::Initialize(callbacks.get());
- EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(1), _, _))
- .WillOnce(SaveArg<2>(&captured_gid1));
- EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(2), _, _))
- .WillOnce(SaveArg<2>(&captured_gid2));
-
- int gid1 = DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty,
- bluetooth::groups::kGroupUnknown);
- int gid2 = DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty);
- int gid3 = DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty);
- ASSERT_NE(bluetooth::groups::kGroupUnknown, gid1);
- ASSERT_NE(bluetooth::groups::kGroupUnknown, gid2);
- ASSERT_EQ(gid2, gid3);
- ASSERT_EQ(gid1, captured_gid1);
- ASSERT_EQ(gid2, captured_gid2);
-
- DeviceGroups::CleanUp(callbacks.get());
-}
-
-TEST_F(GroupsTest, test_storage_calls) {
- ASSERT_EQ(0, mock_function_count_map["btif_storage_load_bonded_groups"]);
- DeviceGroups::Initialize(callbacks.get());
- ASSERT_EQ(1, mock_function_count_map["btif_storage_load_bonded_groups"]);
-
- ASSERT_EQ(0, mock_function_count_map["btif_storage_add_groups"]);
- DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 7);
- DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 8);
- ASSERT_EQ(2, mock_function_count_map["btif_storage_add_groups"]);
-
- DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 7);
- DeviceGroups::Get()->AddDevice(GetTestAddress(3), Uuid::kEmpty, 7);
- ASSERT_EQ(4, mock_function_count_map["btif_storage_add_groups"]);
-
- ASSERT_EQ(0, mock_function_count_map["btif_storage_remove_groups"]);
- DeviceGroups::Get()->RemoveDevice(GetTestAddress(1));
- DeviceGroups::Get()->RemoveDevice(GetTestAddress(2));
- DeviceGroups::Get()->RemoveDevice(GetTestAddress(3));
- ASSERT_EQ(3, mock_function_count_map["btif_storage_remove_groups"]);
-
- DeviceGroups::CleanUp(callbacks.get());
-}
-
-TEST_F(GroupsTest, test_storage_content) {
- int gid1 = bluetooth::groups::kGroupUnknown;
- int gid2 = bluetooth::groups::kGroupUnknown;
- Uuid uuid1 = Uuid::GetRandom();
- Uuid uuid2 = Uuid::GetRandom();
- ASSERT_NE(uuid1, uuid2);
-
- DeviceGroups::Initialize(callbacks.get());
- gid1 = DeviceGroups::Get()->AddDevice(GetTestAddress(1), uuid1, gid1);
- DeviceGroups::Get()->AddDevice(GetTestAddress(2), uuid1, gid1);
- gid2 = DeviceGroups::Get()->AddDevice(GetTestAddress(2), uuid2, gid2);
- ASSERT_NE(bluetooth::groups::kGroupUnknown, gid1);
- ASSERT_NE(gid1, gid2);
-
- std::vector<uint8_t> dev1_storage;
- std::vector<uint8_t> dev2_storage;
-
- // Store to byte buffer
- DeviceGroups::GetForStorage(GetTestAddress(1), dev1_storage);
- DeviceGroups::GetForStorage(GetTestAddress(2), dev2_storage);
- ASSERT_NE(0u, dev1_storage.size());
- ASSERT_TRUE(dev2_storage.size() > dev1_storage.size());
-
- // Clean it up
- DeviceGroups::CleanUp(callbacks.get());
- ASSERT_EQ(nullptr, DeviceGroups::Get());
-
- // Restore dev1 from the byte buffer
- DeviceGroups::Initialize(callbacks.get());
- EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(1), uuid1, gid1));
- DeviceGroups::AddFromStorage(GetTestAddress(1), dev1_storage);
-
- // Restore dev2 from the byte buffer
- EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(2), uuid2, gid2));
- EXPECT_CALL(*callbacks, OnGroupMemberAdded(GetTestAddress(2), gid1)).Times(1);
- DeviceGroups::AddFromStorage(GetTestAddress(2), dev2_storage);
-
- DeviceGroups::CleanUp(callbacks.get());
-}
-
-} // namespace groups
-} // namespace bluetooth
diff --git a/bta/hd/bta_hd_act.cc b/bta/hd/bta_hd_act.cc
deleted file mode 100644
index 3d455d6..0000000
--- a/bta/hd/bta_hd_act.cc
+++ /dev/null
@@ -1,776 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2016 The Android Open Source Project
- * Copyright 2005-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains the HID device action functions.
- *
- ******************************************************************************/
-
-#include <cstdint>
-#include <string>
-
-// BTA_HD_INCLUDED
-#include "bt_target.h" // Must be first to define build configuration
-#if defined(BTA_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE)
-
-#include "bta/hd/bta_hd_int.h"
-#include "include/hardware/bt_hd.h"
-#include "osi/include/allocator.h"
-#include "osi/include/log.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/hidd_api.h"
-#include "types/raw_address.h"
-
-static void bta_hd_cback(const RawAddress& bd_addr, uint8_t event,
- uint32_t data, BT_HDR* pdata);
-
-static bool check_descriptor(uint8_t* data, uint16_t length,
- bool* has_report_id) {
- uint8_t* ptr = data;
-
- *has_report_id = FALSE;
-
- while (ptr < data + length) {
- uint8_t item = *ptr++;
-
- switch (item) {
- case 0xfe: // long item indicator
- if (ptr < data + length) {
- ptr += ((*ptr) + 2);
- } else {
- return false;
- }
- break;
-
- case 0x85: // Report ID
- *has_report_id = TRUE;
- [[fallthrough]];
- default:
- ptr += (item & 0x03);
- break;
- }
- }
-
- return (ptr == data + length);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_api_enable
- *
- * Description Enables HID device
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hd_api_enable(tBTA_HD_DATA* p_data) {
- tBTA_HD_STATUS status = BTA_HD_ERROR;
- tHID_STATUS ret;
-
- APPL_TRACE_API("%s", __func__);
-
- HID_DevInit();
-
- memset(&bta_hd_cb, 0, sizeof(tBTA_HD_CB));
-
- /* store parameters */
- bta_hd_cb.p_cback = p_data->api_enable.p_cback;
-
- ret = HID_DevRegister(bta_hd_cback);
- if (ret == HID_SUCCESS) {
- status = BTA_HD_OK;
- } else {
- APPL_TRACE_ERROR("%s: Failed to register HID device (%d)", __func__, ret);
- }
-
- /* signal BTA call back event */
- tBTA_HD bta_hd;
- bta_hd.status = status;
- (*bta_hd_cb.p_cback)(BTA_HD_ENABLE_EVT, &bta_hd);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_api_disable
- *
- * Description Disables HID device
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hd_api_disable(void) {
- tBTA_HD_STATUS status = BTA_HD_ERROR;
- tHID_STATUS ret;
-
- APPL_TRACE_API("%s", __func__);
-
- /* service is not enabled */
- if (bta_hd_cb.p_cback == NULL) return;
-
- /* Remove service record */
- if (bta_hd_cb.sdp_handle != 0) {
- SDP_DeleteRecord(bta_hd_cb.sdp_handle);
- bta_sys_remove_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
- }
-
- /* Deregister with lower layer */
- ret = HID_DevDeregister();
- if (ret == HID_SUCCESS) {
- status = BTA_HD_OK;
- } else {
- APPL_TRACE_ERROR("%s: Failed to deregister HID device (%s)", __func__, ret);
- }
-
- tBTA_HD bta_hd;
- bta_hd.status = status;
- (*bta_hd_cb.p_cback)(BTA_HD_DISABLE_EVT, &bta_hd);
-
- memset(&bta_hd_cb, 0, sizeof(tBTA_HD_CB));
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_register_act
- *
- * Description Registers SDP record
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hd_register_act(tBTA_HD_DATA* p_data) {
- tBTA_HD ret;
- tBTA_HD_REGISTER_APP* p_app_data = (tBTA_HD_REGISTER_APP*)p_data;
- bool use_report_id = FALSE;
-
- APPL_TRACE_API("%s", __func__);
-
- ret.reg_status.in_use = FALSE;
-
- /* Check if len doesn't exceed BTA_HD_APP_DESCRIPTOR_LEN and descriptor
- * itself is well-formed. Also check if descriptor has Report Id item so we
- * know if report will have prefix or not. */
- if (p_app_data->d_len > BTA_HD_APP_DESCRIPTOR_LEN ||
- !check_descriptor(p_app_data->d_data, p_app_data->d_len,
- &use_report_id)) {
- APPL_TRACE_ERROR("%s: Descriptor is too long or malformed", __func__);
- ret.reg_status.status = BTA_HD_ERROR;
- (*bta_hd_cb.p_cback)(BTA_HD_REGISTER_APP_EVT, &ret);
- return;
- }
-
- ret.reg_status.status = BTA_HD_OK;
-
- /* Remove old record if for some reason it's already registered */
- if (bta_hd_cb.sdp_handle != 0) {
- SDP_DeleteRecord(bta_hd_cb.sdp_handle);
- }
-
- bta_hd_cb.use_report_id = use_report_id;
- bta_hd_cb.sdp_handle = SDP_CreateRecord();
- HID_DevAddRecord(bta_hd_cb.sdp_handle, p_app_data->name,
- p_app_data->description, p_app_data->provider,
- p_app_data->subclass, p_app_data->d_len, p_app_data->d_data);
- bta_sys_add_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
-
- HID_DevSetIncomingQos(
- p_app_data->in_qos.service_type, p_app_data->in_qos.token_rate,
- p_app_data->in_qos.token_bucket_size, p_app_data->in_qos.peak_bandwidth,
- p_app_data->in_qos.access_latency, p_app_data->in_qos.delay_variation);
-
- HID_DevSetOutgoingQos(
- p_app_data->out_qos.service_type, p_app_data->out_qos.token_rate,
- p_app_data->out_qos.token_bucket_size, p_app_data->out_qos.peak_bandwidth,
- p_app_data->out_qos.access_latency, p_app_data->out_qos.delay_variation);
-
- // application is registered so we can accept incoming connections
- HID_DevSetIncomingPolicy(TRUE);
-
- if (HID_DevGetDevice(&ret.reg_status.bda) == HID_SUCCESS) {
- ret.reg_status.in_use = TRUE;
- }
-
- (*bta_hd_cb.p_cback)(BTA_HD_REGISTER_APP_EVT, &ret);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_unregister_act
- *
- * Description Unregisters SDP record
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hd_unregister_act() {
- tBTA_HD_STATUS status = BTA_HD_OK;
-
- APPL_TRACE_API("%s", __func__);
-
- // application is no longer registered so we do not want incoming connections
- HID_DevSetIncomingPolicy(FALSE);
-
- if (bta_hd_cb.sdp_handle != 0) {
- SDP_DeleteRecord(bta_hd_cb.sdp_handle);
- }
-
- bta_hd_cb.sdp_handle = 0;
- bta_sys_remove_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
-
- tBTA_HD bta_hd;
- bta_hd.status = status;
- (*bta_hd_cb.p_cback)(BTA_HD_UNREGISTER_APP_EVT, &bta_hd);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_unregister2_act
- *
- * Description
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hd_unregister2_act(tBTA_HD_DATA* p_data) {
- APPL_TRACE_API("%s", __func__);
-
- // close first
- bta_hd_close_act(p_data);
-
- // then unregister
- bta_hd_unregister_act();
-
- if (bta_hd_cb.disable_w4_close) {
- bta_hd_api_disable();
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_connect_act
- *
- * Description Connect to device (must be virtually plugged)
- *
- * Returns void
- *
- ******************************************************************************/
-extern void bta_hd_connect_act(tBTA_HD_DATA* p_data) {
- tHID_STATUS ret;
- tBTA_HD_DEVICE_CTRL* p_ctrl = (tBTA_HD_DEVICE_CTRL*)p_data;
- tBTA_HD cback_data;
-
- APPL_TRACE_API("%s", __func__);
-
- ret = HID_DevPlugDevice(p_ctrl->addr);
- if (ret != HID_SUCCESS) {
- APPL_TRACE_WARNING("%s: HID_DevPlugDevice returned %d", __func__, ret);
- return;
- }
-
- ret = HID_DevConnect();
- if (ret != HID_SUCCESS) {
- APPL_TRACE_WARNING("%s: HID_DevConnect returned %d", __func__, ret);
- return;
- }
-
- cback_data.conn.bda = p_ctrl->addr;
- cback_data.conn.status = BTHD_CONN_STATE_CONNECTING;
-
- bta_hd_cb.p_cback(BTA_HD_CONN_STATE_EVT, &cback_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_disconnect_act
- *
- * Description Disconnect from device
- *
- * Returns void
- *
- ******************************************************************************/
-extern void bta_hd_disconnect_act() {
- tHID_STATUS ret;
- tBTA_HD cback_data;
-
- APPL_TRACE_API("%s", __func__);
-
- ret = HID_DevDisconnect();
-
- if (ret != HID_SUCCESS) {
- APPL_TRACE_WARNING("%s: HID_DevDisconnect returned %d", __func__, ret);
- return;
- }
-
- if (HID_DevGetDevice(&cback_data.conn.bda) == HID_SUCCESS) {
- cback_data.conn.status = BTHD_CONN_STATE_DISCONNECTING;
- bta_hd_cb.p_cback(BTA_HD_CONN_STATE_EVT, &cback_data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_add_device_act
- *
- * Description
- *
- * Returns void
- *
- ******************************************************************************/
-extern void bta_hd_add_device_act(tBTA_HD_DATA* p_data) {
- tBTA_HD_DEVICE_CTRL* p_ctrl = (tBTA_HD_DEVICE_CTRL*)p_data;
-
- APPL_TRACE_API("%s", __func__);
-
- HID_DevPlugDevice(p_ctrl->addr);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_remove_device_act
- *
- * Description
- *
- * Returns void
- *
- ******************************************************************************/
-extern void bta_hd_remove_device_act(tBTA_HD_DATA* p_data) {
- tBTA_HD_DEVICE_CTRL* p_ctrl = (tBTA_HD_DEVICE_CTRL*)p_data;
-
- APPL_TRACE_API("%s", __func__);
-
- HID_DevUnplugDevice(p_ctrl->addr);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_send_report_act
- *
- * Description Sends report
- *
- * Returns void
- *
- ******************************************************************************/
-extern void bta_hd_send_report_act(tBTA_HD_DATA* p_data) {
- tBTA_HD_SEND_REPORT* p_report = (tBTA_HD_SEND_REPORT*)p_data;
- uint8_t channel;
- uint8_t report_id;
-
- APPL_TRACE_VERBOSE("%s", __func__);
-
- channel = p_report->use_intr ? HID_CHANNEL_INTR : HID_CHANNEL_CTRL;
- report_id =
- (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) ? p_report->id : 0x00;
-
- HID_DevSendReport(channel, p_report->type, report_id, p_report->len,
- p_report->data);
-
- /* trigger PM */
- bta_sys_busy(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
- bta_sys_idle(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_report_error_act
- *
- * Description
- *
- * Returns void
- *
- ******************************************************************************/
-extern void bta_hd_report_error_act(tBTA_HD_DATA* p_data) {
- tBTA_HD_REPORT_ERR* p_report = (tBTA_HD_REPORT_ERR*)p_data;
- tHID_STATUS ret;
-
- APPL_TRACE_API("%s: error = %d", __func__, p_report->error);
-
- ret = HID_DevReportError(p_report->error);
-
- if (ret != HID_SUCCESS) {
- APPL_TRACE_WARNING("%s: HID_DevReportError returned %d", __func__, ret);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_vc_unplug_act
- *
- * Description Sends Virtual Cable Unplug
- *
- * Returns void
- *
- ******************************************************************************/
-extern void bta_hd_vc_unplug_act() {
- tHID_STATUS ret;
-
- APPL_TRACE_API("%s", __func__);
-
- bta_hd_cb.vc_unplug = TRUE;
-
- ret = HID_DevVirtualCableUnplug();
-
- if (ret != HID_SUCCESS) {
- APPL_TRACE_WARNING("%s: HID_DevVirtualCableUnplug returned %d", __func__,
- ret);
- }
-
- /* trigger PM */
- bta_sys_busy(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
- bta_sys_idle(BTA_ID_HD, 1, bta_hd_cb.bd_addr);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_open_act
- *
- * Description
- *
- * Returns void
- *
- ******************************************************************************/
-extern void bta_hd_open_act(tBTA_HD_DATA* p_data) {
- tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
- tBTA_HD cback_data;
-
- APPL_TRACE_API("%s", __func__);
-
- HID_DevPlugDevice(p_cback->addr);
- bta_sys_conn_open(BTA_ID_HD, 1, p_cback->addr);
-
- cback_data.conn.bda = p_cback->addr;
- bta_hd_cb.bd_addr = p_cback->addr;
-
- bta_hd_cb.p_cback(BTA_HD_OPEN_EVT, &cback_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_close_act
- *
- * Description
- *
- * Returns void
- *
- ******************************************************************************/
-extern void bta_hd_close_act(tBTA_HD_DATA* p_data) {
- tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
- tBTA_HD cback_data;
- tBTA_HD_EVT cback_event = BTA_HD_CLOSE_EVT;
-
- APPL_TRACE_API("%s", __func__);
-
- bta_sys_conn_close(BTA_ID_HD, 1, p_cback->addr);
-
- if (bta_hd_cb.vc_unplug) {
- bta_hd_cb.vc_unplug = FALSE;
- HID_DevUnplugDevice(p_cback->addr);
- cback_event = BTA_HD_VC_UNPLUG_EVT;
- }
-
- cback_data.conn.bda = p_cback->addr;
- bta_hd_cb.bd_addr = RawAddress::kEmpty;
-
- bta_hd_cb.p_cback(cback_event, &cback_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_intr_data_act
- *
- * Description Handles incoming DATA request on intr
- *
- * Returns void
- *
- ******************************************************************************/
-extern void bta_hd_intr_data_act(tBTA_HD_DATA* p_data) {
- tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
- BT_HDR* p_msg = p_cback->p_data;
- uint16_t len = p_msg->len;
- uint8_t* p_buf = (uint8_t*)(p_msg + 1) + p_msg->offset;
- tBTA_HD_INTR_DATA ret;
-
- APPL_TRACE_API("%s", __func__);
-
- if (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) {
- if (len < 1) {
- android_errorWriteLog(0x534e4554, "109757986");
- return;
- }
- ret.report_id = *p_buf;
-
- len--;
- p_buf++;
- } else {
- ret.report_id = 0;
- }
-
- ret.len = len;
- ret.p_data = p_buf;
-
- tBTA_HD bta_hd;
- bta_hd.intr_data = ret;
- (*bta_hd_cb.p_cback)(BTA_HD_INTR_DATA_EVT, &bta_hd);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_get_report_act
- *
- * Description Handles incoming GET_REPORT request
- *
- * Returns void
- *
- ******************************************************************************/
-extern void bta_hd_get_report_act(tBTA_HD_DATA* p_data) {
- tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
- bool rep_size_follows = p_cback->data;
- BT_HDR* p_msg = p_cback->p_data;
- uint8_t* p_buf = (uint8_t*)(p_msg + 1) + p_msg->offset;
- tBTA_HD_GET_REPORT ret = {0, 0, 0};
-
- APPL_TRACE_API("%s", __func__);
-
- uint16_t remaining_len = p_msg->len;
- if (remaining_len < 1) {
- android_errorWriteLog(0x534e4554, "109757168");
- return;
- }
-
- ret.report_type = *p_buf & HID_PAR_REP_TYPE_MASK;
- p_buf++;
- remaining_len--;
-
- if (bta_hd_cb.use_report_id) {
- if (remaining_len < 1) {
- android_errorWriteLog(0x534e4554, "109757168");
- return;
- }
- ret.report_id = *p_buf;
- p_buf++;
- remaining_len--;
- }
-
- if (rep_size_follows) {
- if (remaining_len < 2) {
- android_errorWriteLog(0x534e4554, "109757168");
- return;
- }
- ret.buffer_size = *p_buf | (*(p_buf + 1) << 8);
- }
-
- tBTA_HD bta_hd;
- bta_hd.get_report = ret;
- (*bta_hd_cb.p_cback)(BTA_HD_GET_REPORT_EVT, &bta_hd);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_set_report_act
- *
- * Description Handles incoming SET_REPORT request
- *
- * Returns void
- *
- ******************************************************************************/
-extern void bta_hd_set_report_act(tBTA_HD_DATA* p_data) {
- tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
- BT_HDR* p_msg = p_cback->p_data;
- uint16_t len = p_msg->len;
- uint8_t* p_buf = (uint8_t*)(p_msg + 1) + p_msg->offset;
- tBTA_HD_SET_REPORT ret = {0, 0, 0, NULL};
-
- APPL_TRACE_API("%s", __func__);
-
- if (len < 1) {
- android_errorWriteLog(0x534e4554, "110846194");
- return;
- }
- ret.report_type = *p_buf & HID_PAR_REP_TYPE_MASK;
- p_buf++;
- len--;
-
- if (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) {
- if (len < 1) {
- android_errorWriteLog(0x534e4554, "109757435");
- return;
- }
- ret.report_id = *p_buf;
-
- len--;
- p_buf++;
- } else {
- ret.report_id = 0;
- }
-
- ret.len = len;
- ret.p_data = p_buf;
-
- tBTA_HD bta_hd;
- bta_hd.set_report = ret;
- (*bta_hd_cb.p_cback)(BTA_HD_SET_REPORT_EVT, &bta_hd);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_set_protocol_act
- *
- * Description
- *
- * Returns void
- *
- ******************************************************************************/
-extern void bta_hd_set_protocol_act(tBTA_HD_DATA* p_data) {
- tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
- tBTA_HD cback_data;
-
- APPL_TRACE_API("%s", __func__);
-
- bta_hd_cb.boot_mode = (p_cback->data == HID_PAR_PROTOCOL_BOOT_MODE);
- cback_data.set_protocol = p_cback->data;
-
- (*bta_hd_cb.p_cback)(BTA_HD_SET_PROTOCOL_EVT, &cback_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_vc_unplug_done_act
- *
- * Description
- *
- * Returns void
- *
- ******************************************************************************/
-extern void bta_hd_vc_unplug_done_act(tBTA_HD_DATA* p_data) {
- tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
- tBTA_HD cback_data;
-
- APPL_TRACE_API("%s", __func__);
-
- bta_sys_conn_close(BTA_ID_HD, 1, p_cback->addr);
-
- HID_DevUnplugDevice(p_cback->addr);
-
- cback_data.conn.bda = p_cback->addr;
- bta_hd_cb.bd_addr = p_cback->addr;
-
- (*bta_hd_cb.p_cback)(BTA_HD_VC_UNPLUG_EVT, &cback_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_suspend_act
- *
- * Description
- *
- * Returns void
- *
- ******************************************************************************/
-extern void bta_hd_suspend_act(tBTA_HD_DATA* p_data) {
- tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
-
- APPL_TRACE_API("%s", __func__);
-
- bta_sys_idle(BTA_ID_HD, 1, p_cback->addr);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_exit_suspend_act
- *
- * Description
- *
- * Returns void
- *
- ******************************************************************************/
-extern void bta_hd_exit_suspend_act(tBTA_HD_DATA* p_data) {
- tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data;
-
- APPL_TRACE_API("%s", __func__);
-
- bta_sys_busy(BTA_ID_HD, 1, p_cback->addr);
- bta_sys_idle(BTA_ID_HD, 1, p_cback->addr);
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_cback
- *
- * Description BTA HD callback function
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_hd_cback(const RawAddress& bd_addr, uint8_t event,
- uint32_t data, BT_HDR* pdata) {
- tBTA_HD_CBACK_DATA* p_buf = NULL;
- uint16_t sm_event = BTA_HD_INVALID_EVT;
-
- APPL_TRACE_API("%s: event=%d", __func__, event);
-
- switch (event) {
- case HID_DHOST_EVT_OPEN:
- sm_event = BTA_HD_INT_OPEN_EVT;
- break;
-
- case HID_DHOST_EVT_CLOSE:
- sm_event = BTA_HD_INT_CLOSE_EVT;
- break;
-
- case HID_DHOST_EVT_GET_REPORT:
- sm_event = BTA_HD_INT_GET_REPORT_EVT;
- break;
-
- case HID_DHOST_EVT_SET_REPORT:
- sm_event = BTA_HD_INT_SET_REPORT_EVT;
- break;
-
- case HID_DHOST_EVT_SET_PROTOCOL:
- sm_event = BTA_HD_INT_SET_PROTOCOL_EVT;
- break;
-
- case HID_DHOST_EVT_INTR_DATA:
- sm_event = BTA_HD_INT_INTR_DATA_EVT;
- break;
-
- case HID_DHOST_EVT_VC_UNPLUG:
- sm_event = BTA_HD_INT_VC_UNPLUG_EVT;
- break;
-
- case HID_DHOST_EVT_SUSPEND:
- sm_event = BTA_HD_INT_SUSPEND_EVT;
- break;
-
- case HID_DHOST_EVT_EXIT_SUSPEND:
- sm_event = BTA_HD_INT_EXIT_SUSPEND_EVT;
- break;
- }
-
- if (sm_event != BTA_HD_INVALID_EVT &&
- (p_buf = (tBTA_HD_CBACK_DATA*)osi_malloc(sizeof(tBTA_HD_CBACK_DATA) +
- sizeof(BT_HDR))) != NULL) {
- p_buf->hdr.event = sm_event;
- p_buf->addr = bd_addr;
- p_buf->data = data;
- p_buf->p_data = pdata;
-
- bta_sys_sendmsg(p_buf);
- }
-}
-
-#endif /* BTA_HD_INCLUDED */
diff --git a/bta/hd/bta_hd_api.cc b/bta/hd/bta_hd_api.cc
deleted file mode 100644
index 0259a22..0000000
--- a/bta/hd/bta_hd_api.cc
+++ /dev/null
@@ -1,312 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2016 The Android Open Source Project
- * Copyright 2005-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains the HID DEVICE API in the subsystem of BTA.
- *
- ******************************************************************************/
-
-#define LOG_TAG "bluetooth"
-
-// BTA_HD_INCLUDED
-#include "bt_target.h" // Must be first to define build configuration
-#if defined(BTA_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE)
-
-#include "bta/hd/bta_hd_int.h"
-#include "osi/include/allocator.h"
-#include "osi/include/compat.h"
-#include "osi/include/log.h"
-#include "stack/include/bt_hdr.h"
-#include "types/raw_address.h"
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-
-static const tBTA_SYS_REG bta_hd_reg = {bta_hd_hdl_event, BTA_HdDisable};
-
-/*******************************************************************************
- *
- * Function BTA_HdEnable
- *
- * Description Enables HID device
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_HdEnable(tBTA_HD_CBACK* p_cback) {
- APPL_TRACE_API("%s", __func__);
-
- bta_sys_register(BTA_ID_HD, &bta_hd_reg);
-
- tBTA_HD_API_ENABLE* p_buf =
- (tBTA_HD_API_ENABLE*)osi_malloc((uint16_t)sizeof(tBTA_HD_API_ENABLE));
-
- memset(p_buf, 0, sizeof(tBTA_HD_API_ENABLE));
-
- p_buf->hdr.event = BTA_HD_API_ENABLE_EVT;
- p_buf->p_cback = p_cback;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_HdDisable
- *
- * Description Disables HID device.
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_HdDisable(void) {
- APPL_TRACE_API("%s", __func__);
-
- bta_sys_deregister(BTA_ID_HD);
-
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
- p_buf->event = BTA_HD_API_DISABLE_EVT;
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_HdRegisterApp
- *
- * Description This function is called when application should be
-*registered
- *
- * Returns void
- *
- ******************************************************************************/
-extern void BTA_HdRegisterApp(tBTA_HD_APP_INFO* p_app_info,
- tBTA_HD_QOS_INFO* p_in_qos,
- tBTA_HD_QOS_INFO* p_out_qos) {
- APPL_TRACE_API("%s", __func__);
-
- tBTA_HD_REGISTER_APP* p_buf =
- (tBTA_HD_REGISTER_APP*)osi_malloc(sizeof(tBTA_HD_REGISTER_APP));
- p_buf->hdr.event = BTA_HD_API_REGISTER_APP_EVT;
-
- if (p_app_info->p_name) {
- strlcpy(p_buf->name, p_app_info->p_name, BTA_HD_APP_NAME_LEN);
- } else {
- p_buf->name[0] = '\0';
- }
-
- if (p_app_info->p_description) {
- strlcpy(p_buf->description, p_app_info->p_description,
- BTA_HD_APP_DESCRIPTION_LEN);
- } else {
- p_buf->description[0] = '\0';
- }
-
- if (p_app_info->p_provider) {
- strlcpy(p_buf->provider, p_app_info->p_provider, BTA_HD_APP_PROVIDER_LEN);
- } else {
- p_buf->provider[0] = '\0';
- }
-
- p_buf->subclass = p_app_info->subclass;
-
- if (p_app_info->descriptor.dl_len > BTA_HD_APP_DESCRIPTOR_LEN) {
- p_app_info->descriptor.dl_len = BTA_HD_APP_DESCRIPTOR_LEN;
- android_errorWriteLog(0x534e4554, "113111784");
- }
- p_buf->d_len = p_app_info->descriptor.dl_len;
- memcpy(p_buf->d_data, p_app_info->descriptor.dsc_list,
- p_app_info->descriptor.dl_len);
-
- // copy qos data as-is
- memcpy(&p_buf->in_qos, p_in_qos, sizeof(tBTA_HD_QOS_INFO));
- memcpy(&p_buf->out_qos, p_out_qos, sizeof(tBTA_HD_QOS_INFO));
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_HdUnregisterApp
- *
- * Description This function is called when application should be
-*unregistered
- *
- * Returns void
- *
- ******************************************************************************/
-extern void BTA_HdUnregisterApp(void) {
- APPL_TRACE_API("%s", __func__);
-
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
- p_buf->event = BTA_HD_API_UNREGISTER_APP_EVT;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_HdSendReport
- *
- * Description This function is called when report is to be sent
- *
- * Returns void
- *
- ******************************************************************************/
-extern void BTA_HdSendReport(tBTA_HD_REPORT* p_report) {
- APPL_TRACE_VERBOSE("%s", __func__);
-
- if (p_report->len > BTA_HD_REPORT_LEN) {
- APPL_TRACE_WARNING(
- "%s, report len (%d) > MTU len (%d), can't send report."
- " Increase value of HID_DEV_MTU_SIZE to send larger reports",
- __func__, p_report->len, BTA_HD_REPORT_LEN);
- return;
- }
-
- tBTA_HD_SEND_REPORT* p_buf =
- (tBTA_HD_SEND_REPORT*)osi_malloc(sizeof(tBTA_HD_SEND_REPORT));
- p_buf->hdr.event = BTA_HD_API_SEND_REPORT_EVT;
-
- p_buf->use_intr = p_report->use_intr;
- p_buf->type = p_report->type;
- p_buf->id = p_report->id;
- p_buf->len = p_report->len;
- memcpy(p_buf->data, p_report->p_data, p_report->len);
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_HdVirtualCableUnplug
- *
- * Description This function is called when VCU shall be sent
- *
- * Returns void
- *
- ******************************************************************************/
-extern void BTA_HdVirtualCableUnplug(void) {
- APPL_TRACE_API("%s", __func__);
-
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
- p_buf->event = BTA_HD_API_VC_UNPLUG_EVT;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_HdConnect
- *
- * Description This function is called when connection to host shall be
-*made
- *
- * Returns void
- *
- ******************************************************************************/
-extern void BTA_HdConnect(const RawAddress& addr) {
- APPL_TRACE_API("%s", __func__);
-
- tBTA_HD_DEVICE_CTRL* p_buf =
- (tBTA_HD_DEVICE_CTRL*)osi_malloc(sizeof(tBTA_HD_DEVICE_CTRL));
- p_buf->hdr.event = BTA_HD_API_CONNECT_EVT;
-
- p_buf->addr = addr;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_HdDisconnect
- *
- * Description This function is called when host shall be disconnected
- *
- * Returns void
- *
- ******************************************************************************/
-extern void BTA_HdDisconnect(void) {
- APPL_TRACE_API("%s", __func__);
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
- p_buf->event = BTA_HD_API_DISCONNECT_EVT;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_HdAddDevice
- *
- * Description This function is called when a device is virtually cabled
- *
- * Returns void
- *
- ******************************************************************************/
-extern void BTA_HdAddDevice(const RawAddress& addr) {
- APPL_TRACE_API("%s", __func__);
- tBTA_HD_DEVICE_CTRL* p_buf =
- (tBTA_HD_DEVICE_CTRL*)osi_malloc(sizeof(tBTA_HD_DEVICE_CTRL));
- p_buf->hdr.event = BTA_HD_API_ADD_DEVICE_EVT;
-
- p_buf->addr = addr;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_HdRemoveDevice
- *
- * Description This function is called when a device is virtually uncabled
- *
- * Returns void
- *
- ******************************************************************************/
-extern void BTA_HdRemoveDevice(const RawAddress& addr) {
- APPL_TRACE_API("%s", __func__);
- tBTA_HD_DEVICE_CTRL* p_buf =
- (tBTA_HD_DEVICE_CTRL*)osi_malloc(sizeof(tBTA_HD_DEVICE_CTRL));
- p_buf->hdr.event = BTA_HD_API_REMOVE_DEVICE_EVT;
-
- p_buf->addr = addr;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_HdReportError
- *
- * Description This function is called when reporting error for set report
- *
- * Returns void
- *
- ******************************************************************************/
-extern void BTA_HdReportError(uint8_t error) {
- APPL_TRACE_API("%s", __func__);
- tBTA_HD_REPORT_ERR* p_buf =
- (tBTA_HD_REPORT_ERR*)osi_malloc(sizeof(tBTA_HD_REPORT_ERR));
- p_buf->hdr.event = BTA_HD_API_REPORT_ERROR_EVT;
- p_buf->error = error;
-
- bta_sys_sendmsg(p_buf);
-}
-
-#endif /* BTA_HD_INCLUDED */
diff --git a/bta/hd/bta_hd_int.h b/bta/hd/bta_hd_int.h
deleted file mode 100644
index 638ceac..0000000
--- a/bta/hd/bta_hd_int.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2016 The Android Open Source Project
- * Copyright 2005-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains BTA HID Device internal definitions
- *
- ******************************************************************************/
-
-#ifndef BTA_HD_INT_H
-#define BTA_HD_INT_H
-
-#include <cstdint>
-
-#include "bta/include/bta_hd_api.h"
-#include "bta/sys/bta_sys.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/bt_types.h"
-#include "stack/include/hiddefs.h"
-#include "types/raw_address.h"
-
-enum {
- BTA_HD_API_REGISTER_APP_EVT = BTA_SYS_EVT_START(BTA_ID_HD),
- BTA_HD_API_UNREGISTER_APP_EVT,
- BTA_HD_API_CONNECT_EVT,
- BTA_HD_API_DISCONNECT_EVT,
- BTA_HD_API_ADD_DEVICE_EVT,
- BTA_HD_API_REMOVE_DEVICE_EVT,
- BTA_HD_API_SEND_REPORT_EVT,
- BTA_HD_API_REPORT_ERROR_EVT,
- BTA_HD_API_VC_UNPLUG_EVT,
- BTA_HD_INT_OPEN_EVT,
- BTA_HD_INT_CLOSE_EVT,
- BTA_HD_INT_INTR_DATA_EVT,
- BTA_HD_INT_GET_REPORT_EVT,
- BTA_HD_INT_SET_REPORT_EVT,
- BTA_HD_INT_SET_PROTOCOL_EVT,
- BTA_HD_INT_VC_UNPLUG_EVT,
- BTA_HD_INT_SUSPEND_EVT,
- BTA_HD_INT_EXIT_SUSPEND_EVT,
-
- /* handled outside state machine */
- BTA_HD_API_ENABLE_EVT,
- BTA_HD_API_DISABLE_EVT
-};
-typedef uint16_t tBTA_HD_INT_EVT;
-
-#define BTA_HD_INVALID_EVT (BTA_HD_API_DISABLE_EVT + 1)
-
-typedef struct {
- BT_HDR_RIGID hdr;
- tBTA_HD_CBACK* p_cback;
-} tBTA_HD_API_ENABLE;
-
-#define BTA_HD_APP_NAME_LEN 50
-#define BTA_HD_APP_DESCRIPTION_LEN 50
-#define BTA_HD_APP_PROVIDER_LEN 50
-#define BTA_HD_APP_DESCRIPTOR_LEN HIDD_APP_DESCRIPTOR_LEN
-
-#define BTA_HD_STATE_DISABLED 0x00
-#define BTA_HD_STATE_ENABLED 0x01
-#define BTA_HD_STATE_IDLE 0x02
-#define BTA_HD_STATE_CONNECTED 0x03
-#define BTA_HD_STATE_DISABLING 0x04
-#define BTA_HD_STATE_REMOVING 0x05
-
-typedef struct {
- BT_HDR_RIGID hdr;
- char name[BTA_HD_APP_NAME_LEN];
- char description[BTA_HD_APP_DESCRIPTION_LEN];
- char provider[BTA_HD_APP_PROVIDER_LEN];
- uint8_t subclass;
- uint16_t d_len;
- uint8_t d_data[BTA_HD_APP_DESCRIPTOR_LEN];
-
- tBTA_HD_QOS_INFO in_qos;
- tBTA_HD_QOS_INFO out_qos;
-} tBTA_HD_REGISTER_APP;
-
-#define BTA_HD_REPORT_LEN HID_DEV_MTU_SIZE
-
-typedef struct {
- BT_HDR_RIGID hdr;
- bool use_intr;
- uint8_t type;
- uint8_t id;
- uint16_t len;
- uint8_t data[BTA_HD_REPORT_LEN];
-} tBTA_HD_SEND_REPORT;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- RawAddress addr;
-} tBTA_HD_DEVICE_CTRL;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- uint8_t error;
-} tBTA_HD_REPORT_ERR;
-
-/* union of all event data types */
-typedef union {
- BT_HDR_RIGID hdr;
- tBTA_HD_API_ENABLE api_enable;
- tBTA_HD_REGISTER_APP register_app;
- tBTA_HD_SEND_REPORT send_report;
- tBTA_HD_DEVICE_CTRL device_ctrl;
- tBTA_HD_REPORT_ERR report_err;
-} tBTA_HD_DATA;
-
-typedef struct {
- BT_HDR_RIGID hdr;
- RawAddress addr;
- uint32_t data;
- BT_HDR* p_data;
-} tBTA_HD_CBACK_DATA;
-
-/******************************************************************************
- * Main Control Block
- ******************************************************************************/
-typedef struct {
- tBTA_HD_CBACK* p_cback;
- uint32_t sdp_handle;
- uint8_t trace_level;
- uint8_t state;
- RawAddress bd_addr;
- bool use_report_id;
- bool boot_mode;
- bool vc_unplug;
- bool disable_w4_close;
-} tBTA_HD_CB;
-
-extern tBTA_HD_CB bta_hd_cb;
-
-/*****************************************************************************
- * Function prototypes
- ****************************************************************************/
-extern bool bta_hd_hdl_event(BT_HDR_RIGID* p_msg);
-
-extern void bta_hd_api_enable(tBTA_HD_DATA* p_data);
-extern void bta_hd_api_disable(void);
-
-extern void bta_hd_register_act(tBTA_HD_DATA* p_data);
-extern void bta_hd_unregister_act();
-extern void bta_hd_unregister2_act(tBTA_HD_DATA* p_data);
-extern void bta_hd_connect_act(tBTA_HD_DATA* p_data);
-extern void bta_hd_disconnect_act();
-extern void bta_hd_add_device_act(tBTA_HD_DATA* p_data);
-extern void bta_hd_remove_device_act(tBTA_HD_DATA* p_data);
-extern void bta_hd_send_report_act(tBTA_HD_DATA* p_data);
-extern void bta_hd_report_error_act(tBTA_HD_DATA* p_data);
-extern void bta_hd_vc_unplug_act();
-
-extern void bta_hd_open_act(tBTA_HD_DATA* p_data);
-extern void bta_hd_close_act(tBTA_HD_DATA* p_data);
-extern void bta_hd_intr_data_act(tBTA_HD_DATA* p_data);
-extern void bta_hd_get_report_act(tBTA_HD_DATA* p_data);
-extern void bta_hd_set_report_act(tBTA_HD_DATA* p_data);
-extern void bta_hd_set_protocol_act(tBTA_HD_DATA* p_data);
-extern void bta_hd_vc_unplug_done_act(tBTA_HD_DATA* p_data);
-extern void bta_hd_suspend_act(tBTA_HD_DATA* p_data);
-extern void bta_hd_exit_suspend_act(tBTA_HD_DATA* p_data);
-
-#endif
diff --git a/bta/hd/bta_hd_main.cc b/bta/hd/bta_hd_main.cc
deleted file mode 100644
index 67ff3fc..0000000
--- a/bta/hd/bta_hd_main.cc
+++ /dev/null
@@ -1,208 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2016 The Android Open Source Project
- * Copyright 2005-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains the HID host main functions and state machine.
- *
- ******************************************************************************/
-
-#include <cstdint>
-
-// BTA_HD_INCLUDED
-#include "bt_target.h" // Must be first to define build configuration
-#if defined(BTA_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE)
-
-#include "bta/hd/bta_hd_int.h"
-#include "stack/include/bt_hdr.h"
-
-/*****************************************************************************
- * Constants and types
- ****************************************************************************/
-
-/* state machine states */
-enum {
- BTA_HD_INIT_ST,
- BTA_HD_IDLE_ST, /* not connected, waiting for connection */
- BTA_HD_CONN_ST, /* host connected */
- BTA_HD_TRANSIENT_TO_INIT_ST, /* transient state: going back from CONN to INIT
- */
-};
-typedef uint8_t tBTA_HD_STATE;
-
-/*****************************************************************************
- * Global data
- ****************************************************************************/
-tBTA_HD_CB bta_hd_cb;
-
-static tBTA_HD_STATE get_state() { return bta_hd_cb.state; }
-
-static void set_state(tBTA_HD_STATE state) { bta_hd_cb.state = state; }
-
-static void bta_hd_better_state_machine(uint16_t event, tBTA_HD_DATA* p_data) {
- switch (get_state()) {
- case BTA_HD_INIT_ST:
- switch (event) {
- case BTA_HD_API_REGISTER_APP_EVT:
- set_state(BTA_HD_IDLE_ST);
- bta_hd_register_act(p_data);
- break;
- case BTA_HD_API_ADD_DEVICE_EVT:
- bta_hd_add_device_act(p_data);
- break;
- case BTA_HD_API_REMOVE_DEVICE_EVT:
- bta_hd_remove_device_act(p_data);
- break;
- }
- break;
- case BTA_HD_IDLE_ST:
- switch (event) {
- case BTA_HD_API_UNREGISTER_APP_EVT:
- set_state(BTA_HD_INIT_ST);
- bta_hd_unregister_act();
- break;
- case BTA_HD_API_CONNECT_EVT:
- bta_hd_connect_act(p_data);
- break;
- case BTA_HD_API_DISCONNECT_EVT:
- bta_hd_disconnect_act();
- break;
- case BTA_HD_API_ADD_DEVICE_EVT:
- bta_hd_add_device_act(p_data);
- break;
- case BTA_HD_API_REMOVE_DEVICE_EVT:
- bta_hd_remove_device_act(p_data);
- break;
- case BTA_HD_API_SEND_REPORT_EVT:
- bta_hd_send_report_act(p_data);
- break;
- case BTA_HD_INT_OPEN_EVT:
- set_state(BTA_HD_CONN_ST);
- bta_hd_open_act(p_data);
- break;
- case BTA_HD_INT_CLOSE_EVT:
- bta_hd_close_act(p_data);
- break;
- }
- break;
- case BTA_HD_CONN_ST:
- switch (event) {
- case BTA_HD_API_UNREGISTER_APP_EVT:
- set_state(BTA_HD_TRANSIENT_TO_INIT_ST);
- bta_hd_disconnect_act();
- break;
- case BTA_HD_API_DISCONNECT_EVT:
- bta_hd_disconnect_act();
- break;
- case BTA_HD_API_ADD_DEVICE_EVT:
- bta_hd_add_device_act(p_data);
- break;
- case BTA_HD_API_REMOVE_DEVICE_EVT:
- bta_hd_remove_device_act(p_data);
- break;
- case BTA_HD_API_SEND_REPORT_EVT:
- bta_hd_send_report_act(p_data);
- break;
- case BTA_HD_API_REPORT_ERROR_EVT:
- bta_hd_report_error_act(p_data);
- break;
- case BTA_HD_API_VC_UNPLUG_EVT:
- bta_hd_vc_unplug_act();
- break;
- case BTA_HD_INT_CLOSE_EVT:
- set_state(BTA_HD_IDLE_ST);
- bta_hd_close_act(p_data);
- break;
- case BTA_HD_INT_INTR_DATA_EVT:
- bta_hd_intr_data_act(p_data);
- break;
- case BTA_HD_INT_GET_REPORT_EVT:
- bta_hd_get_report_act(p_data);
- break;
- case BTA_HD_INT_SET_REPORT_EVT:
- bta_hd_set_report_act(p_data);
- break;
- case BTA_HD_INT_SET_PROTOCOL_EVT:
- bta_hd_set_protocol_act(p_data);
- break;
- case BTA_HD_INT_VC_UNPLUG_EVT:
- set_state(BTA_HD_IDLE_ST);
- bta_hd_vc_unplug_done_act(p_data);
- break;
- case BTA_HD_INT_SUSPEND_EVT:
- bta_hd_suspend_act(p_data);
- break;
- case BTA_HD_INT_EXIT_SUSPEND_EVT:
- bta_hd_exit_suspend_act(p_data);
- break;
- }
- break;
- case BTA_HD_TRANSIENT_TO_INIT_ST:
- switch (event) {
- case BTA_HD_INT_CLOSE_EVT:
- set_state(BTA_HD_INIT_ST);
- bta_hd_unregister2_act(p_data);
- break;
- case BTA_HD_INT_VC_UNPLUG_EVT:
- set_state(BTA_HD_INIT_ST);
- bta_hd_unregister2_act(p_data);
- break;
- }
- break;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hd_hdl_event
- *
- * Description HID device main event handling function.
- *
- * Returns void
- *
- ******************************************************************************/
-bool bta_hd_hdl_event(BT_HDR_RIGID* p_msg) {
- APPL_TRACE_API("%s: p_msg->event=%d", __func__, p_msg->event);
-
- switch (p_msg->event) {
- case BTA_HD_API_ENABLE_EVT:
- bta_hd_api_enable((tBTA_HD_DATA*)p_msg);
- break;
-
- case BTA_HD_API_DISABLE_EVT:
- if (bta_hd_cb.state == BTA_HD_CONN_ST) {
- APPL_TRACE_WARNING("%s: host connected, disconnect before disabling",
- __func__);
-
- // unregister (and disconnect)
- bta_hd_cb.disable_w4_close = TRUE;
- bta_hd_better_state_machine(BTA_HD_API_UNREGISTER_APP_EVT,
- (tBTA_HD_DATA*)p_msg);
- } else {
- bta_hd_api_disable();
- }
- break;
-
- default:
- bta_hd_better_state_machine(p_msg->event, (tBTA_HD_DATA*)p_msg);
- }
- return (TRUE);
-}
-
-#endif /* BTA_HD_INCLUDED */
diff --git a/bta/hearing_aid/hearing_aid.cc b/bta/hearing_aid/hearing_aid.cc
deleted file mode 100644
index dfc0ac3..0000000
--- a/bta/hearing_aid/hearing_aid.cc
+++ /dev/null
@@ -1,1819 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2018 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 "bta_hearing_aid_api.h"
-
-#define LOG_TAG "bluetooth"
-
-#include <base/bind.h>
-#include <base/callback.h>
-#include <base/logging.h>
-#include <base/strings/string_number_conversions.h> // HexEncode
-
-#include <cstdint>
-#include <vector>
-
-#include "bta/include/bta_gatt_api.h"
-#include "bta/include/bta_gatt_queue.h"
-#include "bta/include/bta_hearing_aid_api.h"
-#include "device/include/controller.h"
-#include "embdrv/g722/g722_enc_dec.h"
-#include "osi/include/compat.h"
-#include "osi/include/log.h"
-#include "osi/include/properties.h"
-#include "stack/btm/btm_sec.h"
-#include "stack/include/acl_api.h" // BTM_ReadRSSI
-#include "stack/include/acl_api_types.h" // tBTM_RSSI_RESULT
-#include "stack/include/bt_hdr.h"
-#include "stack/include/bt_octets.h"
-#include "stack/include/gap_api.h"
-#include "stack/include/l2c_api.h" // L2CAP_MIN_OFFSET
-#include "types/bluetooth/uuid.h"
-#include "types/bt_transport.h"
-#include "types/raw_address.h"
-
-using base::Closure;
-using bluetooth::Uuid;
-using bluetooth::hearing_aid::ConnectionState;
-
-// The MIN_CE_LEN parameter for Connection Parameters based on the current
-// Connection Interval
-constexpr uint16_t MIN_CE_LEN_10MS_CI = 0x0006;
-constexpr uint16_t MIN_CE_LEN_20MS_CI = 0x000C;
-constexpr uint16_t CONNECTION_INTERVAL_10MS_PARAM = 0x0008;
-constexpr uint16_t CONNECTION_INTERVAL_20MS_PARAM = 0x0010;
-
-void btif_storage_add_hearing_aid(const HearingDevice& dev_info);
-bool btif_storage_get_hearing_aid_prop(
- const RawAddress& address, uint8_t* capabilities, uint64_t* hi_sync_id,
- uint16_t* render_delay, uint16_t* preparation_delay, uint16_t* codecs);
-
-constexpr uint8_t CODEC_G722_16KHZ = 0x01;
-constexpr uint8_t CODEC_G722_24KHZ = 0x02;
-
-// audio control point opcodes
-constexpr uint8_t CONTROL_POINT_OP_START = 0x01;
-constexpr uint8_t CONTROL_POINT_OP_STOP = 0x02;
-constexpr uint8_t CONTROL_POINT_OP_STATE_CHANGE = 0x03;
-
-constexpr uint8_t STATE_CHANGE_OTHER_SIDE_DISCONNECTED = 0x00;
-constexpr uint8_t STATE_CHANGE_OTHER_SIDE_CONNECTED = 0x01;
-constexpr uint8_t STATE_CHANGE_CONN_UPDATE = 0x02;
-
-// used to mark current_volume as not yet known, or possibly old
-constexpr int8_t VOLUME_UNKNOWN = 127;
-constexpr int8_t VOLUME_MIN = -127;
-
-// audio type
-constexpr uint8_t AUDIOTYPE_UNKNOWN = 0x00;
-
-// Status of the other side Hearing Aids device
-constexpr uint8_t OTHER_SIDE_NOT_STREAMING = 0x00;
-constexpr uint8_t OTHER_SIDE_IS_STREAMING = 0x01;
-
-// This ADD_RENDER_DELAY_INTERVALS is the number of connection intervals when
-// the audio data packet is send by Audio Engine to when the Hearing Aids device
-// received it from the air. We assumed that there is 2 data buffer queued from
-// audio subsystem to bluetooth chip. Then the estimated OTA delay is two
-// connnection intervals.
-constexpr uint16_t ADD_RENDER_DELAY_INTERVALS = 4;
-
-namespace {
-
-// clang-format off
-Uuid HEARING_AID_UUID = Uuid::FromString("FDF0");
-Uuid READ_ONLY_PROPERTIES_UUID = Uuid::FromString("6333651e-c481-4a3e-9169-7c902aad37bb");
-Uuid AUDIO_CONTROL_POINT_UUID = Uuid::FromString("f0d4de7e-4a88-476c-9d9f-1937b0996cc0");
-Uuid AUDIO_STATUS_UUID = Uuid::FromString("38663f1a-e711-4cac-b641-326b56404837");
-Uuid VOLUME_UUID = Uuid::FromString("00e4ca9e-ab14-41e4-8823-f9e70c7e91df");
-Uuid LE_PSM_UUID = Uuid::FromString("2d410339-82b6-42aa-b34e-e2e01df8cc1a");
-// clang-format on
-
-void hearingaid_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data);
-void encryption_callback(const RawAddress*, tBT_TRANSPORT, void*, tBTM_STATUS);
-void read_rssi_cb(void* p_void);
-
-inline BT_HDR* malloc_l2cap_buf(uint16_t len) {
- BT_HDR* msg = (BT_HDR*)osi_malloc(BT_HDR_SIZE + L2CAP_MIN_OFFSET +
- len /* LE-only, no need for FCS here */);
- msg->offset = L2CAP_MIN_OFFSET;
- msg->len = len;
- return msg;
-}
-
-inline uint8_t* get_l2cap_sdu_start_ptr(BT_HDR* msg) {
- return (uint8_t*)(msg) + BT_HDR_SIZE + L2CAP_MIN_OFFSET;
-}
-
-class HearingAidImpl;
-HearingAidImpl* instance;
-HearingAidAudioReceiver* audioReceiver;
-
-class HearingDevices {
- public:
- void Add(HearingDevice device) {
- if (FindByAddress(device.address) != nullptr) return;
-
- devices.push_back(device);
- }
-
- void Remove(const RawAddress& address) {
- for (auto it = devices.begin(); it != devices.end();) {
- if (it->address != address) {
- ++it;
- continue;
- }
-
- it = devices.erase(it);
- return;
- }
- }
-
- HearingDevice* FindByAddress(const RawAddress& address) {
- auto iter = std::find_if(devices.begin(), devices.end(),
- [&address](const HearingDevice& device) {
- return device.address == address;
- });
-
- return (iter == devices.end()) ? nullptr : &(*iter);
- }
-
- HearingDevice* FindByConnId(uint16_t conn_id) {
- auto iter = std::find_if(devices.begin(), devices.end(),
- [&conn_id](const HearingDevice& device) {
- return device.conn_id == conn_id;
- });
-
- return (iter == devices.end()) ? nullptr : &(*iter);
- }
-
- HearingDevice* FindByGapHandle(uint16_t gap_handle) {
- auto iter = std::find_if(devices.begin(), devices.end(),
- [&gap_handle](const HearingDevice& device) {
- return device.gap_handle == gap_handle;
- });
-
- return (iter == devices.end()) ? nullptr : &(*iter);
- }
-
- bool IsAnyConnectionUpdateStarted() {
- for (const auto& d : devices) {
- if (d.connection_update_status == STARTED) return true;
- }
-
- return false;
- }
-
- void StartRssiLog() {
- int read_rssi_start_interval_count = 0;
-
- for (auto& d : devices) {
- VLOG(1) << __func__ << ": device=" << d.address << ", read_rssi_count=" << d.read_rssi_count;
-
- // Reset the count
- if (d.read_rssi_count <= 0) {
- d.read_rssi_count = READ_RSSI_NUM_TRIES;
- d.num_intervals_since_last_rssi_read = read_rssi_start_interval_count;
-
- // Spaced apart the Read RSSI commands to the BT controller.
- read_rssi_start_interval_count += PERIOD_TO_READ_RSSI_IN_INTERVALS / 2;
- read_rssi_start_interval_count %= PERIOD_TO_READ_RSSI_IN_INTERVALS;
-
- std::deque<rssi_log>& rssi_logs = d.audio_stats.rssi_history;
- if (rssi_logs.size() >= MAX_RSSI_HISTORY) {
- rssi_logs.pop_front();
- }
- rssi_logs.emplace_back();
- }
- }
- }
-
- size_t size() { return (devices.size()); }
-
- std::vector<HearingDevice> devices;
-};
-
-static void write_rpt_ctl_cfg_cb(uint16_t conn_id, tGATT_STATUS status,
- uint16_t handle, uint16_t len,
- const uint8_t* value, void* data) {
- if (status != GATT_SUCCESS) {
- LOG(ERROR) << __func__ << ": handle=" << handle << ", conn_id=" << conn_id
- << ", status=" << loghex(static_cast<uint8_t>(status))
- << ", length=" << len;
- }
-}
-
-g722_encode_state_t* encoder_state_left = nullptr;
-g722_encode_state_t* encoder_state_right = nullptr;
-
-inline void encoder_state_init() {
- if (encoder_state_left != nullptr) {
- LOG(WARNING) << __func__ << ": encoder already initialized";
- return;
- }
- encoder_state_left = g722_encode_init(nullptr, 64000, G722_PACKED);
- encoder_state_right = g722_encode_init(nullptr, 64000, G722_PACKED);
-}
-
-inline void encoder_state_release() {
- if (encoder_state_left != nullptr) {
- g722_encode_release(encoder_state_left);
- encoder_state_left = nullptr;
- g722_encode_release(encoder_state_right);
- encoder_state_right = nullptr;
- }
-}
-
-class HearingAidImpl : public HearingAid {
- private:
- // Keep track of whether the Audio Service has resumed audio playback
- bool audio_running;
- // For Testing: overwrite the MIN_CE_LEN during connection parameter updates
- uint16_t overwrite_min_ce_len;
-
- public:
- ~HearingAidImpl() override = default;
-
- HearingAidImpl(bluetooth::hearing_aid::HearingAidCallbacks* callbacks,
- Closure initCb)
- : audio_running(false),
- overwrite_min_ce_len(0),
- gatt_if(0),
- seq_counter(0),
- current_volume(VOLUME_UNKNOWN),
- callbacks(callbacks),
- codec_in_use(0) {
- default_data_interval_ms = (uint16_t)osi_property_get_int32(
- "persist.bluetooth.hearingaid.interval", (int32_t)HA_INTERVAL_20_MS);
- if ((default_data_interval_ms != HA_INTERVAL_10_MS) &&
- (default_data_interval_ms != HA_INTERVAL_20_MS)) {
- LOG(ERROR) << __func__
- << ": invalid interval=" << default_data_interval_ms
- << "ms. Overwriting back to default";
- default_data_interval_ms = HA_INTERVAL_20_MS;
- }
- VLOG(2) << __func__
- << ", default_data_interval_ms=" << default_data_interval_ms;
-
- overwrite_min_ce_len = (uint16_t)osi_property_get_int32(
- "persist.bluetooth.hearingaidmincelen", 0);
- if (overwrite_min_ce_len) {
- LOG(INFO) << __func__
- << ": Overwrites MIN_CE_LEN=" << overwrite_min_ce_len;
- }
-
- BTA_GATTC_AppRegister(
- hearingaid_gattc_callback,
- base::Bind(
- [](Closure initCb, uint8_t client_id, uint8_t status) {
- if (status != GATT_SUCCESS) {
- LOG(ERROR) << "Can't start Hearing Aid profile - no gatt "
- "clients left!";
- return;
- }
- instance->gatt_if = client_id;
- initCb.Run();
- },
- initCb), false);
- }
-
- uint16_t UpdateBleConnParams(const RawAddress& address) {
- /* List of parameters that depends on the chosen Connection Interval */
- uint16_t min_ce_len;
- uint16_t connection_interval;
-
- switch (default_data_interval_ms) {
- case HA_INTERVAL_10_MS:
- min_ce_len = MIN_CE_LEN_10MS_CI;
- connection_interval = CONNECTION_INTERVAL_10MS_PARAM;
- break;
- case HA_INTERVAL_20_MS:
- min_ce_len = MIN_CE_LEN_20MS_CI;
- connection_interval = CONNECTION_INTERVAL_20MS_PARAM;
- break;
- default:
- LOG(ERROR) << __func__ << ":Error: invalid default_data_interval_ms="
- << default_data_interval_ms;
- min_ce_len = MIN_CE_LEN_10MS_CI;
- connection_interval = CONNECTION_INTERVAL_10MS_PARAM;
- }
-
- if (overwrite_min_ce_len != 0) {
- VLOG(2) << __func__ << ": min_ce_len=" << min_ce_len
- << " is overwritten to " << overwrite_min_ce_len;
- min_ce_len = overwrite_min_ce_len;
- }
-
- L2CA_UpdateBleConnParams(address, connection_interval, connection_interval,
- 0x000A, 0x0064 /*1s*/, min_ce_len, min_ce_len);
- return connection_interval;
- }
-
- void Connect(const RawAddress& address) override {
- DVLOG(2) << __func__ << " " << address;
- hearingDevices.Add(HearingDevice(address, true));
- BTA_GATTC_Open(gatt_if, address, true, false);
- }
-
- void AddToAcceptlist(const RawAddress& address) override {
- VLOG(2) << __func__ << " address: " << address;
- hearingDevices.Add(HearingDevice(address, true));
- BTA_GATTC_Open(gatt_if, address, false, false);
- }
-
- void AddFromStorage(const HearingDevice& dev_info, uint16_t is_acceptlisted) {
- DVLOG(2) << __func__ << " " << dev_info.address
- << ", hiSyncId=" << loghex(dev_info.hi_sync_id)
- << ", isAcceptlisted=" << is_acceptlisted;
- if (is_acceptlisted) {
- hearingDevices.Add(dev_info);
-
- // TODO: we should increase the scanning window for few seconds, to get
- // faster initial connection, same after hearing aid disconnects, i.e.
- // BTM_BleSetConnScanParams(2048, 1024);
-
- /* add device into BG connection to accept remote initiated connection */
- BTA_GATTC_Open(gatt_if, dev_info.address, false, false);
- }
-
- callbacks->OnDeviceAvailable(dev_info.capabilities, dev_info.hi_sync_id,
- dev_info.address);
- }
-
- int GetDeviceCount() { return (hearingDevices.size()); }
-
- void OnGattConnected(tGATT_STATUS status, uint16_t conn_id,
- tGATT_IF client_if, RawAddress address,
- tBT_TRANSPORT transport, uint16_t mtu) {
- VLOG(2) << __func__ << ": address=" << address << ", conn_id=" << conn_id;
-
- HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
- if (!hearingDevice) {
- /* When Hearing Aid is quickly disabled and enabled in settings, this case
- * might happen */
- LOG(WARNING) << "Closing connection to non hearing-aid device, address="
- << address;
- BTA_GATTC_Close(conn_id);
- return;
- }
-
- if (status != GATT_SUCCESS) {
- if (!hearingDevice->connecting_actively) {
- // acceptlist connection failed, that's ok.
- return;
- }
-
- LOG(INFO) << "Failed to connect to Hearing Aid device";
- hearingDevices.Remove(address);
- callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address);
- return;
- }
-
- hearingDevice->connecting_actively = false;
- hearingDevice->conn_id = conn_id;
-
- /* We must update connection parameters one at a time, otherwise anchor
- * point (start of connection event) for two devices can be too close to
- * each other. Here, by setting min_ce_len=max_ce_len=X, we force controller
- * to move anchor point of both connections away from each other, to make
- * sure we'll be able to fit all the data we want in one connection event.
- */
- bool any_update_pending = hearingDevices.IsAnyConnectionUpdateStarted();
- // mark the device as pending connection update. If we don't start the
- // update now, it'll be started once current device finishes.
- if (!any_update_pending) {
- hearingDevice->connection_update_status = STARTED;
- hearingDevice->requested_connection_interval =
- UpdateBleConnParams(address);
- } else {
- hearingDevice->connection_update_status = AWAITING;
- }
-
- if (controller_get_interface()->supports_ble_2m_phy()) {
- LOG(INFO) << address << " set preferred PHY to 2M";
- BTM_BleSetPhy(address, PHY_LE_2M, PHY_LE_2M, 0);
- }
-
- // Set data length
- // TODO(jpawlowski: for 16khz only 87 is required, optimize
- BTM_SetBleDataLength(address, 167);
-
- if (BTM_SecIsSecurityPending(address)) {
- /* if security collision happened, wait for encryption done
- * (BTA_GATTC_ENC_CMPL_CB_EVT) */
- return;
- }
-
- /* verify bond */
- if (BTM_IsEncrypted(address, BT_TRANSPORT_LE)) {
- /* if link has been encrypted */
- OnEncryptionComplete(address, true);
- return;
- }
-
- if (BTM_IsLinkKeyKnown(address, BT_TRANSPORT_LE)) {
- /* if bonded and link not encrypted */
- BTM_SetEncryption(address, BT_TRANSPORT_LE, encryption_callback, nullptr,
- BTM_BLE_SEC_ENCRYPT);
- return;
- }
-
- /* otherwise let it go through */
- OnEncryptionComplete(address, true);
- }
-
- void OnConnectionUpdateComplete(uint16_t conn_id, tBTA_GATTC* p_data) {
- HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
- if (!hearingDevice) {
- DVLOG(2) << "Skipping unknown device, conn_id=" << loghex(conn_id);
- return;
- }
-
- if (p_data) {
- if (p_data->conn_update.status == 0) {
- bool same_conn_interval =
- (hearingDevice->requested_connection_interval ==
- p_data->conn_update.interval);
-
- switch (hearingDevice->connection_update_status) {
- case COMPLETED:
- if (!same_conn_interval) {
- LOG(WARNING) << __func__
- << ": Unexpected change. Redo. connection interval="
- << p_data->conn_update.interval << ", expected="
- << hearingDevice->requested_connection_interval
- << ", conn_id=" << conn_id
- << ", connection_update_status="
- << hearingDevice->connection_update_status;
- // Redo this connection interval change.
- hearingDevice->connection_update_status = AWAITING;
- }
- break;
- case STARTED:
- if (same_conn_interval) {
- LOG(INFO) << __func__
- << ": Connection update completed. conn_id=" << conn_id
- << ", device=" << hearingDevice->address;
- hearingDevice->connection_update_status = COMPLETED;
- } else {
- LOG(WARNING) << __func__
- << ": Ignored. Different connection interval="
- << p_data->conn_update.interval << ", expected="
- << hearingDevice->requested_connection_interval
- << ", conn_id=" << conn_id
- << ", connection_update_status="
- << hearingDevice->connection_update_status;
- // Wait for the right Connection Update Completion.
- return;
- }
- break;
- case AWAITING:
- case NONE:
- break;
- }
-
- // Inform this side and other side device (if any) of Connection
- // Updates.
- std::vector<uint8_t> conn_update(
- {CONTROL_POINT_OP_STATE_CHANGE, STATE_CHANGE_CONN_UPDATE,
- (uint8_t)p_data->conn_update.interval});
- send_state_change_to_other_side(hearingDevice, conn_update);
- send_state_change(hearingDevice, conn_update);
- } else {
- LOG(INFO) << __func__ << ": error status="
- << loghex(static_cast<uint8_t>(p_data->conn_update.status))
- << ", conn_id=" << conn_id
- << ", device=" << hearingDevice->address
- << ", connection_update_status="
- << hearingDevice->connection_update_status;
-
- if (hearingDevice->connection_update_status == STARTED) {
- // Redo this connection interval change.
- LOG(ERROR) << __func__ << ": Redo Connection Interval change";
- hearingDevice->connection_update_status = AWAITING;
- }
- }
- } else {
- hearingDevice->connection_update_status = NONE;
- }
-
- for (auto& device : hearingDevices.devices) {
- if (device.conn_id && (device.connection_update_status == AWAITING)) {
- device.connection_update_status = STARTED;
- device.requested_connection_interval =
- UpdateBleConnParams(device.address);
- return;
- }
- }
- }
-
- // Completion Callback for the RSSI read operation.
- void OnReadRssiComplete(const RawAddress& address, int8_t rssi_value) {
- HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
- if (!hearingDevice) {
- LOG(INFO) << "Skipping unknown device" << address;
- return;
- }
-
- VLOG(1) << __func__ << ": device=" << address << ", rssi=" << (int)rssi_value;
-
- if (hearingDevice->read_rssi_count <= 0) {
- LOG(ERROR) << __func__ << ": device=" << address
- << ", invalid read_rssi_count=" << hearingDevice->read_rssi_count;
- return;
- }
-
- rssi_log& last_log_set = hearingDevice->audio_stats.rssi_history.back();
-
- if (hearingDevice->read_rssi_count == READ_RSSI_NUM_TRIES) {
- // Store the timestamp only for the first one after packet flush
- clock_gettime(CLOCK_REALTIME, &last_log_set.timestamp);
- LOG(INFO) << __func__ << ": store time. device=" << address << ", rssi=" << (int)rssi_value;
- }
-
- last_log_set.rssi.emplace_back(rssi_value);
- hearingDevice->read_rssi_count--;
- }
-
- void OnEncryptionComplete(const RawAddress& address, bool success) {
- HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
- if (!hearingDevice) {
- DVLOG(2) << "Skipping unknown device" << address;
- return;
- }
-
- if (!success) {
- LOG(ERROR) << "encryption failed";
- BTA_GATTC_Close(hearingDevice->conn_id);
- if (hearingDevice->first_connection) {
- callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address);
- }
- return;
- }
-
- DVLOG(2) << __func__ << " " << address;
-
- if (hearingDevice->audio_control_point_handle &&
- hearingDevice->audio_status_handle &&
- hearingDevice->audio_status_ccc_handle &&
- hearingDevice->volume_handle && hearingDevice->read_psm_handle) {
- // Use cached data, jump to read PSM
- ReadPSM(hearingDevice);
- } else {
- hearingDevice->first_connection = true;
- BTA_GATTC_ServiceSearchRequest(hearingDevice->conn_id, &HEARING_AID_UUID);
- }
- }
-
- void OnServiceChangeEvent(const RawAddress& address) {
- HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
- if (!hearingDevice) {
- VLOG(2) << "Skipping unknown device" << address;
- return;
- }
- LOG(INFO) << __func__ << ": address=" << address;
- hearingDevice->first_connection = true;
- hearingDevice->service_changed_rcvd = true;
- BtaGattQueue::Clean(hearingDevice->conn_id);
- if (hearingDevice->gap_handle) {
- GAP_ConnClose(hearingDevice->gap_handle);
- hearingDevice->gap_handle = 0;
- }
- }
-
- void OnServiceDiscDoneEvent(const RawAddress& address) {
- HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
- if (!hearingDevice) {
- VLOG(2) << "Skipping unknown device" << address;
- return;
- }
- if (hearingDevice->service_changed_rcvd) {
- BTA_GATTC_ServiceSearchRequest(hearingDevice->conn_id, &HEARING_AID_UUID);
- }
- }
-
- void OnServiceSearchComplete(uint16_t conn_id, tGATT_STATUS status) {
- HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
- if (!hearingDevice) {
- DVLOG(2) << "Skipping unknown device, conn_id=" << loghex(conn_id);
- return;
- }
-
- // Known device, nothing to do.
- if (!hearingDevice->first_connection) return;
-
- if (status != GATT_SUCCESS) {
- /* close connection and report service discovery complete with error */
- LOG(ERROR) << "Service discovery failed";
- if (hearingDevice->first_connection) {
- callbacks->OnConnectionState(ConnectionState::DISCONNECTED,
- hearingDevice->address);
- }
- return;
- }
-
- const std::list<gatt::Service>* services = BTA_GATTC_GetServices(conn_id);
-
- const gatt::Service* service = nullptr;
- for (const gatt::Service& tmp : *services) {
- if (tmp.uuid == Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER)) {
- LOG(INFO) << "Found UUID_SERVCLASS_GATT_SERVER, handle="
- << loghex(tmp.handle);
- const gatt::Service* service_changed_service = &tmp;
- find_server_changed_ccc_handle(conn_id, service_changed_service);
- } else if (tmp.uuid == HEARING_AID_UUID) {
- LOG(INFO) << "Found Hearing Aid service, handle=" << loghex(tmp.handle);
- service = &tmp;
- }
- }
-
- if (!service) {
- LOG(ERROR) << "No Hearing Aid service found";
- callbacks->OnConnectionState(ConnectionState::DISCONNECTED,
- hearingDevice->address);
- return;
- }
-
- for (const gatt::Characteristic& charac : service->characteristics) {
- if (charac.uuid == READ_ONLY_PROPERTIES_UUID) {
- if (!btif_storage_get_hearing_aid_prop(
- hearingDevice->address, &hearingDevice->capabilities,
- &hearingDevice->hi_sync_id, &hearingDevice->render_delay,
- &hearingDevice->preparation_delay, &hearingDevice->codecs)) {
- VLOG(2) << "Reading read only properties "
- << loghex(charac.value_handle);
- BtaGattQueue::ReadCharacteristic(
- conn_id, charac.value_handle,
- HearingAidImpl::OnReadOnlyPropertiesReadStatic, nullptr);
- }
- } else if (charac.uuid == AUDIO_CONTROL_POINT_UUID) {
- hearingDevice->audio_control_point_handle = charac.value_handle;
- // store audio control point!
- } else if (charac.uuid == AUDIO_STATUS_UUID) {
- hearingDevice->audio_status_handle = charac.value_handle;
-
- hearingDevice->audio_status_ccc_handle =
- find_ccc_handle(conn_id, charac.value_handle);
- if (!hearingDevice->audio_status_ccc_handle) {
- LOG(ERROR) << __func__ << ": cannot find Audio Status CCC descriptor";
- continue;
- }
-
- LOG(INFO) << __func__
- << ": audio_status_handle=" << loghex(charac.value_handle)
- << ", ccc=" << loghex(hearingDevice->audio_status_ccc_handle);
- } else if (charac.uuid == VOLUME_UUID) {
- hearingDevice->volume_handle = charac.value_handle;
- } else if (charac.uuid == LE_PSM_UUID) {
- hearingDevice->read_psm_handle = charac.value_handle;
- } else {
- LOG(WARNING) << "Unknown characteristic found:" << charac.uuid;
- }
- }
-
- if (hearingDevice->service_changed_rcvd) {
- hearingDevice->service_changed_rcvd = false;
- }
-
- ReadPSM(hearingDevice);
- }
-
- void ReadPSM(HearingDevice* hearingDevice) {
- if (hearingDevice->read_psm_handle) {
- LOG(INFO) << "Reading PSM " << loghex(hearingDevice->read_psm_handle)
- << ", device=" << hearingDevice->address;
- BtaGattQueue::ReadCharacteristic(
- hearingDevice->conn_id, hearingDevice->read_psm_handle,
- HearingAidImpl::OnPsmReadStatic, nullptr);
- }
- }
-
- void OnNotificationEvent(uint16_t conn_id, uint16_t handle, uint16_t len,
- uint8_t* value) {
- HearingDevice* device = hearingDevices.FindByConnId(conn_id);
- if (!device) {
- LOG(INFO) << __func__
- << ": Skipping unknown device, conn_id=" << loghex(conn_id);
- return;
- }
-
- if (device->audio_status_handle != handle) {
- LOG(INFO) << __func__ << ": Mismatched handle, "
- << loghex(device->audio_status_handle)
- << "!=" << loghex(handle);
- return;
- }
-
- if (len < 1) {
- LOG(ERROR) << __func__ << ": Data Length too small, len=" << len
- << ", expecting at least 1";
- return;
- }
-
- if (value[0] != 0) {
- LOG(INFO) << __func__
- << ": Invalid returned status. data=" << loghex(value[0]);
- return;
- }
-
- LOG(INFO) << __func__
- << ": audio status success notification. command_acked="
- << device->command_acked;
- device->command_acked = true;
- }
-
- void OnReadOnlyPropertiesRead(uint16_t conn_id, tGATT_STATUS status,
- uint16_t handle, uint16_t len, uint8_t* value,
- void* data) {
- HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
- if (!hearingDevice) {
- DVLOG(2) << __func__ << "unknown conn_id=" << loghex(conn_id);
- return;
- }
-
- VLOG(2) << __func__ << " " << base::HexEncode(value, len);
-
- uint8_t* p = value;
-
- uint8_t version;
- STREAM_TO_UINT8(version, p);
-
- if (version != 0x01) {
- LOG(WARNING) << "Unknown version: " << loghex(version);
- return;
- }
-
- // version 0x01 of read only properties:
- if (len < 17) {
- LOG(WARNING) << "Read only properties too short: " << loghex(len);
- return;
- }
- uint8_t capabilities;
- STREAM_TO_UINT8(capabilities, p);
- hearingDevice->capabilities = capabilities;
- bool side = capabilities & CAPABILITY_SIDE;
- bool standalone = capabilities & CAPABILITY_BINAURAL;
- VLOG(2) << __func__ << " capabilities: " << (side ? "right" : "left")
- << ", " << (standalone ? "binaural" : "monaural");
-
- if (capabilities & CAPABILITY_RESERVED) {
- LOG(WARNING) << __func__ << " reserved capabilities are set";
- }
-
- STREAM_TO_UINT64(hearingDevice->hi_sync_id, p);
- VLOG(2) << __func__ << " hiSyncId: " << loghex(hearingDevice->hi_sync_id);
- uint8_t feature_map;
- STREAM_TO_UINT8(feature_map, p);
-
- STREAM_TO_UINT16(hearingDevice->render_delay, p);
- VLOG(2) << __func__
- << " render delay: " << loghex(hearingDevice->render_delay);
-
- STREAM_TO_UINT16(hearingDevice->preparation_delay, p);
- VLOG(2) << __func__ << " preparation delay: "
- << loghex(hearingDevice->preparation_delay);
-
- uint16_t codecs;
- STREAM_TO_UINT16(codecs, p);
- hearingDevice->codecs = codecs;
- VLOG(2) << __func__ << " supported codecs: " << loghex(codecs);
- if (codecs & (1 << CODEC_G722_16KHZ)) VLOG(2) << "\tG722@16kHz";
- if (codecs & (1 << CODEC_G722_24KHZ)) VLOG(2) << "\tG722@24kHz";
-
- if (!(codecs & (1 << CODEC_G722_16KHZ))) {
- LOG(WARNING) << __func__ << " Mandatory codec, G722@16kHz not supported";
- }
- }
-
- uint16_t CalcCompressedAudioPacketSize(uint16_t codec_type,
- int connection_interval) {
- int sample_rate;
-
- const int sample_bit_rate = 16; /* 16 bits per sample */
- const int compression_ratio = 4; /* G.722 has a 4:1 compression ratio */
- if (codec_type == CODEC_G722_24KHZ) {
- sample_rate = 24000;
- } else {
- sample_rate = 16000;
- }
-
- // compressed_data_packet_size is the size in bytes of the compressed audio
- // data buffer that is generated for each connection interval.
- uint32_t compressed_data_packet_size =
- (sample_rate * connection_interval * (sample_bit_rate / 8) /
- compression_ratio) /
- 1000;
- return ((uint16_t)compressed_data_packet_size);
- }
-
- void ChooseCodec(const HearingDevice& hearingDevice) {
- if (codec_in_use) return;
-
- // use the best codec available for this pair of devices.
- uint16_t codecs = hearingDevice.codecs;
- if (hearingDevice.hi_sync_id != 0) {
- for (const auto& device : hearingDevices.devices) {
- if (device.hi_sync_id != hearingDevice.hi_sync_id) continue;
-
- codecs &= device.codecs;
- }
- }
-
- if ((codecs & (1 << CODEC_G722_24KHZ)) &&
- controller_get_interface()->supports_ble_2m_phy() &&
- default_data_interval_ms == HA_INTERVAL_10_MS) {
- codec_in_use = CODEC_G722_24KHZ;
- } else if (codecs & (1 << CODEC_G722_16KHZ)) {
- codec_in_use = CODEC_G722_16KHZ;
- }
- }
-
- void OnAudioStatus(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
- uint16_t len, uint8_t* value, void* data) {
- LOG(INFO) << __func__ << " " << base::HexEncode(value, len);
- }
-
- void OnPsmRead(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
- uint16_t len, uint8_t* value, void* data) {
- HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
- if (!hearingDevice) {
- DVLOG(2) << "Skipping unknown read event, conn_id=" << loghex(conn_id);
- return;
- }
-
- if (status != GATT_SUCCESS) {
- LOG(ERROR) << "Error reading PSM for device" << hearingDevice->address;
- return;
- }
-
- if (len > 2) {
- LOG(ERROR) << "Bad PSM length";
- return;
- }
-
- uint16_t psm = *((uint16_t*)value);
- VLOG(2) << "read psm:" << loghex(psm);
-
- ConnectSocket(hearingDevice, psm);
- }
-
- void ConnectSocket(HearingDevice* hearingDevice, uint16_t psm) {
- tL2CAP_CFG_INFO cfg_info = tL2CAP_CFG_INFO{.mtu = 512};
-
- SendEnableServiceChangedInd(hearingDevice);
-
- uint8_t service_id = hearingDevice->isLeft()
- ? BTM_SEC_SERVICE_HEARING_AID_LEFT
- : BTM_SEC_SERVICE_HEARING_AID_RIGHT;
- uint16_t gap_handle = GAP_ConnOpen(
- "", service_id, false, &hearingDevice->address, psm, 514 /* MPS */,
- &cfg_info, nullptr, BTM_SEC_NONE /* TODO: request security ? */,
- HearingAidImpl::GapCallbackStatic, BT_TRANSPORT_LE);
- if (gap_handle == GAP_INVALID_HANDLE) {
- LOG(ERROR) << "UNABLE TO GET gap_handle";
- return;
- }
-
- hearingDevice->gap_handle = gap_handle;
- LOG(INFO) << "Successfully sent GAP connect request";
- }
-
- static void OnReadOnlyPropertiesReadStatic(uint16_t conn_id,
- tGATT_STATUS status,
- uint16_t handle, uint16_t len,
- uint8_t* value, void* data) {
- if (instance)
- instance->OnReadOnlyPropertiesRead(conn_id, status, handle, len, value,
- data);
- }
- static void OnAudioStatusStatic(uint16_t conn_id, tGATT_STATUS status,
- uint16_t handle, uint16_t len, uint8_t* value,
- void* data) {
- if (instance)
- instance->OnAudioStatus(conn_id, status, handle, len, value, data);
- }
-
- static void OnPsmReadStatic(uint16_t conn_id, tGATT_STATUS status,
- uint16_t handle, uint16_t len, uint8_t* value,
- void* data) {
- if (instance)
- instance->OnPsmRead(conn_id, status, handle, len, value, data);
- }
-
- /* CoC Socket is ready */
- void OnGapConnection(const RawAddress& address) {
- HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
- if (!hearingDevice) {
- LOG(INFO) << "Device not connected to profile" << address;
- return;
- }
-
- if (hearingDevice->first_connection) {
- btif_storage_add_hearing_aid(*hearingDevice);
-
- hearingDevice->first_connection = false;
- }
-
- LOG(INFO) << __func__ << ": audio_status_handle="
- << loghex(hearingDevice->audio_status_handle)
- << ", audio_status_ccc_handle="
- << loghex(hearingDevice->audio_status_ccc_handle);
-
- /* Register and enable the Audio Status Notification */
- tGATT_STATUS register_status;
- register_status = BTA_GATTC_RegisterForNotifications(
- gatt_if, address, hearingDevice->audio_status_handle);
- if (register_status != GATT_SUCCESS) {
- LOG(ERROR) << __func__
- << ": BTA_GATTC_RegisterForNotifications failed, status="
- << loghex(static_cast<uint8_t>(register_status));
- return;
- }
- std::vector<uint8_t> value(2);
- uint8_t* ptr = value.data();
- UINT16_TO_STREAM(ptr, GATT_CHAR_CLIENT_CONFIG_NOTIFICATION);
- BtaGattQueue::WriteDescriptor(
- hearingDevice->conn_id, hearingDevice->audio_status_ccc_handle,
- std::move(value), GATT_WRITE, write_rpt_ctl_cfg_cb, nullptr);
-
- ChooseCodec(*hearingDevice);
-
- SendStart(hearingDevice);
-
- if (audio_running) {
- // Inform the other side (if any) of this connection
- std::vector<uint8_t> inform_conn_state(
- {CONTROL_POINT_OP_STATE_CHANGE, STATE_CHANGE_OTHER_SIDE_CONNECTED});
- send_state_change_to_other_side(hearingDevice, inform_conn_state);
- }
-
- hearingDevice->accepting_audio = true;
- LOG(INFO) << __func__ << ": address=" << address
- << ", hi_sync_id=" << loghex(hearingDevice->hi_sync_id)
- << ", codec_in_use=" << loghex(codec_in_use)
- << ", audio_running=" << audio_running;
-
- StartSendingAudio(*hearingDevice);
-
- callbacks->OnDeviceAvailable(hearingDevice->capabilities,
- hearingDevice->hi_sync_id, address);
- callbacks->OnConnectionState(ConnectionState::CONNECTED, address);
- }
-
- void StartSendingAudio(const HearingDevice& hearingDevice) {
- VLOG(0) << __func__ << ": device=" << hearingDevice.address;
-
- if (encoder_state_left == nullptr) {
- encoder_state_init();
- seq_counter = 0;
-
- CodecConfiguration codec;
- if (codec_in_use == CODEC_G722_24KHZ) {
- codec.sample_rate = 24000;
- } else {
- codec.sample_rate = 16000;
- }
- codec.bit_rate = 16;
- codec.data_interval_ms = default_data_interval_ms;
-
- uint16_t delay_report_ms = 0;
- if (hearingDevice.render_delay != 0) {
- delay_report_ms =
- hearingDevice.render_delay +
- (ADD_RENDER_DELAY_INTERVALS * default_data_interval_ms);
- }
-
- HearingAidAudioSource::Start(codec, audioReceiver, delay_report_ms);
- }
- }
-
- void OnAudioSuspend(const std::function<void()>& stop_audio_ticks) {
- CHECK(stop_audio_ticks) << "stop_audio_ticks is empty";
-
- if (!audio_running) {
- LOG(WARNING) << __func__ << ": Unexpected audio suspend";
- } else {
- LOG(INFO) << __func__ << ": audio_running=" << audio_running;
- }
- audio_running = false;
- stop_audio_ticks();
-
- std::vector<uint8_t> stop({CONTROL_POINT_OP_STOP});
- for (auto& device : hearingDevices.devices) {
- if (!device.accepting_audio) continue;
-
- if (!device.playback_started) {
- LOG(WARNING) << __func__
- << ": Playback not started, skip send Stop cmd, device="
- << device.address;
- } else {
- LOG(INFO) << __func__ << ": send Stop cmd, device=" << device.address;
- device.playback_started = false;
- device.command_acked = false;
- BtaGattQueue::WriteCharacteristic(device.conn_id,
- device.audio_control_point_handle,
- stop, GATT_WRITE, nullptr, nullptr);
- }
- }
- }
-
- void OnAudioResume(const std::function<void()>& start_audio_ticks) {
- CHECK(start_audio_ticks) << "start_audio_ticks is empty";
-
- if (audio_running) {
- LOG(ERROR) << __func__ << ": Unexpected Audio Resume";
- } else {
- LOG(INFO) << __func__ << ": audio_running=" << audio_running;
- }
-
- for (auto& device : hearingDevices.devices) {
- if (!device.accepting_audio) continue;
- audio_running = true;
- SendStart(&device);
- }
-
- if (!audio_running) {
- LOG(INFO) << __func__ << ": No device (0/" << GetDeviceCount()
- << ") ready to start";
- return;
- }
-
- // TODO: shall we also reset the encoder ?
- encoder_state_release();
- encoder_state_init();
- seq_counter = 0;
-
- start_audio_ticks();
- }
-
- uint8_t GetOtherSideStreamStatus(HearingDevice* this_side_device) {
- for (auto& device : hearingDevices.devices) {
- if ((device.address == this_side_device->address) ||
- (device.hi_sync_id != this_side_device->hi_sync_id)) {
- continue;
- }
- if (audio_running && (device.conn_id != 0)) {
- return (OTHER_SIDE_IS_STREAMING);
- } else {
- return (OTHER_SIDE_NOT_STREAMING);
- }
- }
- return (OTHER_SIDE_NOT_STREAMING);
- }
-
- void SendEnableServiceChangedInd(HearingDevice* device) {
- VLOG(2) << __func__ << " Enable " << device->address
- << "service changed ind.";
- std::vector<uint8_t> value(2);
- uint8_t* ptr = value.data();
- UINT16_TO_STREAM(ptr, GATT_CHAR_CLIENT_CONFIG_INDICTION);
- BtaGattQueue::WriteDescriptor(
- device->conn_id, device->service_changed_ccc_handle, std::move(value),
- GATT_WRITE, nullptr, nullptr);
- }
-
- void SendStart(HearingDevice* device) {
- std::vector<uint8_t> start({CONTROL_POINT_OP_START, codec_in_use,
- AUDIOTYPE_UNKNOWN, (uint8_t)current_volume,
- OTHER_SIDE_NOT_STREAMING});
-
- if (!audio_running) {
- if (!device->playback_started) {
- LOG(INFO) << __func__
- << ": Skip Send Start since audio is not running, device="
- << device->address;
- } else {
- LOG(ERROR) << __func__
- << ": Audio not running but Playback has started, device="
- << device->address;
- }
- return;
- }
-
- if (current_volume == VOLUME_UNKNOWN) start[3] = (uint8_t)VOLUME_MIN;
-
- if (device->playback_started) {
- LOG(ERROR) << __func__
- << ": Playback already started, skip send Start cmd, device="
- << device->address;
- } else {
- start[4] = GetOtherSideStreamStatus(device);
- LOG(INFO) << __func__ << ": send Start cmd, volume=" << loghex(start[3])
- << ", audio type=" << loghex(start[2])
- << ", device=" << device->address
- << ", other side streaming=" << loghex(start[4]);
- device->playback_started = true;
- device->command_acked = false;
- BtaGattQueue::WriteCharacteristic(device->conn_id,
- device->audio_control_point_handle,
- start, GATT_WRITE, nullptr, nullptr);
- }
- }
-
- void OnAudioDataReady(const std::vector<uint8_t>& data) {
- /* For now we assume data comes in as 16bit per sample 16kHz PCM stereo */
- DVLOG(2) << __func__;
-
- int num_samples =
- data.size() / (2 /*bytes_per_sample*/ * 2 /*number of channels*/);
-
- // The G.722 codec accept only even number of samples for encoding
- if (num_samples % 2 != 0)
- LOG(FATAL) << "num_samples is not even: " << num_samples;
-
- // TODO: we should cache left/right and current state, instad of recomputing
- // it for each packet, 100 times a second.
- HearingDevice* left = nullptr;
- HearingDevice* right = nullptr;
- for (auto& device : hearingDevices.devices) {
- if (!device.accepting_audio) continue;
-
- if (device.isLeft())
- left = &device;
- else
- right = &device;
- }
-
- if (left == nullptr && right == nullptr) {
- LOG(WARNING) << __func__ << ": No more (0/" << GetDeviceCount()
- << ") devices ready";
- DoDisconnectAudioStop();
- return;
- }
-
- std::vector<uint16_t> chan_left;
- std::vector<uint16_t> chan_right;
- if (left == nullptr || right == nullptr) {
- for (int i = 0; i < num_samples; i++) {
- const uint8_t* sample = data.data() + i * 4;
-
- int16_t left = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
-
- sample += 2;
- int16_t right = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
-
- uint16_t mono_data = (int16_t)(((uint32_t)left + (uint32_t)right) >> 1);
- chan_left.push_back(mono_data);
- chan_right.push_back(mono_data);
- }
- } else {
- for (int i = 0; i < num_samples; i++) {
- const uint8_t* sample = data.data() + i * 4;
-
- uint16_t left = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
- chan_left.push_back(left);
-
- sample += 2;
- uint16_t right = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
- chan_right.push_back(right);
- }
- }
-
- // TODO: monural, binarual check
-
- // divide encoded data into packets, add header, send.
-
- // TODO: make those buffers static and global to prevent constant
- // reallocations
- // TODO: this should basically fit the encoded data, tune the size later
- std::vector<uint8_t> encoded_data_left;
- if (left) {
- // TODO: instead of a magic number, we need to figure out the correct
- // buffer size
- encoded_data_left.resize(4000);
- int encoded_size =
- g722_encode(encoder_state_left, encoded_data_left.data(),
- (const int16_t*)chan_left.data(), chan_left.size());
- encoded_data_left.resize(encoded_size);
-
- uint16_t cid = GAP_ConnGetL2CAPCid(left->gap_handle);
- uint16_t packets_to_flush = L2CA_FlushChannel(cid, L2CAP_FLUSH_CHANS_GET);
- if (packets_to_flush) {
- VLOG(2) << left->address << " skipping " << packets_to_flush
- << " packets";
- left->audio_stats.packet_flush_count += packets_to_flush;
- left->audio_stats.frame_flush_count++;
- hearingDevices.StartRssiLog();
- }
- // flush all packets stuck in queue
- L2CA_FlushChannel(cid, 0xffff);
- check_and_do_rssi_read(left);
- }
-
- std::vector<uint8_t> encoded_data_right;
- if (right) {
- // TODO: instead of a magic number, we need to figure out the correct
- // buffer size
- encoded_data_right.resize(4000);
- int encoded_size =
- g722_encode(encoder_state_right, encoded_data_right.data(),
- (const int16_t*)chan_right.data(), chan_right.size());
- encoded_data_right.resize(encoded_size);
-
- uint16_t cid = GAP_ConnGetL2CAPCid(right->gap_handle);
- uint16_t packets_to_flush = L2CA_FlushChannel(cid, L2CAP_FLUSH_CHANS_GET);
- if (packets_to_flush) {
- VLOG(2) << right->address << " skipping " << packets_to_flush
- << " packets";
- right->audio_stats.packet_flush_count += packets_to_flush;
- right->audio_stats.frame_flush_count++;
- hearingDevices.StartRssiLog();
- }
- // flush all packets stuck in queue
- L2CA_FlushChannel(cid, 0xffff);
- check_and_do_rssi_read(right);
- }
-
- size_t encoded_data_size =
- std::max(encoded_data_left.size(), encoded_data_right.size());
-
- uint16_t packet_size =
- CalcCompressedAudioPacketSize(codec_in_use, default_data_interval_ms);
-
- for (size_t i = 0; i < encoded_data_size; i += packet_size) {
- if (left) {
- left->audio_stats.packet_send_count++;
- SendAudio(encoded_data_left.data() + i, packet_size, left);
- }
- if (right) {
- right->audio_stats.packet_send_count++;
- SendAudio(encoded_data_right.data() + i, packet_size, right);
- }
- seq_counter++;
- }
- if (left) left->audio_stats.frame_send_count++;
- if (right) right->audio_stats.frame_send_count++;
- }
-
- void SendAudio(uint8_t* encoded_data, uint16_t packet_size,
- HearingDevice* hearingAid) {
- if (!hearingAid->playback_started || !hearingAid->command_acked) {
- VLOG(2) << __func__
- << ": Playback stalled, device=" << hearingAid->address
- << ", cmd send=" << hearingAid->playback_started
- << ", cmd acked=" << hearingAid->command_acked;
- return;
- }
-
- BT_HDR* audio_packet = malloc_l2cap_buf(packet_size + 1);
- uint8_t* p = get_l2cap_sdu_start_ptr(audio_packet);
- *p = seq_counter;
- p++;
- memcpy(p, encoded_data, packet_size);
-
- DVLOG(2) << hearingAid->address << " : " << base::HexEncode(p, packet_size);
-
- uint16_t result = GAP_ConnWriteData(hearingAid->gap_handle, audio_packet);
-
- if (result != BT_PASS) {
- LOG(ERROR) << " Error sending data: " << loghex(result);
- }
- }
-
- void GapCallback(uint16_t gap_handle, uint16_t event, tGAP_CB_DATA* data) {
- HearingDevice* hearingDevice = hearingDevices.FindByGapHandle(gap_handle);
- if (!hearingDevice) {
- LOG(INFO) << "Skipping unknown device, gap_handle=" << gap_handle;
- return;
- }
-
- switch (event) {
- case GAP_EVT_CONN_OPENED: {
- RawAddress address = *GAP_ConnGetRemoteAddr(gap_handle);
- uint16_t tx_mtu = GAP_ConnGetRemMtuSize(gap_handle);
-
- LOG(INFO) << "GAP_EVT_CONN_OPENED " << address << ", tx_mtu=" << tx_mtu;
- OnGapConnection(address);
- break;
- }
-
- // TODO: handle properly!
- case GAP_EVT_CONN_CLOSED:
- LOG(INFO) << __func__
- << ": GAP_EVT_CONN_CLOSED: " << hearingDevice->address
- << ", playback_started=" << hearingDevice->playback_started;
- hearingDevice->accepting_audio = false;
- hearingDevice->gap_handle = 0;
- hearingDevice->playback_started = false;
- hearingDevice->command_acked = false;
- break;
- case GAP_EVT_CONN_DATA_AVAIL: {
- DVLOG(2) << "GAP_EVT_CONN_DATA_AVAIL";
-
- // only data we receive back from hearing aids are some stats, not
- // really important, but useful now for debugging.
- uint32_t bytes_to_read = 0;
- GAP_GetRxQueueCnt(gap_handle, &bytes_to_read);
- std::vector<uint8_t> buffer(bytes_to_read);
-
- uint16_t bytes_read = 0;
- // TODO:GAP_ConnReadData should accpet uint32_t for length!
- GAP_ConnReadData(gap_handle, buffer.data(), buffer.size(), &bytes_read);
-
- if (bytes_read < 4) {
- LOG(WARNING) << " Wrong data length";
- return;
- }
-
- uint8_t* p = buffer.data();
-
- DVLOG(1) << "stats from the hearing aid:";
- for (size_t i = 0; i + 4 <= buffer.size(); i += 4) {
- uint16_t event_counter, frame_index;
- STREAM_TO_UINT16(event_counter, p);
- STREAM_TO_UINT16(frame_index, p);
- DVLOG(1) << "event_counter=" << event_counter
- << " frame_index: " << frame_index;
- }
- break;
- }
-
- case GAP_EVT_TX_EMPTY:
- DVLOG(2) << "GAP_EVT_TX_EMPTY";
- break;
- case GAP_EVT_CONN_CONGESTED:
- DVLOG(2) << "GAP_EVT_CONN_CONGESTED";
-
- // TODO: make it into function
- HearingAidAudioSource::Stop();
- // TODO: kill the encoder only if all hearing aids are down.
- // g722_encode_release(encoder_state);
- // encoder_state_left = nulllptr;
- // encoder_state_right = nulllptr;
- break;
- case GAP_EVT_CONN_UNCONGESTED:
- DVLOG(2) << "GAP_EVT_CONN_UNCONGESTED";
- break;
- }
- }
-
- static void GapCallbackStatic(uint16_t gap_handle, uint16_t event,
- tGAP_CB_DATA* data) {
- if (instance) instance->GapCallback(gap_handle, event, data);
- }
-
- void DumpRssi(int fd, const HearingDevice& device) {
- const struct AudioStats* stats = &device.audio_stats;
-
- if (stats->rssi_history.size() <= 0) {
- dprintf(fd, " No RSSI history for %s:\n", device.address.ToString().c_str());
- return;
- }
- dprintf(fd, " RSSI history for %s:\n", device.address.ToString().c_str());
-
- dprintf(fd, " Time of RSSI 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9\n");
- for (auto& rssi_logs : stats->rssi_history) {
- if (rssi_logs.rssi.size() <= 0) {
- break;
- }
-
- char eventtime[20];
- char temptime[20];
- struct tm* tstamp = localtime(&rssi_logs.timestamp.tv_sec);
- if (!strftime(temptime, sizeof(temptime), "%H:%M:%S", tstamp)) {
- LOG(ERROR) << __func__ << ": strftime fails. tm_sec=" << tstamp->tm_sec << ", tm_min=" << tstamp->tm_min
- << ", tm_hour=" << tstamp->tm_hour;
- strlcpy(temptime, "UNKNOWN TIME", sizeof(temptime));
- }
- snprintf(eventtime, sizeof(eventtime), "%s.%03ld", temptime, rssi_logs.timestamp.tv_nsec / 1000000);
-
- dprintf(fd, " %s: ", eventtime);
-
- for (auto rssi_value : rssi_logs.rssi) {
- dprintf(fd, " %04d", rssi_value);
- }
- dprintf(fd, "\n");
- }
- }
-
- void Dump(int fd) {
- std::stringstream stream;
- for (const auto& device : hearingDevices.devices) {
- bool side = device.capabilities & CAPABILITY_SIDE;
- bool standalone = device.capabilities & CAPABILITY_BINAURAL;
- stream << " " << device.address.ToString() << " "
- << (device.accepting_audio ? "" : "not ") << "connected"
- << "\n " << (standalone ? "binaural" : "monaural") << " "
- << (side ? "right" : "left") << " " << loghex(device.hi_sync_id)
- << std::endl;
- stream
- << " Packet counts (enqueued/flushed) : "
- << device.audio_stats.packet_send_count << " / "
- << device.audio_stats.packet_flush_count
- << "\n Frame counts (enqueued/flushed) : "
- << device.audio_stats.frame_send_count << " / "
- << device.audio_stats.frame_flush_count << std::endl;
-
- DumpRssi(fd, device);
- }
- dprintf(fd, "%s", stream.str().c_str());
- }
-
- void Disconnect(const RawAddress& address) override {
- DVLOG(2) << __func__;
- HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
- if (!hearingDevice) {
- LOG(INFO) << "Device not connected to profile" << address;
- return;
- }
-
- VLOG(2) << __func__ << ": " << address;
-
- bool connected = hearingDevice->accepting_audio;
-
- LOG(INFO) << "GAP_EVT_CONN_CLOSED: " << hearingDevice->address
- << ", playback_started=" << hearingDevice->playback_started
- << ", accepting_audio=" << hearingDevice->accepting_audio;
-
- if (hearingDevice->connecting_actively) {
- // cancel pending direct connect
- BTA_GATTC_CancelOpen(gatt_if, address, true);
- }
-
- // Removes all registrations for connection.
- BTA_GATTC_CancelOpen(0, address, false);
-
- // Inform the other side (if any) of this disconnection
- std::vector<uint8_t> inform_disconn_state(
- {CONTROL_POINT_OP_STATE_CHANGE, STATE_CHANGE_OTHER_SIDE_DISCONNECTED});
- send_state_change_to_other_side(hearingDevice, inform_disconn_state);
-
- DoDisconnectCleanUp(hearingDevice);
-
- hearingDevices.Remove(address);
-
- if (!connected) {
- return;
- }
-
- callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address);
- for (const auto& device : hearingDevices.devices) {
- if (device.accepting_audio) return;
- }
- LOG(INFO) << __func__ << ": No more (0/" << GetDeviceCount()
- << ") devices ready";
- DoDisconnectAudioStop();
- }
-
- void OnGattDisconnected(uint16_t conn_id, tGATT_IF client_if,
- RawAddress remote_bda) {
- HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
- if (!hearingDevice) {
- VLOG(2) << "Skipping unknown device disconnect, conn_id="
- << loghex(conn_id);
- return;
- }
- VLOG(2) << __func__ << ": conn_id=" << loghex(conn_id)
- << ", remote_bda=" << remote_bda;
-
- // Inform the other side (if any) of this disconnection
- std::vector<uint8_t> inform_disconn_state(
- {CONTROL_POINT_OP_STATE_CHANGE, STATE_CHANGE_OTHER_SIDE_DISCONNECTED});
- send_state_change_to_other_side(hearingDevice, inform_disconn_state);
-
- DoDisconnectCleanUp(hearingDevice);
-
- // This is needed just for the first connection. After stack is restarted,
- // code that loads device will add them to acceptlist.
- BTA_GATTC_Open(gatt_if, hearingDevice->address, false, false);
-
- callbacks->OnConnectionState(ConnectionState::DISCONNECTED, remote_bda);
-
- for (const auto& device : hearingDevices.devices) {
- if (device.accepting_audio) return;
- }
- LOG(INFO) << __func__ << ": No more (0/" << GetDeviceCount()
- << ") devices ready";
- DoDisconnectAudioStop();
- }
-
- void DoDisconnectCleanUp(HearingDevice* hearingDevice) {
- if (hearingDevice->connection_update_status != COMPLETED) {
- LOG(INFO) << __func__ << ": connection update not completed. Current="
- << hearingDevice->connection_update_status
- << ", device=" << hearingDevice->address;
-
- if (hearingDevice->connection_update_status == STARTED) {
- OnConnectionUpdateComplete(hearingDevice->conn_id, NULL);
- }
- }
- hearingDevice->connection_update_status = NONE;
-
- if (hearingDevice->conn_id) {
- BtaGattQueue::Clean(hearingDevice->conn_id);
- BTA_GATTC_Close(hearingDevice->conn_id);
- hearingDevice->conn_id = 0;
- }
-
- if (hearingDevice->gap_handle) {
- GAP_ConnClose(hearingDevice->gap_handle);
- hearingDevice->gap_handle = 0;
- }
-
- hearingDevice->accepting_audio = false;
- LOG(INFO) << __func__ << ": device=" << hearingDevice->address
- << ", playback_started=" << hearingDevice->playback_started;
- hearingDevice->playback_started = false;
- hearingDevice->command_acked = false;
- }
-
- void DoDisconnectAudioStop() {
- HearingAidAudioSource::Stop();
- audio_running = false;
- encoder_state_release();
- current_volume = VOLUME_UNKNOWN;
- }
-
- void SetVolume(int8_t volume) override {
- VLOG(2) << __func__ << ": " << +volume;
- current_volume = volume;
- for (HearingDevice& device : hearingDevices.devices) {
- if (!device.accepting_audio) continue;
-
- std::vector<uint8_t> volume_value({static_cast<unsigned char>(volume)});
- BtaGattQueue::WriteCharacteristic(device.conn_id, device.volume_handle,
- volume_value, GATT_WRITE_NO_RSP,
- nullptr, nullptr);
- }
- }
-
- void CleanUp() {
- BTA_GATTC_AppDeregister(gatt_if);
- for (HearingDevice& device : hearingDevices.devices) {
- DoDisconnectCleanUp(&device);
- }
-
- hearingDevices.devices.clear();
-
- encoder_state_release();
- }
-
- private:
- uint8_t gatt_if;
- uint8_t seq_counter;
- /* current volume gain for the hearing aids*/
- int8_t current_volume;
- bluetooth::hearing_aid::HearingAidCallbacks* callbacks;
-
- /* currently used codec */
- uint8_t codec_in_use;
-
- uint16_t default_data_interval_ms;
-
- HearingDevices hearingDevices;
-
- void find_server_changed_ccc_handle(uint16_t conn_id,
- const gatt::Service* service) {
- HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
- if (!hearingDevice) {
- DVLOG(2) << "Skipping unknown device, conn_id=" << loghex(conn_id);
- return;
- }
- for (const gatt::Characteristic& charac : service->characteristics) {
- if (charac.uuid == Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD)) {
- hearingDevice->service_changed_ccc_handle =
- find_ccc_handle(conn_id, charac.value_handle);
- if (!hearingDevice->service_changed_ccc_handle) {
- LOG(ERROR) << __func__
- << ": cannot find service changed CCC descriptor";
- continue;
- }
- LOG(INFO) << __func__ << " service_changed_ccc="
- << loghex(hearingDevice->service_changed_ccc_handle);
- break;
- }
- }
- }
-
- // Find the handle for the client characteristics configuration of a given
- // characteristics
- uint16_t find_ccc_handle(uint16_t conn_id, uint16_t char_handle) {
- const gatt::Characteristic* p_char =
- BTA_GATTC_GetCharacteristic(conn_id, char_handle);
-
- if (!p_char) {
- LOG(WARNING) << __func__ << ": No such characteristic: " << char_handle;
- return 0;
- }
-
- for (const gatt::Descriptor& desc : p_char->descriptors) {
- if (desc.uuid == Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG))
- return desc.handle;
- }
-
- return 0;
- }
-
- void send_state_change(HearingDevice* device, std::vector<uint8_t> payload) {
- if (device->conn_id != 0) {
- if (device->service_changed_rcvd) {
- LOG(INFO)
- << __func__
- << ": service discover is in progress, skip send State Change cmd.";
- return;
- }
- // Send the data packet
- LOG(INFO) << __func__ << ": Send State Change. device=" << device->address
- << ", status=" << loghex(payload[1]);
- BtaGattQueue::WriteCharacteristic(
- device->conn_id, device->audio_control_point_handle, payload,
- GATT_WRITE_NO_RSP, nullptr, nullptr);
- }
- }
-
- void send_state_change_to_other_side(HearingDevice* this_side_device,
- std::vector<uint8_t> payload) {
- for (auto& device : hearingDevices.devices) {
- if ((device.address == this_side_device->address) ||
- (device.hi_sync_id != this_side_device->hi_sync_id)) {
- continue;
- }
- send_state_change(&device, payload);
- }
- }
-
- void check_and_do_rssi_read(HearingDevice* device) {
- if (device->read_rssi_count > 0) {
- device->num_intervals_since_last_rssi_read++;
- if (device->num_intervals_since_last_rssi_read >= PERIOD_TO_READ_RSSI_IN_INTERVALS) {
- device->num_intervals_since_last_rssi_read = 0;
- VLOG(1) << __func__ << ": device=" << device->address;
- BTM_ReadRSSI(device->address, read_rssi_cb);
- }
- }
- }
-};
-
-void read_rssi_cb(void* p_void) {
- tBTM_RSSI_RESULT* p_result = (tBTM_RSSI_RESULT*)p_void;
-
- if (!p_result) return;
-
- if ((instance) && (p_result->status == BTM_SUCCESS)) {
- instance->OnReadRssiComplete(p_result->rem_bda, p_result->rssi);
- }
-}
-
-void hearingaid_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
- VLOG(2) << __func__ << " event = " << +event;
-
- if (p_data == nullptr) return;
-
- switch (event) {
- case BTA_GATTC_DEREG_EVT:
- break;
-
- case BTA_GATTC_OPEN_EVT: {
- if (!instance) return;
- tBTA_GATTC_OPEN& o = p_data->open;
- instance->OnGattConnected(o.status, o.conn_id, o.client_if, o.remote_bda,
- o.transport, o.mtu);
- break;
- }
-
- case BTA_GATTC_CLOSE_EVT: {
- if (!instance) return;
- tBTA_GATTC_CLOSE& c = p_data->close;
- instance->OnGattDisconnected(c.conn_id, c.client_if, c.remote_bda);
- } break;
-
- case BTA_GATTC_SEARCH_CMPL_EVT:
- if (!instance) return;
- instance->OnServiceSearchComplete(p_data->search_cmpl.conn_id,
- p_data->search_cmpl.status);
- break;
-
- case BTA_GATTC_NOTIF_EVT:
- if (!instance) return;
- if (!p_data->notify.is_notify || p_data->notify.len > GATT_MAX_ATTR_LEN) {
- LOG(ERROR) << __func__ << ": rejected BTA_GATTC_NOTIF_EVT. is_notify="
- << p_data->notify.is_notify
- << ", len=" << p_data->notify.len;
- break;
- }
- instance->OnNotificationEvent(p_data->notify.conn_id,
- p_data->notify.handle, p_data->notify.len,
- p_data->notify.value);
- break;
-
- case BTA_GATTC_ENC_CMPL_CB_EVT:
- if (!instance) return;
- instance->OnEncryptionComplete(p_data->enc_cmpl.remote_bda, true);
- break;
-
- case BTA_GATTC_CONN_UPDATE_EVT:
- if (!instance) return;
- instance->OnConnectionUpdateComplete(p_data->conn_update.conn_id, p_data);
- break;
-
- case BTA_GATTC_SRVC_CHG_EVT:
- if (!instance) return;
- instance->OnServiceChangeEvent(p_data->remote_bda);
- break;
-
- case BTA_GATTC_SRVC_DISC_DONE_EVT:
- if (!instance) return;
- instance->OnServiceDiscDoneEvent(p_data->service_changed.remote_bda);
- break;
-
- default:
- break;
- }
-}
-
-void encryption_callback(const RawAddress* address, tBT_TRANSPORT, void*,
- tBTM_STATUS status) {
- if (instance) {
- instance->OnEncryptionComplete(*address,
- status == BTM_SUCCESS ? true : false);
- }
-}
-
-class HearingAidAudioReceiverImpl : public HearingAidAudioReceiver {
- public:
- void OnAudioDataReady(const std::vector<uint8_t>& data) override {
- if (instance) instance->OnAudioDataReady(data);
- }
- void OnAudioSuspend(const std::function<void()>& stop_audio_ticks) override {
- if (instance) instance->OnAudioSuspend(stop_audio_ticks);
- }
- void OnAudioResume(const std::function<void()>& start_audio_ticks) override {
- if (instance) instance->OnAudioResume(start_audio_ticks);
- }
-};
-
-HearingAidAudioReceiverImpl audioReceiverImpl;
-
-} // namespace
-
-void HearingAid::Initialize(
- bluetooth::hearing_aid::HearingAidCallbacks* callbacks, Closure initCb) {
- if (instance) {
- LOG(ERROR) << "Already initialized!";
- }
-
- audioReceiver = &audioReceiverImpl;
- instance = new HearingAidImpl(callbacks, initCb);
- HearingAidAudioSource::Initialize();
-}
-
-bool HearingAid::IsHearingAidRunning() { return instance; }
-
-HearingAid* HearingAid::Get() {
- CHECK(instance);
- return instance;
-};
-
-void HearingAid::AddFromStorage(const HearingDevice& dev_info,
- uint16_t is_acceptlisted) {
- if (!instance) {
- LOG(ERROR) << "Not initialized yet";
- }
-
- instance->AddFromStorage(dev_info, is_acceptlisted);
-};
-
-int HearingAid::GetDeviceCount() {
- if (!instance) {
- LOG(INFO) << __func__ << ": Not initialized yet";
- return 0;
- }
-
- return (instance->GetDeviceCount());
-}
-
-void HearingAid::CleanUp() {
- // Must stop audio source to make sure it doesn't call any of callbacks on our
- // soon to be null instance
- HearingAidAudioSource::Stop();
-
- HearingAidImpl* ptr = instance;
- instance = nullptr;
- HearingAidAudioSource::CleanUp();
-
- ptr->CleanUp();
-
- delete ptr;
-};
-
-void HearingAid::DebugDump(int fd) {
- dprintf(fd, "Hearing Aid Manager:\n");
- if (instance) instance->Dump(fd);
- HearingAidAudioSource::DebugDump(fd);
- dprintf(fd, "\n");
-}
diff --git a/bta/hearing_aid/hearing_aid_audio_source.cc b/bta/hearing_aid/hearing_aid_audio_source.cc
deleted file mode 100644
index c7a684c..0000000
--- a/bta/hearing_aid/hearing_aid_audio_source.cc
+++ /dev/null
@@ -1,450 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2018 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 <base/files/file_util.h>
-#include <base/logging.h>
-#include <cstdint>
-#include <memory>
-#include <sstream>
-#include <vector>
-
-#include "audio_hal_interface/hearing_aid_software_encoding.h"
-#include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h"
-#include "bta/include/bta_hearing_aid_api.h"
-#include "common/repeating_timer.h"
-#include "common/time_util.h"
-#include "osi/include/wakelock.h"
-#include "stack/include/btu.h" // get_main_thread
-#include "udrv/include/uipc.h"
-
-using base::FilePath;
-
-namespace {
-#define CASE_RETURN_STR(const) \
- case const: \
- return #const;
-
-const char* audio_ha_hw_dump_ctrl_event(tHEARING_AID_CTRL_CMD event) {
- switch (event) {
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_NONE)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_CHECK_READY)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_START)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_STOP)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_SUSPEND)
- CASE_RETURN_STR(HEARING_AID_CTRL_GET_INPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(HEARING_AID_CTRL_GET_OUTPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_OFFLOAD_START)
- default:
- break;
- }
-
- return "UNKNOWN HEARING_AID_CTRL_CMD";
-}
-
-int bit_rate = -1;
-int sample_rate = -1;
-int data_interval_ms = -1;
-int num_channels = 2;
-bluetooth::common::RepeatingTimer audio_timer;
-HearingAidAudioReceiver* localAudioReceiver = nullptr;
-std::unique_ptr<tUIPC_STATE> uipc_hearing_aid = nullptr;
-
-struct AudioHalStats {
- size_t media_read_total_underflow_bytes;
- size_t media_read_total_underflow_count;
- uint64_t media_read_last_underflow_us;
-
- AudioHalStats() { Reset(); }
-
- void Reset() {
- media_read_total_underflow_bytes = 0;
- media_read_total_underflow_count = 0;
- media_read_last_underflow_us = 0;
- }
-};
-
-AudioHalStats stats;
-
-bool hearing_aid_on_resume_req(bool start_media_task);
-bool hearing_aid_on_suspend_req();
-
-void send_audio_data() {
- uint32_t bytes_per_tick =
- (num_channels * sample_rate * data_interval_ms * (bit_rate / 8)) / 1000;
-
- uint8_t p_buf[bytes_per_tick];
-
- uint32_t bytes_read;
- if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) {
- bytes_read = bluetooth::audio::hearing_aid::read(p_buf, bytes_per_tick);
- } else {
- bytes_read = UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, p_buf,
- bytes_per_tick);
- }
-
- VLOG(2) << "bytes_read: " << bytes_read;
- if (bytes_read < bytes_per_tick) {
- stats.media_read_total_underflow_bytes += bytes_per_tick - bytes_read;
- stats.media_read_total_underflow_count++;
- stats.media_read_last_underflow_us =
- bluetooth::common::time_get_os_boottime_us();
- }
-
- std::vector<uint8_t> data(p_buf, p_buf + bytes_read);
-
- if (localAudioReceiver != nullptr) {
- localAudioReceiver->OnAudioDataReady(data);
- }
-}
-
-void hearing_aid_send_ack(tHEARING_AID_CTRL_ACK status) {
- uint8_t ack = status;
- DVLOG(2) << "Hearing Aid audio ctrl ack: " << status;
- UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, &ack, sizeof(ack));
-}
-
-void start_audio_ticks() {
- if (data_interval_ms != HA_INTERVAL_10_MS &&
- data_interval_ms != HA_INTERVAL_20_MS) {
- LOG(FATAL) << " Unsupported data interval: " << data_interval_ms;
- }
-
- wakelock_acquire();
- audio_timer.SchedulePeriodic(
- get_main_thread()->GetWeakPtr(), FROM_HERE, base::Bind(&send_audio_data),
- base::TimeDelta::FromMilliseconds(data_interval_ms));
- LOG(INFO) << __func__ << ": running with data interval: " << data_interval_ms;
-}
-
-void stop_audio_ticks() {
- LOG(INFO) << __func__ << ": stopped";
- audio_timer.CancelAndWait();
- wakelock_release();
-}
-
-void hearing_aid_data_cb(tUIPC_CH_ID, tUIPC_EVENT event) {
- DVLOG(2) << "Hearing Aid audio data event: " << event;
- switch (event) {
- case UIPC_OPEN_EVT:
- LOG(INFO) << __func__ << ": UIPC_OPEN_EVT";
- /*
- * Read directly from media task from here on (keep callback for
- * connection events.
- */
- UIPC_Ioctl(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO,
- UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
- UIPC_Ioctl(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
- reinterpret_cast<void*>(0));
-
- do_in_main_thread(FROM_HERE, base::BindOnce(start_audio_ticks));
- break;
- case UIPC_CLOSE_EVT:
- LOG(INFO) << __func__ << ": UIPC_CLOSE_EVT";
- hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
- do_in_main_thread(FROM_HERE, base::BindOnce(stop_audio_ticks));
- break;
- default:
- LOG(ERROR) << "Hearing Aid audio data event not recognized:" << event;
- }
-}
-
-void hearing_aid_recv_ctrl_data() {
- tHEARING_AID_CTRL_CMD cmd = HEARING_AID_CTRL_CMD_NONE;
- int n;
-
- uint8_t read_cmd = 0; /* The read command size is one octet */
- n = UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, &read_cmd, 1);
- cmd = static_cast<tHEARING_AID_CTRL_CMD>(read_cmd);
-
- /* detach on ctrl channel means audioflinger process was terminated */
- if (n == 0) {
- LOG(WARNING) << __func__ << "CTRL CH DETACHED";
- UIPC_Close(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL);
- return;
- }
-
- LOG(INFO) << __func__ << " " << audio_ha_hw_dump_ctrl_event(cmd);
- // a2dp_cmd_pending = cmd;
-
- tHEARING_AID_CTRL_ACK ctrl_ack_status;
-
- switch (cmd) {
- case HEARING_AID_CTRL_CMD_CHECK_READY:
- hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
- break;
-
- case HEARING_AID_CTRL_CMD_START:
- ctrl_ack_status = HEARING_AID_CTRL_ACK_SUCCESS;
- // timer is restarted in UIPC_Open
- if (!hearing_aid_on_resume_req(false)) {
- ctrl_ack_status = HEARING_AID_CTRL_ACK_FAILURE;
- } else {
- UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, hearing_aid_data_cb,
- HEARING_AID_DATA_PATH);
- }
- hearing_aid_send_ack(ctrl_ack_status);
- break;
-
- case HEARING_AID_CTRL_CMD_STOP:
- if (!hearing_aid_on_suspend_req()) {
- LOG(INFO) << __func__ << ":HEARING_AID_CTRL_CMD_STOP: hearing_aid_on_suspend_req() errs, but ignored.";
- }
- hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
- break;
-
- case HEARING_AID_CTRL_CMD_SUSPEND:
- ctrl_ack_status = HEARING_AID_CTRL_ACK_SUCCESS;
- if (!hearing_aid_on_suspend_req()) {
- ctrl_ack_status = HEARING_AID_CTRL_ACK_FAILURE;
- }
- hearing_aid_send_ack(ctrl_ack_status);
- break;
-
- case HEARING_AID_CTRL_GET_OUTPUT_AUDIO_CONFIG: {
- btav_a2dp_codec_config_t codec_config;
- btav_a2dp_codec_config_t codec_capability;
- if (sample_rate == 16000) {
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_16000;
- codec_capability.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_16000;
- } else if (sample_rate == 24000) {
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_24000;
- codec_capability.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_24000;
- } else {
- LOG(FATAL) << "unsupported sample rate: " << sample_rate;
- }
-
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;
- codec_capability.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;
-
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
- codec_capability.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
-
- hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
- // Send the current codec config
- UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
- reinterpret_cast<const uint8_t*>(&codec_config.sample_rate),
- sizeof(btav_a2dp_codec_sample_rate_t));
- UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
- reinterpret_cast<const uint8_t*>(&codec_config.bits_per_sample),
- sizeof(btav_a2dp_codec_bits_per_sample_t));
- UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
- reinterpret_cast<const uint8_t*>(&codec_config.channel_mode),
- sizeof(btav_a2dp_codec_channel_mode_t));
- // Send the current codec capability
- UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
- reinterpret_cast<const uint8_t*>(&codec_capability.sample_rate),
- sizeof(btav_a2dp_codec_sample_rate_t));
- UIPC_Send(
- *uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
- reinterpret_cast<const uint8_t*>(&codec_capability.bits_per_sample),
- sizeof(btav_a2dp_codec_bits_per_sample_t));
- UIPC_Send(
- *uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
- reinterpret_cast<const uint8_t*>(&codec_capability.channel_mode),
- sizeof(btav_a2dp_codec_channel_mode_t));
- break;
- }
-
- case HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG: {
- // TODO: we only support one config for now!
- btav_a2dp_codec_config_t codec_config;
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
-
- hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
- // Send the current codec config
- if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL,
- reinterpret_cast<uint8_t*>(&codec_config.sample_rate),
- sizeof(btav_a2dp_codec_sample_rate_t)) !=
- sizeof(btav_a2dp_codec_sample_rate_t)) {
- LOG(ERROR) << __func__ << "Error reading sample rate from audio HAL";
- break;
- }
- if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL,
- reinterpret_cast<uint8_t*>(&codec_config.bits_per_sample),
- sizeof(btav_a2dp_codec_bits_per_sample_t)) !=
- sizeof(btav_a2dp_codec_bits_per_sample_t)) {
- LOG(ERROR) << __func__
- << "Error reading bits per sample from audio HAL";
-
- break;
- }
- if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL,
- reinterpret_cast<uint8_t*>(&codec_config.channel_mode),
- sizeof(btav_a2dp_codec_channel_mode_t)) !=
- sizeof(btav_a2dp_codec_channel_mode_t)) {
- LOG(ERROR) << __func__ << "Error reading channel mode from audio HAL";
-
- break;
- }
- LOG(INFO) << __func__ << " HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG: "
- << "sample_rate=" << codec_config.sample_rate
- << "bits_per_sample=" << codec_config.bits_per_sample
- << "channel_mode=" << codec_config.channel_mode;
- break;
- }
-
- default:
- LOG(ERROR) << __func__ << "UNSUPPORTED CMD: " << cmd;
- hearing_aid_send_ack(HEARING_AID_CTRL_ACK_FAILURE);
- break;
- }
- LOG(INFO) << __func__
- << " a2dp-ctrl-cmd : " << audio_ha_hw_dump_ctrl_event(cmd)
- << " DONE";
-}
-
-void hearing_aid_ctrl_cb(tUIPC_CH_ID, tUIPC_EVENT event) {
- VLOG(2) << "Hearing Aid audio ctrl event: " << event;
- switch (event) {
- case UIPC_OPEN_EVT:
- break;
- case UIPC_CLOSE_EVT:
- /* restart ctrl server unless we are shutting down */
- if (HearingAid::IsHearingAidRunning()) {
- UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, hearing_aid_ctrl_cb,
- HEARING_AID_CTRL_PATH);
- }
- break;
- case UIPC_RX_DATA_READY_EVT:
- hearing_aid_recv_ctrl_data();
- break;
- default:
- LOG(ERROR) << "Hearing Aid audio ctrl unrecognized event: " << event;
- }
-}
-
-bool hearing_aid_on_resume_req(bool start_media_task) {
- if (localAudioReceiver == nullptr) {
- LOG(ERROR) << __func__
- << ": HEARING_AID_CTRL_CMD_START: audio receiver not started";
- return false;
- }
- bt_status_t status;
- if (start_media_task) {
- status = do_in_main_thread(
- FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioResume,
- base::Unretained(localAudioReceiver),
- start_audio_ticks));
- } else {
- auto start_dummy_ticks = []() {
- LOG(INFO) << "start_audio_ticks: waiting for data path opened";
- };
- status = do_in_main_thread(
- FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioResume,
- base::Unretained(localAudioReceiver),
- start_dummy_ticks));
- }
- if (status != BT_STATUS_SUCCESS) {
- LOG(ERROR) << __func__
- << ": HEARING_AID_CTRL_CMD_START: do_in_main_thread err="
- << status;
- return false;
- }
- return true;
-}
-
-bool hearing_aid_on_suspend_req() {
- if (localAudioReceiver == nullptr) {
- LOG(ERROR) << __func__
- << ": HEARING_AID_CTRL_CMD_SUSPEND: audio receiver not started";
- return false;
- }
- bt_status_t status = do_in_main_thread(
- FROM_HERE,
- base::BindOnce(&HearingAidAudioReceiver::OnAudioSuspend,
- base::Unretained(localAudioReceiver), stop_audio_ticks));
- if (status != BT_STATUS_SUCCESS) {
- LOG(ERROR) << __func__
- << ": HEARING_AID_CTRL_CMD_SUSPEND: do_in_main_thread err="
- << status;
- return false;
- }
- return true;
-}
-} // namespace
-
-void HearingAidAudioSource::Start(const CodecConfiguration& codecConfiguration,
- HearingAidAudioReceiver* audioReceiver,
- uint16_t remote_delay_ms) {
- LOG(INFO) << __func__ << ": Hearing Aid Source Open";
-
- bit_rate = codecConfiguration.bit_rate;
- sample_rate = codecConfiguration.sample_rate;
- data_interval_ms = codecConfiguration.data_interval_ms;
-
- stats.Reset();
-
- if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) {
- bluetooth::audio::hearing_aid::start_session();
- bluetooth::audio::hearing_aid::set_remote_delay(remote_delay_ms);
- }
- localAudioReceiver = audioReceiver;
-}
-
-void HearingAidAudioSource::Stop() {
- LOG(INFO) << __func__ << ": Hearing Aid Source Close";
-
- localAudioReceiver = nullptr;
- if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) {
- bluetooth::audio::hearing_aid::end_session();
- }
-
- stop_audio_ticks();
-}
-
-void HearingAidAudioSource::Initialize() {
- auto stream_cb = bluetooth::audio::hearing_aid::StreamCallbacks{
- .on_resume_ = hearing_aid_on_resume_req,
- .on_suspend_ = hearing_aid_on_suspend_req,
- };
- if (!bluetooth::audio::hearing_aid::init(stream_cb, get_main_thread())) {
- LOG(WARNING) << __func__ << ": Using legacy HAL";
- uipc_hearing_aid = UIPC_Init();
- UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, hearing_aid_ctrl_cb, HEARING_AID_CTRL_PATH);
- }
-}
-
-void HearingAidAudioSource::CleanUp() {
- if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) {
- bluetooth::audio::hearing_aid::cleanup();
- } else {
- UIPC_Close(*uipc_hearing_aid, UIPC_CH_ID_ALL);
- uipc_hearing_aid = nullptr;
- }
-}
-
-void HearingAidAudioSource::DebugDump(int fd) {
- uint64_t now_us = bluetooth::common::time_get_os_boottime_us();
- std::stringstream stream;
- stream << " Hearing Aid Audio HAL:"
- << "\n Counts (underflow) : "
- << stats.media_read_total_underflow_count
- << "\n Bytes (underflow) : "
- << stats.media_read_total_underflow_bytes
- << "\n Last update time ago in ms (underflow) : "
- << (stats.media_read_last_underflow_us > 0
- ? (unsigned long long)(now_us -
- stats.media_read_last_underflow_us) /
- 1000
- : 0)
- << std::endl;
- dprintf(fd, "%s", stream.str().c_str());
-}
diff --git a/bta/hf_client/bta_hf_client_act.cc b/bta/hf_client/bta_hf_client_act.cc
deleted file mode 100644
index 175f703..0000000
--- a/bta/hf_client/bta_hf_client_act.cc
+++ /dev/null
@@ -1,456 +0,0 @@
-/******************************************************************************
- *
- * Copyright (c) 2014 The Android Open Source Project
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains action functions for the handsfree client.
- *
- ******************************************************************************/
-
-#include "bt_trace.h" // Legacy trace logging
-
-#include "bta/hf_client/bta_hf_client_int.h"
-#include "bta/include/bta_dm_api.h"
-#include "stack/include/l2c_api.h"
-#include "stack/include/port_api.h"
-#include "types/raw_address.h"
-
-#include <base/logging.h>
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-
-/* maximum length of data to read from RFCOMM */
-#define BTA_HF_CLIENT_RFC_READ_MAX 512
-
-/*******************************************************************************
- *
- * Function bta_hf_client_start_close
- *
- * Description Start the process of closing SCO and RFCOMM connection.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_start_close(tBTA_HF_CLIENT_DATA* p_data) {
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- /* Take the link out of sniff and set L2C idle time to 0 */
- bta_dm_pm_active(client_cb->peer_addr);
- L2CA_SetIdleTimeoutByBdAddr(client_cb->peer_addr, 0, BT_TRANSPORT_BR_EDR);
-
- /* if SCO is open close SCO and wait on RFCOMM close */
- if (client_cb->sco_state == BTA_HF_CLIENT_SCO_OPEN_ST) {
- client_cb->sco_close_rfc = true;
- } else {
- bta_hf_client_rfc_do_close(p_data);
- }
-
- /* always do SCO shutdown to handle all SCO corner cases */
- bta_hf_client_sco_shutdown(client_cb);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_start_open
- *
- * Description This starts an HF Client open.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA* p_data) {
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- /* store parameters */
- if (p_data) {
- client_cb->peer_addr = p_data->api_open.bd_addr;
- }
-
- /* Check if RFCOMM has any incoming connection to avoid collision. */
- RawAddress pending_bd_addr = RawAddress::kEmpty;
- if (PORT_IsOpening(&pending_bd_addr)) {
- /* Let the incoming connection goes through. */
- /* Issue collision for now. */
- /* We will decide what to do when we find incoming connection later.*/
- bta_hf_client_collision_cback(BTA_SYS_CONN_OPEN, BTA_ID_HS, 0,
- client_cb->peer_addr);
- return;
- }
-
- /* set role */
- client_cb->role = BTA_HF_CLIENT_INT;
-
- /* do service search */
- bta_hf_client_do_disc(client_cb);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_rfc_open
- *
- * Description Handle RFCOMM channel open.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA* p_data) {
- APPL_TRACE_DEBUG("%s", __func__);
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- bta_sys_conn_open(BTA_ID_HS, 1, client_cb->peer_addr);
-
- /* start SLC procedure */
- bta_hf_client_slc_seq(client_cb, false);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_rfc_acp_open
- *
- * Description Handle RFCOMM channel open when accepting connection.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA* p_data) {
- APPL_TRACE_DEBUG("%s", __func__);
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
- /* set role */
- client_cb->role = BTA_HF_CLIENT_ACP;
-
- APPL_TRACE_DEBUG("%s: conn_handle %d", __func__, client_cb->conn_handle);
-
- /* get bd addr of peer */
- uint16_t lcid = 0;
- RawAddress dev_addr = RawAddress::kEmpty;
- int status = PORT_CheckConnection(client_cb->conn_handle, &dev_addr, &lcid);
- if (status != PORT_SUCCESS) {
- LOG(ERROR) << __func__ << ": PORT_CheckConnection returned " << status;
- }
-
- /* Collision Handling */
- if (alarm_is_scheduled(client_cb->collision_timer)) {
- alarm_cancel(client_cb->collision_timer);
-
- if (dev_addr == client_cb->peer_addr) {
- /* If incoming and outgoing device are same, nothing more to do. */
- /* Outgoing conn will be aborted because we have successful incoming conn.
- */
- } else {
- /* Resume outgoing connection. */
- bta_hf_client_resume_open(client_cb);
- }
- }
-
- client_cb->peer_addr = dev_addr;
-
- /* do service discovery to get features */
- bta_hf_client_do_disc(client_cb);
-
- /* continue with open processing */
- bta_hf_client_rfc_open(p_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_rfc_fail
- *
- * Description RFCOMM connection failed.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA* p_data) {
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- /* reinitialize stuff */
- client_cb->peer_features = 0;
- client_cb->chld_features = 0;
- client_cb->role = BTA_HF_CLIENT_ACP;
- client_cb->svc_conn = false;
- client_cb->send_at_reply = false;
- client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;
-
- bta_hf_client_at_reset(client_cb);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_disc_fail
- *
- * Description This function handles a discovery failure.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA* p_data) {
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_open_fail
- *
- * Description open connection failed.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA* p_data) {
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_rfc_close
- *
- * Description RFCOMM connection closed.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA* p_data) {
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- bta_hf_client_at_reset(client_cb);
-
- bta_sys_conn_close(BTA_ID_HS, 1, client_cb->peer_addr);
-
- /* call close cback */
- tBTA_HF_CLIENT evt;
- memset(&evt, 0, sizeof(evt));
- evt.conn.bd_addr = client_cb->peer_addr;
-
- /* if not deregistering reopen server */
- if (!bta_hf_client_cb_arr.deregister) {
- /* Make sure SCO is shutdown */
- bta_hf_client_sco_shutdown(client_cb);
-
- bta_sys_sco_unuse(BTA_ID_HS, 1, client_cb->peer_addr);
- }
- /* else close port and deallocate scb */
- else {
- tBTA_HF_CLIENT evt;
- memset(&evt, 0, sizeof(evt));
- evt.reg.bd_addr = client_cb->peer_addr;
- bta_hf_client_app_callback(BTA_HF_CLIENT_DISABLE_EVT, &evt);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_disc_int_res
- *
- * Description This function handles a discovery result when initiator.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA* p_data) {
- uint16_t event = BTA_HF_CLIENT_DISC_FAIL_EVT;
-
- APPL_TRACE_DEBUG("%s: Status: %d", __func__, p_data->disc_result.status);
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- /* if found service */
- if (p_data->disc_result.status == SDP_SUCCESS ||
- p_data->disc_result.status == SDP_DB_FULL) {
- /* get attributes */
- if (bta_hf_client_sdp_find_attr(client_cb)) {
- event = BTA_HF_CLIENT_DISC_OK_EVT;
- }
- }
-
- /* free discovery db */
- bta_hf_client_free_db(p_data);
-
- /* send ourselves sdp ok/fail event */
- bta_hf_client_sm_execute(event, p_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_disc_acp_res
- *
- * Description This function handles a discovery result when acceptor.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA* p_data) {
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- /* if found service */
- if (p_data->disc_result.status == SDP_SUCCESS ||
- p_data->disc_result.status == SDP_DB_FULL) {
- /* get attributes */
- bta_hf_client_sdp_find_attr(client_cb);
- }
-
- /* free discovery db */
- bta_hf_client_free_db(p_data);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_rfc_data
- *
- * Description Read and process data from RFCOMM.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA* p_data) {
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- uint16_t len;
- char buf[BTA_HF_CLIENT_RFC_READ_MAX];
- memset(buf, 0, sizeof(buf));
- /* read data from rfcomm; if bad status, we're done */
- while (PORT_ReadData(client_cb->conn_handle, buf, BTA_HF_CLIENT_RFC_READ_MAX,
- &len) == PORT_SUCCESS) {
- /* if no data, we're done */
- if (len == 0) {
- break;
- }
-
- bta_hf_client_at_parse(client_cb, buf, len);
-
- /* no more data to read, we're done */
- if (len < BTA_HF_CLIENT_RFC_READ_MAX) {
- break;
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_svc_conn_open
- *
- * Description Service level connection opened
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA* p_data) {
- APPL_TRACE_DEBUG("%s", __func__);
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- tBTA_HF_CLIENT evt;
-
- memset(&evt, 0, sizeof(evt));
-
- if (!client_cb->svc_conn) {
- /* set state variable */
- client_cb->svc_conn = true;
-
- /* call callback */
- evt.conn.bd_addr = client_cb->peer_addr;
- evt.conn.peer_feat = client_cb->peer_features;
- evt.conn.chld_feat = client_cb->chld_features;
-
- bta_hf_client_app_callback(BTA_HF_CLIENT_CONN_EVT, &evt);
- }
-}
diff --git a/bta/hf_client/bta_hf_client_api.cc b/bta/hf_client/bta_hf_client_api.cc
deleted file mode 100644
index 15d57fe..0000000
--- a/bta/hf_client/bta_hf_client_api.cc
+++ /dev/null
@@ -1,205 +0,0 @@
-/******************************************************************************
- *
- * Copyright (c) 2014 The Android Open Source Project
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This is the implementation of the API for the handsfree (HF role)
- * subsystem of BTA
- *
- ******************************************************************************/
-
-#include "bta/include/bta_hf_client_api.h"
-
-#include <cstdint>
-
-#include "bt_trace.h" // Legacy trace logging
-#include "bta/hf_client/bta_hf_client_int.h"
-#include "bta/sys/bta_sys.h"
-#include "osi/include/allocator.h"
-#include "osi/include/compat.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/bt_types.h"
-#include "types/raw_address.h"
-
-/*****************************************************************************
- * External Function Declarations
- ****************************************************************************/
-
-/*******************************************************************************
- *
- * Function BTA_HfClientEnable
- *
- * Description Enable the HF CLient service. It does the following:
- * 1. Sets the state to initialized (control blocks)
- * 2. Starts the SDP for the client role (HF)
- * 3. Starts the RFCOMM server to accept incoming connections
- * The function is synchronous and returns with an error code
- * if anything went wrong. This should be the first call to the
- * API before doing an BTA_HfClientOpen
- *
- * Returns BTA_SUCCESS if OK, BTA_FAILURE otherwise.
- *
- ******************************************************************************/
-tBTA_STATUS BTA_HfClientEnable(tBTA_HF_CLIENT_CBACK* p_cback,
- tBTA_HF_CLIENT_FEAT features,
- const char* p_service_name) {
- return bta_hf_client_api_enable(p_cback, features, p_service_name);
-}
-
-/*******************************************************************************
- *
- * Function BTA_HfClientDisable
- *
- * Description Disable the HF Client service
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_HfClientDisable(void) { bta_hf_client_api_disable(); }
-
-/*******************************************************************************
- *
- * Function BTA_HfClientOpen
- *
- * Description Opens up a RF connection to the remote device and
- * subsequently set it up for a HF SLC
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_HfClientOpen(const RawAddress& bd_addr, uint16_t* p_handle) {
- APPL_TRACE_DEBUG("%s", __func__);
- tBTA_HF_CLIENT_API_OPEN* p_buf =
- (tBTA_HF_CLIENT_API_OPEN*)osi_malloc(sizeof(tBTA_HF_CLIENT_API_OPEN));
-
- if (!bta_hf_client_allocate_handle(bd_addr, p_handle)) {
- APPL_TRACE_ERROR("%s: could not allocate handle", __func__);
- return;
- }
-
- p_buf->hdr.event = BTA_HF_CLIENT_API_OPEN_EVT;
- p_buf->hdr.layer_specific = *p_handle;
- p_buf->bd_addr = bd_addr;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_HfClientClose
- *
- * Description Close the current connection to an audio gateway.
- * Any current audio connection will also be closed
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_HfClientClose(uint16_t handle) {
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
-
- p_buf->event = BTA_HF_CLIENT_API_CLOSE_EVT;
- p_buf->layer_specific = handle;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_HfCllientAudioOpen
- *
- * Description Opens an audio connection to the currently connected
- * audio gateway
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_HfClientAudioOpen(uint16_t handle) {
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
-
- p_buf->event = BTA_HF_CLIENT_API_AUDIO_OPEN_EVT;
- p_buf->layer_specific = handle;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_HfClientAudioClose
- *
- * Description Close the currently active audio connection to an audio
- * gateway. The data connection remains open
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_HfClientAudioClose(uint16_t handle) {
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
-
- p_buf->event = BTA_HF_CLIENT_API_AUDIO_CLOSE_EVT;
- p_buf->layer_specific = handle;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_HfClientSendAT
- *
- * Description send AT command
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void BTA_HfClientSendAT(uint16_t handle, tBTA_HF_CLIENT_AT_CMD_TYPE at,
- uint32_t val1, uint32_t val2, const char* str) {
- tBTA_HF_CLIENT_DATA_VAL* p_buf =
- (tBTA_HF_CLIENT_DATA_VAL*)osi_malloc(sizeof(tBTA_HF_CLIENT_DATA_VAL));
-
- p_buf->hdr.event = BTA_HF_CLIENT_SEND_AT_CMD_EVT;
- p_buf->uint8_val = at;
- p_buf->uint32_val1 = val1;
- p_buf->uint32_val2 = val2;
-
- if (str) {
- strlcpy(p_buf->str, str, BTA_HF_CLIENT_NUMBER_LEN + 1);
- p_buf->str[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
- } else {
- p_buf->str[0] = '\0';
- }
-
- p_buf->hdr.layer_specific = handle;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function BTA_HfClientDumpStatistics
- *
- * Description Dump statistics about the various control blocks
- * and other relevant connection statistics
- *
- * Returns Void
- *
- ******************************************************************************/
-void BTA_HfClientDumpStatistics(int fd) { bta_hf_client_dump_statistics(fd); }
diff --git a/bta/hf_client/bta_hf_client_at.cc b/bta/hf_client/bta_hf_client_at.cc
deleted file mode 100644
index f2fcf82..0000000
--- a/bta/hf_client/bta_hf_client_at.cc
+++ /dev/null
@@ -1,2285 +0,0 @@
-/******************************************************************************
- *
- * Copyright (c) 2014 The Android Open Source Project
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-#define LOG_TAG "bt_hf_client"
-
-#include "bt_trace.h" // Legacy trace logging
-
-#include "bta/hf_client/bta_hf_client_int.h"
-#include "osi/include/allocator.h"
-#include "osi/include/compat.h"
-#include "osi/include/log.h"
-#include "stack/include/port_api.h"
-
-/* Uncomment to enable AT traffic dumping */
-/* #define BTA_HF_CLIENT_AT_DUMP 1 */
-
-/* minimum length of AT event */
-#define BTA_HF_CLIENT_AT_EVENT_MIN_LEN 3
-
-/* timeout (in milliseconds) for AT response */
-#define BTA_HF_CLIENT_AT_TIMEOUT 29989
-
-/* timeout (in milliseconds) for AT hold timer */
-#define BTA_HF_CLIENT_AT_HOLD_TIMEOUT 41
-
-/******************************************************************************
- * SUPPORTED EVENT MESSAGES
- ******************************************************************************/
-
-/* CIND: supported indicator names */
-#define BTA_HF_CLIENT_INDICATOR_BATTERYCHG "battchg"
-#define BTA_HF_CLIENT_INDICATOR_SIGNAL "signal"
-#define BTA_HF_CLIENT_INDICATOR_SERVICE "service"
-#define BTA_HF_CLIENT_INDICATOR_CALL "call"
-#define BTA_HF_CLIENT_INDICATOR_ROAM "roam"
-#define BTA_HF_CLIENT_INDICATOR_CALLSETUP "callsetup"
-#define BTA_HF_CLIENT_INDICATOR_CALLHELD "callheld"
-
-/* BIND parse mode */
-#define BTA_HF_CLIENT_BIND_PARSE_READ_ENABLED_IND 0
-#define BTA_HF_CLIENT_BIND_PARSE_READ_SUPPOETED_IND 1
-
-#define MIN(a, b) \
- ({ \
- __typeof__(a) _a = (a); \
- __typeof__(b) _b = (b); \
- (_a < _b) ? _a : _b; \
- })
-
-/* CIND: represents each indicators boundaries */
-typedef struct {
- const char* name;
- uint8_t min;
- uint8_t max;
- uint8_t namelen;
-} tBTA_HF_CLIENT_INDICATOR;
-
-#define BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT 7
-
-/* CIND: storage room for indicators value range and their statuses */
-static const tBTA_HF_CLIENT_INDICATOR
- bta_hf_client_indicators[BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT] = {
- /* name | min | max | name length -
- used by parser */
- {BTA_HF_CLIENT_INDICATOR_BATTERYCHG, 0, 5,
- sizeof(BTA_HF_CLIENT_INDICATOR_BATTERYCHG)},
- {BTA_HF_CLIENT_INDICATOR_SIGNAL, 0, 5,
- sizeof(BTA_HF_CLIENT_INDICATOR_SIGNAL)},
- {BTA_HF_CLIENT_INDICATOR_SERVICE, 0, 1,
- sizeof(BTA_HF_CLIENT_INDICATOR_SERVICE)},
- {BTA_HF_CLIENT_INDICATOR_CALL, 0, 1,
- sizeof(BTA_HF_CLIENT_INDICATOR_CALL)},
- {BTA_HF_CLIENT_INDICATOR_ROAM, 0, 1,
- sizeof(BTA_HF_CLIENT_INDICATOR_ROAM)},
- {BTA_HF_CLIENT_INDICATOR_CALLSETUP, 0, 3,
- sizeof(BTA_HF_CLIENT_INDICATOR_CALLSETUP)},
- {BTA_HF_CLIENT_INDICATOR_CALLHELD, 0, 2,
- sizeof(BTA_HF_CLIENT_INDICATOR_CALLHELD)}};
-
-/* +VGM/+VGS - gain min/max values */
-#define BTA_HF_CLIENT_VGS_MIN 0
-#define BTA_HF_CLIENT_VGS_MAX 15
-#define BTA_HF_CLIENT_VGM_MIN 0
-#define BTA_HF_CLIENT_VGM_MAX 15
-
-uint32_t service_index = 0;
-bool service_availability = true;
-/* helper functions for handling AT commands queueing */
-
-static void bta_hf_client_handle_ok(tBTA_HF_CLIENT_CB* client_cb);
-
-static void bta_hf_client_clear_queued_at(tBTA_HF_CLIENT_CB* client_cb) {
- tBTA_HF_CLIENT_AT_QCMD* cur = client_cb->at_cb.queued_cmd;
- tBTA_HF_CLIENT_AT_QCMD* next;
-
- while (cur != NULL) {
- next = cur->next;
- osi_free(cur);
- cur = next;
- }
-
- client_cb->at_cb.queued_cmd = NULL;
-}
-
-static void bta_hf_client_queue_at(tBTA_HF_CLIENT_CB* client_cb,
- tBTA_HF_CLIENT_AT_CMD cmd, const char* buf,
- uint16_t buf_len) {
- tBTA_HF_CLIENT_AT_QCMD* new_cmd =
- (tBTA_HF_CLIENT_AT_QCMD*)osi_malloc(sizeof(tBTA_HF_CLIENT_AT_QCMD));
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- new_cmd->cmd = cmd;
- new_cmd->buf_len = buf_len;
- new_cmd->next = NULL;
- memcpy(new_cmd->buf, buf, buf_len);
-
- if (client_cb->at_cb.queued_cmd != NULL) {
- tBTA_HF_CLIENT_AT_QCMD* qcmd = client_cb->at_cb.queued_cmd;
-
- while (qcmd->next != NULL) qcmd = qcmd->next;
-
- qcmd->next = new_cmd;
- } else {
- client_cb->at_cb.queued_cmd = new_cmd;
- }
-}
-
-static void bta_hf_client_at_resp_timer_cback(void* data) {
- tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data;
- if (client_cb->at_cb.current_cmd == BTA_HF_CLIENT_AT_CNUM) {
- LOG_INFO("%s: timed out waiting for AT+CNUM response; spoofing OK.",
- __func__);
- bta_hf_client_handle_ok(client_cb);
- } else {
- APPL_TRACE_ERROR("HFPClient: AT response timeout, disconnecting");
-
- tBTA_HF_CLIENT_DATA msg = {};
- msg.hdr.layer_specific = client_cb->handle;
- bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
- }
-}
-
-static void bta_hf_client_start_at_resp_timer(tBTA_HF_CLIENT_CB* client_cb) {
- alarm_set_on_mloop(client_cb->at_cb.resp_timer, BTA_HF_CLIENT_AT_TIMEOUT,
- bta_hf_client_at_resp_timer_cback, (void*)client_cb);
-}
-
-static void bta_hf_client_stop_at_resp_timer(tBTA_HF_CLIENT_CB* client_cb) {
- alarm_cancel(client_cb->at_cb.resp_timer);
-}
-
-static void bta_hf_client_send_at(tBTA_HF_CLIENT_CB* client_cb,
- tBTA_HF_CLIENT_AT_CMD cmd, const char* buf,
- uint16_t buf_len) {
- APPL_TRACE_DEBUG("%s", __func__);
- if ((client_cb->at_cb.current_cmd == BTA_HF_CLIENT_AT_NONE ||
- !client_cb->svc_conn) &&
- !alarm_is_scheduled(client_cb->at_cb.hold_timer)) {
- uint16_t len;
-
-#ifdef BTA_HF_CLIENT_AT_DUMP
- APPL_TRACE_DEBUG("%s: %.*s", __func__, buf_len - 1, buf);
-#endif
-
- client_cb->at_cb.current_cmd = cmd;
- /* Generate fake responses for these because they won't reliably work */
- if (!service_availability &&
- (cmd == BTA_HF_CLIENT_AT_CNUM || cmd == BTA_HF_CLIENT_AT_COPS)) {
- APPL_TRACE_WARNING("%s: No service, skipping %d command", __func__, cmd);
- bta_hf_client_handle_ok(client_cb);
- return;
- }
-
- APPL_TRACE_DEBUG("%s: writing port data to %d", __func__,
- client_cb->conn_handle);
- PORT_WriteData(client_cb->conn_handle, buf, buf_len, &len);
-
- bta_hf_client_start_at_resp_timer(client_cb);
-
- return;
- }
-
- bta_hf_client_queue_at(client_cb, cmd, buf, buf_len);
-}
-
-static void bta_hf_client_send_queued_at(tBTA_HF_CLIENT_CB* client_cb) {
- tBTA_HF_CLIENT_AT_QCMD* cur = client_cb->at_cb.queued_cmd;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- if (cur != NULL) {
- client_cb->at_cb.queued_cmd = cur->next;
-
- bta_hf_client_send_at(client_cb, cur->cmd, cur->buf, cur->buf_len);
-
- osi_free(cur);
- }
-}
-
-static void bta_hf_client_at_hold_timer_cback(void* data) {
- tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data;
- APPL_TRACE_DEBUG("%s", __func__);
- bta_hf_client_send_queued_at(client_cb);
-}
-
-static void bta_hf_client_stop_at_hold_timer(tBTA_HF_CLIENT_CB* client_cb) {
- APPL_TRACE_DEBUG("%s", __func__);
- alarm_cancel(client_cb->at_cb.hold_timer);
-}
-
-static void bta_hf_client_start_at_hold_timer(tBTA_HF_CLIENT_CB* client_cb) {
- APPL_TRACE_DEBUG("%s", __func__);
- alarm_set_on_mloop(client_cb->at_cb.hold_timer, BTA_HF_CLIENT_AT_HOLD_TIMEOUT,
- bta_hf_client_at_hold_timer_cback, (void*)client_cb);
-}
-
-/******************************************************************************
- *
- * COMMON AT EVENT HANDLING funcS
- *
- * Receives data (strings, ints, etc.) from the parser and processes this
- * data. No buffer parsing is being done here.
- ******************************************************************************/
-
-static void bta_hf_client_handle_ok(tBTA_HF_CLIENT_CB* client_cb) {
- APPL_TRACE_DEBUG("%s", __func__);
-
- bta_hf_client_stop_at_resp_timer(client_cb);
-
- if (!client_cb->svc_conn) {
- bta_hf_client_slc_seq(client_cb, false);
- return;
- }
-
- switch (client_cb->at_cb.current_cmd) {
- case BTA_HF_CLIENT_AT_BIA:
- case BTA_HF_CLIENT_AT_BCC:
- break;
- case BTA_HF_CLIENT_AT_BCS:
- bta_hf_client_start_at_hold_timer(client_cb);
- client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
- return;
- case BTA_HF_CLIENT_AT_CLIP: // last cmd is post slc seq
- if (!client_cb->send_at_reply) {
- client_cb->send_at_reply = true;
- }
- break;
- case BTA_HF_CLIENT_AT_NONE:
- bta_hf_client_stop_at_hold_timer(client_cb);
- break;
- default:
- if (client_cb->send_at_reply) {
- bta_hf_client_at_result(client_cb, BTA_HF_CLIENT_AT_RESULT_OK, 0);
- }
- break;
- }
-
- client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
-
- bta_hf_client_send_queued_at(client_cb);
-}
-
-static void bta_hf_client_handle_error(tBTA_HF_CLIENT_CB* client_cb,
- tBTA_HF_CLIENT_AT_RESULT_TYPE type,
- uint16_t cme) {
- APPL_TRACE_DEBUG("%s: %u %u", __func__, type, cme);
-
- bta_hf_client_stop_at_resp_timer(client_cb);
-
- if (!client_cb->svc_conn) {
- bta_hf_client_slc_seq(client_cb, true);
- return;
- }
-
- switch (client_cb->at_cb.current_cmd) {
- case BTA_HF_CLIENT_AT_BIA:
- break;
- case BTA_HF_CLIENT_AT_BCC:
- case BTA_HF_CLIENT_AT_BCS:
- bta_hf_client_cback_sco(client_cb, BTA_HF_CLIENT_AUDIO_CLOSE_EVT);
- break;
- case BTA_HF_CLIENT_AT_CLIP: // last cmd is post slc seq
- if (!client_cb->send_at_reply) {
- client_cb->send_at_reply = true;
- }
- break;
- default:
- if (client_cb->send_at_reply) {
- bta_hf_client_at_result(client_cb, type, cme);
- }
- break;
- }
-
- client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
-
- bta_hf_client_send_queued_at(client_cb);
-}
-
-static void bta_hf_client_handle_ring(tBTA_HF_CLIENT_CB* client_cb) {
- APPL_TRACE_DEBUG("%s", __func__);
- bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_RING_INDICATION, 0);
-}
-
-static void bta_hf_client_handle_brsf(tBTA_HF_CLIENT_CB* client_cb,
- uint32_t value) {
- APPL_TRACE_DEBUG("%s: 0x%x", __func__, value);
- client_cb->peer_features = value;
-}
-
-/* handles a single indicator descriptor - registers it for value changing
- * events */
-static void bta_hf_client_handle_cind_list_item(tBTA_HF_CLIENT_CB* client_cb,
- char* name, uint32_t min,
- uint32_t max, uint32_t index) {
- uint8_t i = 0;
-
- APPL_TRACE_DEBUG("%s: %lu.%s <%lu:%lu>", __func__, index, name, min, max);
-
- /* look for a matching indicator on list of supported ones */
- for (i = 0; i < BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT; i++) {
- if (strcmp(name, BTA_HF_CLIENT_INDICATOR_SERVICE) == 0) {
- service_index = index;
- }
- /* look for a match - search one sign further than indicators name to check
- * for string end */
- /* It will distinguish 'callheld' which could be matched by strncmp as
- * 'call'. */
- if (strncmp(name, bta_hf_client_indicators[i].name,
- bta_hf_client_indicators[i].namelen) != 0)
- continue;
-
- /* index - enumerates value position in the incoming sequence */
- /* if name matches one of the known indicators, add its incoming position */
- /* to lookup table for easy value->indicator matching later, when only
- * values come */
- client_cb->at_cb.indicator_lookup[index] = i;
-
- return;
- }
-}
-
-static void bta_hf_client_handle_cind_value(tBTA_HF_CLIENT_CB* client_cb,
- uint32_t index, uint32_t value) {
- APPL_TRACE_DEBUG("%s: index: %u value: %u", __func__, index, value);
-
- if (index >= BTA_HF_CLIENT_AT_INDICATOR_COUNT) {
- return;
- }
-
- if (service_index == index) {
- if (value == 0) {
- service_availability = false;
- } else {
- service_availability = true;
- }
- }
- if (client_cb->at_cb.indicator_lookup[index] == -1) {
- return;
- }
-
- /* get the real array index from lookup table */
- index = client_cb->at_cb.indicator_lookup[index];
-
- /* Ignore out of range values */
- if (value > bta_hf_client_indicators[index].max ||
- value < bta_hf_client_indicators[index].min) {
- return;
- }
-
- /* tBTA_HF_CLIENT_IND_TYPE match index in bta_hf_client_indicators */
- bta_hf_client_ind(client_cb, index, value);
-}
-
-static void bta_hf_client_handle_chld(tBTA_HF_CLIENT_CB* client_cb,
- uint32_t mask) {
- APPL_TRACE_DEBUG("%s: 0x%x", __func__, mask);
-
- client_cb->chld_features |= mask;
-}
-
-static void bta_hf_client_handle_bind_read_supported_ind(
- tBTA_HF_CLIENT_CB* client_cb, int indicator_id) {
- APPL_TRACE_DEBUG("%s: %d", __func__, indicator_id);
-
- client_cb->peer_hf_indicators.insert(indicator_id);
-}
-
-static void bta_hf_client_handle_bind_read_enabled_ind(
- tBTA_HF_CLIENT_CB* client_cb, int indicator_id, bool enable) {
- APPL_TRACE_DEBUG("%s: %d", __func__, indicator_id);
-
- if (enable) {
- client_cb->enabled_hf_indicators.insert(indicator_id);
- } else {
- client_cb->enabled_hf_indicators.erase(indicator_id);
- }
-}
-
-static void bta_hf_client_handle_ciev(tBTA_HF_CLIENT_CB* client_cb,
- uint32_t index, uint32_t value) {
- int8_t realind = -1;
-
- APPL_TRACE_DEBUG("%s: index: %u value: %u", __func__, index, value);
-
- if (index == 0 || index > BTA_HF_CLIENT_AT_INDICATOR_COUNT) {
- return;
- }
-
- if (service_index == index - 1) {
- service_availability = value == 0 ? false : true;
- }
-
- realind = client_cb->at_cb.indicator_lookup[index - 1];
-
- if (realind >= 0 && realind < BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT) {
- /* get the real in-array index from lookup table by index it comes at */
- /* if there is no bug it should automatically be correctly calculated */
- if (value > bta_hf_client_indicators[realind].max ||
- value < bta_hf_client_indicators[realind].min) {
- return;
- }
-
- /* update service availability on +ciev from AG. */
- if (service_index == (index - 1)) {
- if (value == 1) {
- service_availability = true;
- } else {
- service_availability = false;
- }
- }
-
- /* tBTA_HF_CLIENT_IND_TYPE match index in bta_hf_client_indicators */
- bta_hf_client_ind(client_cb, realind, value);
- }
-}
-
-static void bta_hf_client_handle_bcs(tBTA_HF_CLIENT_CB* client_cb,
- uint32_t codec) {
- APPL_TRACE_DEBUG("%s: codec: %u sco listen state: %d", __func__, codec,
- client_cb->sco_state);
- if (codec == BTM_SCO_CODEC_CVSD || codec == BTM_SCO_CODEC_MSBC) {
- client_cb->negotiated_codec = codec;
- bta_hf_client_send_at_bcs(client_cb, codec);
- } else {
- client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;
- bta_hf_client_send_at_bac(client_cb);
- }
-}
-
-static void bta_hf_client_handle_bsir(tBTA_HF_CLIENT_CB* client_cb,
- uint32_t provided) {
- APPL_TRACE_DEBUG("%s: %u", __func__, provided);
-
- bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_BSIR_EVT, provided);
-}
-
-static void bta_hf_client_handle_cmeerror(tBTA_HF_CLIENT_CB* client_cb,
- uint32_t code) {
- bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_CME, code);
-}
-
-static void bta_hf_client_handle_vgm(tBTA_HF_CLIENT_CB* client_cb,
- uint32_t value) {
- APPL_TRACE_DEBUG("%s: %lu", __func__, value);
-
- if (value <= BTA_HF_CLIENT_VGM_MAX) {
- bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_MIC_EVT, value);
- }
-}
-
-static void bta_hf_client_handle_vgs(tBTA_HF_CLIENT_CB* client_cb,
- uint32_t value) {
- APPL_TRACE_DEBUG("%s: %lu", __func__, value);
-
- if (value <= BTA_HF_CLIENT_VGS_MAX) {
- bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_SPK_EVT, value);
- }
-}
-
-static void bta_hf_client_handle_bvra(tBTA_HF_CLIENT_CB* client_cb,
- uint32_t value) {
- APPL_TRACE_DEBUG("%s: %lu", __func__, value);
-
- if (value > 1) {
- return;
- }
-
- bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_VOICE_REC_EVT, value);
-}
-
-static void bta_hf_client_handle_clip(tBTA_HF_CLIENT_CB* client_cb,
- char* numstr, uint32_t type) {
- APPL_TRACE_DEBUG("%s: %u %s", __func__, type, numstr);
-
- bta_hf_client_clip(client_cb, numstr);
-}
-
-static void bta_hf_client_handle_ccwa(tBTA_HF_CLIENT_CB* client_cb,
- char* numstr, uint32_t type) {
- APPL_TRACE_DEBUG("%s: %u %s", __func__, type, numstr);
-
- bta_hf_client_ccwa(client_cb, numstr);
-}
-
-static void bta_hf_client_handle_cops(tBTA_HF_CLIENT_CB* client_cb, char* opstr,
- uint32_t mode) {
- APPL_TRACE_DEBUG("%s: %u %s", __func__, mode, opstr);
-
- bta_hf_client_operator_name(client_cb, opstr);
-}
-
-static void bta_hf_client_handle_binp(tBTA_HF_CLIENT_CB* client_cb,
- char* numstr) {
- APPL_TRACE_DEBUG("%s: %s", __func__, numstr);
-
- bta_hf_client_binp(client_cb, numstr);
-}
-
-static void bta_hf_client_handle_clcc(tBTA_HF_CLIENT_CB* client_cb,
- uint16_t idx, uint16_t dir,
- uint16_t status, uint16_t mode,
- uint16_t mpty, char* numstr,
- uint16_t type) {
- APPL_TRACE_DEBUG("%s: idx: %u dir: %u status: %u mode: %u mpty: %u", __func__,
- idx, dir, status, mode, mpty);
-
- if (numstr) {
- APPL_TRACE_DEBUG("%s: number: %s type: %u", __func__, numstr, type);
- }
-
- bta_hf_client_clcc(client_cb, idx, dir, status, mpty, numstr);
-}
-
-static void bta_hf_client_handle_cnum(tBTA_HF_CLIENT_CB* client_cb,
- char* numstr, uint16_t type,
- uint16_t service) {
- APPL_TRACE_DEBUG("%s: number: %s type: %u service: %u", __func__, numstr,
- type, service);
-
- /* TODO: should number be modified according to type? */
- bta_hf_client_cnum(client_cb, numstr, service);
-}
-
-static void bta_hf_client_handle_btrh(tBTA_HF_CLIENT_CB* client_cb,
- uint16_t code) {
- APPL_TRACE_DEBUG("%s: %lu", __func__, code);
-
- bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_BTRH_EVT, code);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_cback_ind
- *
- * Description Send indicator callback event to application.
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_ind(tBTA_HF_CLIENT_CB* client_cb,
- tBTA_HF_CLIENT_IND_TYPE type, uint16_t value) {
- tBTA_HF_CLIENT evt;
-
- memset(&evt, 0, sizeof(evt));
-
- evt.ind.type = type;
- evt.ind.value = value;
-
- evt.ind.bd_addr = client_cb->peer_addr;
- bta_hf_client_app_callback(BTA_HF_CLIENT_IND_EVT, &evt);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_evt_val
- *
- * Description Send event to application.
- * This is a generic helper for events with common data.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_evt_val(tBTA_HF_CLIENT_CB* client_cb,
- tBTA_HF_CLIENT_EVT type, uint16_t value) {
- tBTA_HF_CLIENT evt;
-
- memset(&evt, 0, sizeof(evt));
-
- evt.val.bd_addr = client_cb->peer_addr;
- evt.val.value = value;
-
- bta_hf_client_app_callback(type, &evt);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_operator_name
- *
- * Description Send operator name event to application.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_operator_name(tBTA_HF_CLIENT_CB* client_cb, char* name) {
- tBTA_HF_CLIENT evt;
-
- memset(&evt, 0, sizeof(evt));
-
- strlcpy(evt.operator_name.name, name, BTA_HF_CLIENT_OPERATOR_NAME_LEN + 1);
- evt.operator_name.name[BTA_HF_CLIENT_OPERATOR_NAME_LEN] = '\0';
-
- evt.operator_name.bd_addr = client_cb->peer_addr;
- bta_hf_client_app_callback(BTA_HF_CLIENT_OPERATOR_NAME_EVT, &evt);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_clip
- *
- * Description Send CLIP event to application.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_clip(tBTA_HF_CLIENT_CB* client_cb, char* number) {
- tBTA_HF_CLIENT evt;
-
- memset(&evt, 0, sizeof(evt));
-
- strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
- evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
-
- evt.number.bd_addr = client_cb->peer_addr;
- bta_hf_client_app_callback(BTA_HF_CLIENT_CLIP_EVT, &evt);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_ccwa
- *
- * Description Send CLIP event to application.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_ccwa(tBTA_HF_CLIENT_CB* client_cb, char* number) {
- tBTA_HF_CLIENT evt;
-
- memset(&evt, 0, sizeof(evt));
-
- strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
- evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
-
- evt.number.bd_addr = client_cb->peer_addr;
- bta_hf_client_app_callback(BTA_HF_CLIENT_CCWA_EVT, &evt);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_at_result
- *
- * Description Send AT result event to application.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_at_result(tBTA_HF_CLIENT_CB* client_cb,
- tBTA_HF_CLIENT_AT_RESULT_TYPE type, uint16_t cme) {
- tBTA_HF_CLIENT evt;
-
- memset(&evt, 0, sizeof(evt));
-
- evt.result.type = type;
- evt.result.cme = cme;
-
- evt.result.bd_addr = client_cb->peer_addr;
- bta_hf_client_app_callback(BTA_HF_CLIENT_AT_RESULT_EVT, &evt);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_clcc
- *
- * Description Send clcc event to application.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_clcc(tBTA_HF_CLIENT_CB* client_cb, uint32_t idx,
- bool incoming, uint8_t status, bool mpty,
- char* number) {
- tBTA_HF_CLIENT evt;
-
- memset(&evt, 0, sizeof(evt));
-
- evt.clcc.idx = idx;
- evt.clcc.inc = incoming;
- evt.clcc.status = status;
- evt.clcc.mpty = mpty;
-
- if (number) {
- evt.clcc.number_present = true;
- strlcpy(evt.clcc.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
- evt.clcc.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
- }
-
- evt.clcc.bd_addr = client_cb->peer_addr;
- bta_hf_client_app_callback(BTA_HF_CLIENT_CLCC_EVT, &evt);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_cnum
- *
- * Description Send cnum event to application.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_cnum(tBTA_HF_CLIENT_CB* client_cb, char* number,
- uint16_t service) {
- tBTA_HF_CLIENT evt = {};
-
- evt.cnum.service = service;
- strlcpy(evt.cnum.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
- evt.cnum.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
-
- evt.cnum.bd_addr = client_cb->peer_addr;
- bta_hf_client_app_callback(BTA_HF_CLIENT_CNUM_EVT, &evt);
-}
-
-void bta_hf_client_unknown_response(tBTA_HF_CLIENT_CB* client_cb,
- const char* evt_buffer) {
- tBTA_HF_CLIENT evt = {};
-
- strlcpy(evt.unknown.event_string, evt_buffer,
- BTA_HF_CLIENT_UNKOWN_EVENT_LEN + 1);
- evt.unknown.event_string[BTA_HF_CLIENT_UNKOWN_EVENT_LEN] = '\0';
-
- evt.unknown.bd_addr = client_cb->peer_addr;
- bta_hf_client_app_callback(BTA_HF_CLIENT_UNKNOWN_EVT, &evt);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_binp
- *
- * Description Send BINP event to application.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_binp(tBTA_HF_CLIENT_CB* client_cb, char* number) {
- tBTA_HF_CLIENT evt;
-
- memset(&evt, 0, sizeof(evt));
-
- strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
- evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
-
- evt.number.bd_addr = client_cb->peer_addr;
- bta_hf_client_app_callback(BTA_HF_CLIENT_BINP_EVT, &evt);
-}
-
-/******************************************************************************
- *
- * COMMON AT EVENTS PARSING FUNCTIONS
- *
- ******************************************************************************/
-
-/* Check if prefix match and skip spaces if any */
-#define AT_CHECK_EVENT(buf, event) \
- do { \
- if (strncmp("\r\n" event, buf, sizeof("\r\n" event) - 1) != 0) return buf; \
- (buf) += sizeof("\r\n" event) - 1; \
- while (*(buf) == ' ') (buf)++; \
- } while (0)
-
-/* check for <cr><lf> and forward buffer if match */
-#define AT_CHECK_RN(buf) \
- do { \
- if (strncmp("\r\n", buf, sizeof("\r\n") - 1) != 0) { \
- APPL_TRACE_DEBUG("%s: missing end <cr><lf>", __func__); \
- return NULL; \
- } \
- (buf) += sizeof("\r\n") - 1; \
- } while (0)
-
-/* skip rest of AT string up to <cr> */
-#define AT_SKIP_REST(buf) \
- do { \
- while (*(buf) != '\r') (buf)++; \
- } while (0)
-
-static char* bta_hf_client_parse_ok(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "OK");
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_ok(client_cb);
-
- return buffer;
-}
-
-static char* bta_hf_client_parse_error(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "ERROR");
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_ERROR, 0);
-
- return buffer;
-}
-
-static char* bta_hf_client_parse_ring(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "RING");
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_ring(client_cb);
-
- return buffer;
-}
-
-/* generic uint32 parser */
-static char* bta_hf_client_parse_uint32(
- tBTA_HF_CLIENT_CB* client_cb, char* buffer,
- void (*handler_callback)(tBTA_HF_CLIENT_CB*, uint32_t)) {
- uint32_t value;
- int res;
- int offset;
-
- res = sscanf(buffer, "%u%n", &value, &offset);
- if (res < 1) {
- return NULL;
- }
-
- buffer += offset;
-
- AT_CHECK_RN(buffer);
-
- handler_callback(client_cb, value);
- return buffer;
-}
-
-static char* bta_hf_client_parse_brsf(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "+BRSF:");
-
- return bta_hf_client_parse_uint32(client_cb, buffer,
- bta_hf_client_handle_brsf);
-}
-
-static char* bta_hf_client_parse_cind_values(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- /* value and its position */
- uint16_t index = 0;
- uint32_t value = 0;
-
- int offset;
- int res;
-
- while ((res = sscanf(buffer, "%u%n", &value, &offset)) > 0) {
- /* decides if its valid index and value, if yes stores it */
- bta_hf_client_handle_cind_value(client_cb, index, value);
-
- buffer += offset;
-
- /* check if more values are present */
- if (*buffer != ',') {
- break;
- }
-
- index++;
- buffer++;
- }
-
- if (res > 0) {
- AT_CHECK_RN(buffer);
- return buffer;
- }
-
- return NULL;
-}
-
-static char* bta_hf_client_parse_cind_list(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- int offset = 0;
- char name[129];
- uint32_t min, max;
- uint32_t index = 0;
- int res;
-
- while ((res = sscanf(buffer, "(\"%128[^\"]\",(%u%*[-,]%u))%n", name, &min,
- &max, &offset)) > 2) {
- bta_hf_client_handle_cind_list_item(client_cb, name, min, max, index);
- if (offset == 0) {
- APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
- return NULL;
- }
-
- buffer += offset;
- index++;
-
- if (*buffer != ',') {
- break;
- }
-
- buffer++;
- }
-
- if (res > 2) {
- AT_CHECK_RN(buffer);
- return buffer;
- }
-
- return NULL;
-}
-
-static char* bta_hf_client_parse_cind(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "+CIND:");
-
- if (*buffer == '(') return bta_hf_client_parse_cind_list(client_cb, buffer);
-
- return bta_hf_client_parse_cind_values(client_cb, buffer);
-}
-
-static char* bta_hf_client_parse_chld(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "+CHLD:");
-
- if (*buffer != '(') {
- return NULL;
- }
-
- buffer++;
-
- while (*buffer != '\0') {
- if (strncmp("0", buffer, 1) == 0) {
- bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_REL);
- buffer++;
- } else if (strncmp("1x", buffer, 2) == 0) {
- bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_REL_X);
- buffer += 2;
- } else if (strncmp("1", buffer, 1) == 0) {
- bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_REL_ACC);
- buffer++;
- } else if (strncmp("2x", buffer, 2) == 0) {
- bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_PRIV_X);
- buffer += 2;
- } else if (strncmp("2", buffer, 1) == 0) {
- bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_HOLD_ACC);
- buffer++;
- } else if (strncmp("3", buffer, 1) == 0) {
- bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_MERGE);
- buffer++;
- } else if (strncmp("4", buffer, 1) == 0) {
- bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_MERGE_DETACH);
- buffer++;
- } else {
- return NULL;
- }
-
- if (*buffer == ',') {
- buffer++;
- continue;
- }
-
- if (*buffer == ')') {
- buffer++;
- break;
- }
-
- return NULL;
- }
-
- AT_CHECK_RN(buffer);
-
- return buffer;
-}
-
-static char* bta_hf_client_parse_bind(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "+BIND:");
-
- uint8_t mode = BTA_HF_CLIENT_BIND_PARSE_READ_ENABLED_IND;
-
- int idx = -1;
-
- while (*buffer != 0) {
- switch (*buffer) {
- case '(':
- mode = BTA_HF_CLIENT_BIND_PARSE_READ_SUPPOETED_IND;
- break;
- case ')':
- break;
- case '0':
- case '1':
- case '2':
- if (mode == BTA_HF_CLIENT_BIND_PARSE_READ_SUPPOETED_IND) {
- // +BIND: (id0, id1, ...)
- bta_hf_client_handle_bind_read_supported_ind(client_cb,
- (*buffer - '0'));
- } else if (idx == -1) {
- // +BIND: [id]...
- idx = *buffer - '0';
- } else {
- // +BIND: ...[status]
- bta_hf_client_handle_bind_read_enabled_ind(client_cb, idx,
- *buffer - '0');
- }
- break;
- default:
- break;
- }
- buffer++;
- }
-
- return buffer;
-}
-
-static char* bta_hf_client_parse_ciev(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- uint32_t index, value;
- int res;
- int offset = 0;
-
- AT_CHECK_EVENT(buffer, "+CIEV:");
-
- res = sscanf(buffer, "%u,%u%n", &index, &value, &offset);
- if (res < 2) {
- return NULL;
- }
-
- if (offset == 0) {
- APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
- return NULL;
- }
-
- buffer += offset;
-
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_ciev(client_cb, index, value);
- return buffer;
-}
-
-static char* bta_hf_client_parse_bcs(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "+BCS:");
-
- return bta_hf_client_parse_uint32(client_cb, buffer,
- bta_hf_client_handle_bcs);
-}
-
-static char* bta_hf_client_parse_bsir(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "+BSIR:");
-
- return bta_hf_client_parse_uint32(client_cb, buffer,
- bta_hf_client_handle_bsir);
-}
-
-static char* bta_hf_client_parse_cmeerror(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "+CME ERROR:");
-
- return bta_hf_client_parse_uint32(client_cb, buffer,
- bta_hf_client_handle_cmeerror);
-}
-
-static char* bta_hf_client_parse_vgm(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "+VGM:");
-
- return bta_hf_client_parse_uint32(client_cb, buffer,
- bta_hf_client_handle_vgm);
-}
-
-static char* bta_hf_client_parse_vgme(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "+VGM=");
-
- return bta_hf_client_parse_uint32(client_cb, buffer,
- bta_hf_client_handle_vgm);
-}
-
-static char* bta_hf_client_parse_vgs(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "+VGS:");
-
- return bta_hf_client_parse_uint32(client_cb, buffer,
- bta_hf_client_handle_vgs);
-}
-
-static char* bta_hf_client_parse_vgse(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "+VGS=");
-
- return bta_hf_client_parse_uint32(client_cb, buffer,
- bta_hf_client_handle_vgs);
-}
-
-static char* bta_hf_client_parse_bvra(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "+BVRA:");
-
- return bta_hf_client_parse_uint32(client_cb, buffer,
- bta_hf_client_handle_bvra);
-}
-
-static char* bta_hf_client_parse_clip(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- /* spec forces 32 chars, plus \0 here */
- char number[33];
- uint32_t type = 0;
- int res;
- int offset = 0;
-
- AT_CHECK_EVENT(buffer, "+CLIP:");
-
- /* there might be something more after %lu but HFP doesn't care */
- res = sscanf(buffer, "\"%32[^\"]\",%u%n", number, &type, &offset);
- if (res < 2) {
- return NULL;
- }
-
- if (offset == 0) {
- APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
- return NULL;
- }
-
- buffer += offset;
-
- AT_SKIP_REST(buffer);
-
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_clip(client_cb, number, type);
- return buffer;
-}
-
-/* in HFP context there is no difference between ccwa and clip */
-static char* bta_hf_client_parse_ccwa(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- /* ac to spec 32 chars max, plus \0 here */
- char number[33];
- uint32_t type = 0;
- int res;
- int offset = 0;
-
- AT_CHECK_EVENT(buffer, "+CCWA:");
-
- /* there might be something more after %lu but HFP doesn't care */
- res = sscanf(buffer, "\"%32[^\"]\",%u%n", number, &type, &offset);
- if (res < 2) {
- return NULL;
- }
-
- if (offset == 0) {
- APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
- return NULL;
- }
-
- buffer += offset;
-
- AT_SKIP_REST(buffer);
-
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_ccwa(client_cb, number, type);
- return buffer;
-}
-
-static char* bta_hf_client_parse_cops(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- uint8_t mode;
- /* spec forces 16 chars max, plus \0 here */
- char opstr[17];
- int res;
- int offset = 0;
-
- AT_CHECK_EVENT(buffer, "+COPS:");
-
- /* TODO: Not sure if operator string actually can contain escaped " char
- * inside */
- res = sscanf(buffer, "%hhi,0,\"%16[^\"]\"%n", &mode, opstr, &offset);
- if (res < 2) {
- return NULL;
- }
- /* Abort in case offset not set because of format error */
- if (offset == 0) {
- APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
- return NULL;
- }
-
- buffer += offset;
-
- AT_SKIP_REST(buffer);
-
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_cops(client_cb, opstr, mode);
- // check for OK Response in end
- AT_CHECK_EVENT(buffer, "OK");
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_ok(client_cb);
-
- return buffer;
-}
-
-static char* bta_hf_client_parse_binp(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- /* HFP only supports phone number as BINP data */
- /* phone number is 32 chars plus one for \0*/
- char numstr[33];
- int res;
- int offset = 0;
-
- AT_CHECK_EVENT(buffer, "+BINP:");
-
- res = sscanf(buffer, "\"%32[^\"]\"\r\n%n", numstr, &offset);
- if (res < 1) {
- return NULL;
- }
-
- /* Abort in case offset not set because of format error */
- if (offset == 0) {
- APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
- return NULL;
- }
-
- buffer += offset;
-
- /* some phones might sent type as well, just skip it */
- AT_SKIP_REST(buffer);
-
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_binp(client_cb, numstr);
-
- // check for OK response in end
- AT_CHECK_EVENT(buffer, "OK");
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_ok(client_cb);
-
- return buffer;
-}
-
-static char* bta_hf_client_parse_clcc(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- uint16_t idx, dir, status, mode, mpty;
- char numstr[33]; /* spec forces 32 chars, plus one for \0*/
- uint16_t type;
- int res;
- int offset = 0;
-
- AT_CHECK_EVENT(buffer, "+CLCC:");
-
- res = sscanf(buffer, "%hu,%hu,%hu,%hu,%hu%n", &idx, &dir, &status, &mode,
- &mpty, &offset);
- if (res < 5) {
- return NULL;
- }
-
- /* Abort in case offset not set because of format error */
- if (offset == 0) {
- APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
- return NULL;
- }
-
- buffer += offset;
- offset = 0;
-
- /* check optional part */
- if (*buffer == ',') {
- int res2 = sscanf(buffer, ",\"%32[^\"]\",%hu%n", numstr, &type, &offset);
- if (res2 < 0) return NULL;
-
- if (res2 == 0) {
- res2 = sscanf(buffer, ",\"\",%hu%n", &type, &offset);
- if (res2 < 0) return NULL;
-
- /* numstr is not matched in second attempt, correct this */
- res2++;
- numstr[0] = '\0';
- }
-
- if (res2 >= 2) {
- res += res2;
- /* Abort in case offset not set because of format error */
- if (offset == 0) {
- APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
- return NULL;
- }
-
- buffer += offset;
- }
- }
-
- /* Skip any remaing param,as they are not defined by BT HFP spec */
- AT_SKIP_REST(buffer);
- AT_CHECK_RN(buffer);
-
- if (res > 6) {
- /* we also have last two optional parameters */
- bta_hf_client_handle_clcc(client_cb, idx, dir, status, mode, mpty, numstr,
- type);
- } else {
- /* we didn't get the last two parameters */
- bta_hf_client_handle_clcc(client_cb, idx, dir, status, mode, mpty, NULL, 0);
- }
-
- // check for OK response in end
- AT_CHECK_EVENT(buffer, "OK");
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_ok(client_cb);
- return buffer;
-}
-
-static char* bta_hf_client_parse_cnum(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- char numstr[33]; /* spec forces 32 chars, plus one for \0*/
- uint16_t type;
- uint16_t service =
- 0; /* 0 in case this optional parameter is not being sent */
- int res;
- int offset = 0;
-
- AT_CHECK_EVENT(buffer, "+CNUM:");
-
- res = sscanf(buffer, ",\"%32[^\"]\",%hu,,%hu%n", numstr, &type, &service,
- &offset);
- if (res < 0) {
- return NULL;
- }
-
- if (res == 0) {
- res = sscanf(buffer, ",\"\",%hu,,%hu%n", &type, &service, &offset);
- if (res < 0) {
- return NULL;
- }
-
- /* numstr is not matched in second attempt, correct this */
- res++;
- numstr[0] = '\0';
- }
-
- if (res < 3) {
- return NULL;
- }
-
- /* Abort in case offset not set because of format error */
- if (offset == 0) {
- APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
- return NULL;
- }
-
- buffer += offset;
-
- AT_CHECK_RN(buffer);
-
- /* service is optional */
- if (res == 2) {
- bta_hf_client_handle_cnum(client_cb, numstr, type, service);
- return buffer;
- }
-
- if (service != 4 && service != 5) {
- return NULL;
- }
-
- bta_hf_client_handle_cnum(client_cb, numstr, type, service);
-
- // check for OK response in end
- AT_CHECK_EVENT(buffer, "OK");
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_ok(client_cb);
- return buffer;
-}
-
-static char* bta_hf_client_parse_btrh(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- uint16_t code = 0;
- int res;
- int offset;
-
- AT_CHECK_EVENT(buffer, "+BTRH:");
-
- res = sscanf(buffer, "%hu%n", &code, &offset);
- if (res < 1) {
- return NULL;
- }
-
- buffer += offset;
-
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_btrh(client_cb, code);
- return buffer;
-}
-
-static char* bta_hf_client_parse_busy(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "BUSY");
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_BUSY, 0);
-
- return buffer;
-}
-
-static char* bta_hf_client_parse_delayed(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "DELAYED");
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_DELAY, 0);
-
- return buffer;
-}
-
-static char* bta_hf_client_parse_no_carrier(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "NO CARRIER");
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_NO_CARRIER, 0);
-
- return buffer;
-}
-
-static char* bta_hf_client_parse_no_answer(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "NO ANSWER");
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_NO_ANSWER, 0);
-
- return buffer;
-}
-
-static char* bta_hf_client_parse_rejectlisted(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- AT_CHECK_EVENT(buffer, "REJECTLISTED");
- AT_CHECK_RN(buffer);
-
- bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_REJECTLISTED,
- 0);
-
- return buffer;
-}
-
-static char* bta_hf_client_skip_unknown(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- char* start;
- char* tmp;
-
- tmp = strstr(buffer, "\r\n");
- if (tmp == NULL) {
- return NULL;
- }
-
- buffer += 2;
- start = buffer;
-
- tmp = strstr(buffer, "\r\n");
- if (tmp == NULL) {
- return NULL;
- }
-
- buffer = tmp + 2;
-
- APPL_TRACE_DEBUG("%s: %.*s", __func__, buffer - start - 2, start);
-
- return buffer;
-}
-
-static char* bta_hf_client_process_unknown(tBTA_HF_CLIENT_CB* client_cb,
- char* buffer) {
- char* start = strstr(buffer, "\r\n");
- if (start == NULL) {
- return NULL;
- }
- start += sizeof("\r\n") - 1;
-
- char* end = strstr(start, "\r\n");
- if (end == NULL) {
- return NULL;
- }
-
- int evt_size = end - start + 1;
-
- char tmp_buf[BTA_HF_CLIENT_UNKOWN_EVENT_LEN];
- if (evt_size < BTA_HF_CLIENT_UNKOWN_EVENT_LEN) {
- strlcpy(tmp_buf, start, evt_size);
- bta_hf_client_unknown_response(client_cb, tmp_buf);
- AT_CHECK_RN(end);
- } else {
- APPL_TRACE_ERROR("%s: exceed event buffer size. (%d, %d)", __func__,
- evt_size, BTA_HF_CLIENT_UNKOWN_EVENT_LEN);
- }
-
- APPL_TRACE_DEBUG("%s: %s", __func__, buffer);
-
- return end;
-}
-
-/******************************************************************************
- * SUPPORTED EVENT MESSAGES
- ******************************************************************************/
-
-/* returned values are as follow:
- * != NULL && != buf : match and parsed ok
- * == NULL : match but parse failed
- * != NULL && == buf : no match
- */
-typedef char* (*tBTA_HF_CLIENT_PARSER_CALLBACK)(tBTA_HF_CLIENT_CB*, char*);
-
-static const tBTA_HF_CLIENT_PARSER_CALLBACK bta_hf_client_parser_cb[] = {
- bta_hf_client_parse_ok, bta_hf_client_parse_error,
- bta_hf_client_parse_ring, bta_hf_client_parse_brsf,
- bta_hf_client_parse_cind, bta_hf_client_parse_ciev,
- bta_hf_client_parse_chld, bta_hf_client_parse_bcs,
- bta_hf_client_parse_bsir, bta_hf_client_parse_cmeerror,
- bta_hf_client_parse_vgm, bta_hf_client_parse_vgme,
- bta_hf_client_parse_vgs, bta_hf_client_parse_vgse,
- bta_hf_client_parse_bvra, bta_hf_client_parse_clip,
- bta_hf_client_parse_ccwa, bta_hf_client_parse_cops,
- bta_hf_client_parse_binp, bta_hf_client_parse_clcc,
- bta_hf_client_parse_cnum, bta_hf_client_parse_btrh,
- bta_hf_client_parse_bind, bta_hf_client_parse_busy,
- bta_hf_client_parse_delayed, bta_hf_client_parse_no_carrier,
- bta_hf_client_parse_no_answer, bta_hf_client_parse_rejectlisted,
- bta_hf_client_process_unknown};
-
-/* calculate supported event list length */
-static const uint16_t bta_hf_client_parser_cb_count =
- sizeof(bta_hf_client_parser_cb) / sizeof(bta_hf_client_parser_cb[0]);
-
-#ifdef BTA_HF_CLIENT_AT_DUMP
-static void bta_hf_client_dump_at(tBTA_HF_CLIENT_CB* client_cb) {
- char dump[(4 * BTA_HF_CLIENT_AT_PARSER_MAX_LEN) + 1];
- char *p1, *p2;
-
- p1 = client_cb->at_cb.buf;
- p2 = dump;
-
- while (*p1 != '\0') {
- if (*p1 == '\r') {
- strlcpy(p2, "<cr>", 4);
- p2 += 4;
- } else if (*p1 == '\n') {
- strlcpy(p2, "<lf>", 4);
- p2 += 4;
- } else {
- *p2 = *p1;
- p2++;
- }
- p1++;
- }
-
- *p2 = '\0';
-
- APPL_TRACE_DEBUG("%s: %s", __func__, dump);
-}
-#endif
-
-static void bta_hf_client_at_parse_start(tBTA_HF_CLIENT_CB* client_cb) {
- char* buf = client_cb->at_cb.buf;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
-#ifdef BTA_HF_CLIENT_AT_DUMP
- bta_hf_client_dump_at(client_cb);
-#endif
-
- while (*buf != '\0') {
- int i;
- char* tmp = NULL;
-
- for (i = 0; i < bta_hf_client_parser_cb_count; i++) {
- tmp = bta_hf_client_parser_cb[i](client_cb, buf);
- if (tmp == NULL) {
- APPL_TRACE_ERROR("HFPCient: AT event/reply parsing failed, skipping");
- tmp = bta_hf_client_skip_unknown(client_cb, buf);
- break;
- }
-
- /* matched or unknown skipped, if unknown failed tmp is NULL so
- this is also handled */
- if (tmp != buf) {
- buf = tmp;
- break;
- }
- }
-
- /* could not skip unknown (received garbage?)... disconnect */
- if (tmp == NULL) {
- APPL_TRACE_ERROR(
- "HFPCient: could not skip unknown AT event, disconnecting");
- bta_hf_client_at_reset(client_cb);
-
- tBTA_HF_CLIENT_DATA msg = {};
- msg.hdr.layer_specific = client_cb->handle;
- bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
- return;
- }
-
- buf = tmp;
- }
-}
-
-static bool bta_hf_client_check_at_complete(tBTA_HF_CLIENT_CB* client_cb) {
- bool ret = false;
- tBTA_HF_CLIENT_AT_CB* at_cb = &client_cb->at_cb;
-
- if (at_cb->offset >= BTA_HF_CLIENT_AT_EVENT_MIN_LEN) {
- if (at_cb->buf[at_cb->offset - 2] == '\r' &&
- at_cb->buf[at_cb->offset - 1] == '\n') {
- ret = true;
- }
- }
-
- APPL_TRACE_DEBUG("%s: %d", __func__, ret);
-
- return ret;
-}
-
-static void bta_hf_client_at_clear_buf(tBTA_HF_CLIENT_CB* client_cb) {
- memset(client_cb->at_cb.buf, 0, sizeof(client_cb->at_cb.buf));
- client_cb->at_cb.offset = 0;
-}
-
-/******************************************************************************
- *
- * MAIN PARSING FUNCTION
- *
- *
- ******************************************************************************/
-void bta_hf_client_at_parse(tBTA_HF_CLIENT_CB* client_cb, char* buf,
- unsigned int len) {
- APPL_TRACE_DEBUG("%s: offset: %u len: %u", __func__, client_cb->at_cb.offset,
- len);
-
- if (len + client_cb->at_cb.offset > BTA_HF_CLIENT_AT_PARSER_MAX_LEN) {
- char tmp_buff[BTA_HF_CLIENT_AT_PARSER_MAX_LEN];
- unsigned int tmp = client_cb->at_cb.offset;
- unsigned int space_left =
- BTA_HF_CLIENT_AT_PARSER_MAX_LEN - client_cb->at_cb.offset;
-
- APPL_TRACE_DEBUG("%s: overrun, trying to recover", __func__);
-
- /* fill up parser buffer */
- memcpy(client_cb->at_cb.buf + client_cb->at_cb.offset, buf, space_left);
- len -= space_left;
- buf += space_left;
- client_cb->at_cb.offset += space_left;
-
- /* find end of last complete command before proceeding */
- while (!bta_hf_client_check_at_complete(client_cb)) {
- if (client_cb->at_cb.offset == 0) {
- APPL_TRACE_ERROR("HFPClient: AT parser buffer overrun, disconnecting");
-
- bta_hf_client_at_reset(client_cb);
-
- tBTA_HF_CLIENT_DATA msg = {};
- msg.hdr.layer_specific = client_cb->handle;
- bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
- return;
- }
-
- client_cb->at_cb.offset--;
- }
-
- /* cut buffer to complete AT event and keep cut data */
- tmp += space_left - client_cb->at_cb.offset;
- memcpy(tmp_buff, client_cb->at_cb.buf + client_cb->at_cb.offset, tmp);
- client_cb->at_cb.buf[client_cb->at_cb.offset] = '\0';
-
- /* parse */
- bta_hf_client_at_parse_start(client_cb);
- bta_hf_client_at_clear_buf(client_cb);
-
- /* recover cut data */
- memcpy(client_cb->at_cb.buf, tmp_buff, tmp);
- client_cb->at_cb.offset += tmp;
- }
-
- memcpy(client_cb->at_cb.buf + client_cb->at_cb.offset, buf, len);
- client_cb->at_cb.offset += len;
-
- /* If last event is complete, parsing can be started */
- if (bta_hf_client_check_at_complete(client_cb)) {
- bta_hf_client_at_parse_start(client_cb);
- bta_hf_client_at_clear_buf(client_cb);
- }
-}
-
-void bta_hf_client_send_at_brsf(tBTA_HF_CLIENT_CB* client_cb,
- tBTA_HF_CLIENT_FEAT features) {
- char buf[BTA_HF_CLIENT_AT_MAX_LEN];
- int at_len;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- at_len = snprintf(buf, sizeof(buf), "AT+BRSF=%u\r", features);
- if (at_len < 0) {
- APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
- return;
- }
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BRSF, buf, at_len);
-}
-
-void bta_hf_client_send_at_bac(tBTA_HF_CLIENT_CB* client_cb) {
- const char* buf;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- buf = "AT+BAC=1,2\r";
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BAC, buf, strlen(buf));
-}
-
-void bta_hf_client_send_at_bcs(tBTA_HF_CLIENT_CB* client_cb, uint32_t codec) {
- char buf[BTA_HF_CLIENT_AT_MAX_LEN];
- int at_len;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- at_len = snprintf(buf, sizeof(buf), "AT+BCS=%u\r", codec);
- if (at_len < 0) {
- APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
- return;
- }
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BCS, buf, at_len);
-}
-
-void bta_hf_client_send_at_cind(tBTA_HF_CLIENT_CB* client_cb, bool status) {
- const char* buf;
- tBTA_HF_CLIENT_AT_CMD cmd;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- if (status) {
- buf = "AT+CIND?\r";
- cmd = BTA_HF_CLIENT_AT_CIND_STATUS;
- } else {
- buf = "AT+CIND=?\r";
- cmd = BTA_HF_CLIENT_AT_CIND;
- }
-
- bta_hf_client_send_at(client_cb, cmd, buf, strlen(buf));
-}
-
-void bta_hf_client_send_at_cmer(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
- const char* buf;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- if (activate)
- buf = "AT+CMER=3,0,0,1\r";
- else
- buf = "AT+CMER=3,0,0,0\r";
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CMER, buf, strlen(buf));
-}
-
-void bta_hf_client_send_at_chld(tBTA_HF_CLIENT_CB* client_cb, char cmd,
- uint32_t idx) {
- char buf[BTA_HF_CLIENT_AT_MAX_LEN];
- int at_len;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- if (idx > 0)
- at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c%u\r", cmd, idx);
- else
- at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c\r", cmd);
-
- if (at_len < 0) {
- APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
- return;
- }
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CHLD, buf, at_len);
-}
-
-void bta_hf_client_send_at_bind(tBTA_HF_CLIENT_CB* client_cb, int step) {
- std::string buf;
- tBTA_HF_CLIENT_AT_CMD cmd = BTA_HF_CLIENT_AT_BIND_SET_IND;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- switch (step) {
- case 0: // List HF supported indicators
- // TODO: Add flags to determine enabled HF features
- buf = "AT+BIND=1,2\r";
- cmd = BTA_HF_CLIENT_AT_BIND_SET_IND;
- break;
- case 1: // Read AG supported indicators
- buf = "AT+BIND=?\r";
- cmd = BTA_HF_CLIENT_AT_BIND_READ_SUPPORTED_IND;
- break;
- case 2: // Read AG enabled/disabled status of indicators
- buf = "AT+BIND?\r";
- cmd = BTA_HF_CLIENT_AT_BIND_READ_ENABLED_IND;
- break;
- default:
- break;
- }
- bta_hf_client_send_at(client_cb, cmd, buf.c_str(), buf.size());
-}
-
-void bta_hf_client_send_at_biev(tBTA_HF_CLIENT_CB* client_cb, int indicator_id,
- int indicator_value) {
- char buf[32];
- tBTA_HF_CLIENT_AT_CMD cmd = BTA_HF_CLIENT_AT_BIEV;
-
- if ((client_cb->peer_features & BTA_HF_CLIENT_FEAT_HF_IND) == 0) {
- APPL_TRACE_ERROR("%s peer does not support HF Indicators", __func__);
- return;
- }
-
- if (client_cb->enabled_hf_indicators.count(indicator_id) <= 0) {
- APPL_TRACE_ERROR("%s HF indicators %d is disabled", __func__, indicator_id);
- return;
- }
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- int len = sprintf(buf, "AT+BIEV=%d,%d\r", indicator_id, indicator_value);
-
- bta_hf_client_send_at(client_cb, cmd, buf, len);
-}
-
-void bta_hf_client_send_at_clip(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
- const char* buf;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- if (activate)
- buf = "AT+CLIP=1\r";
- else
- buf = "AT+CLIP=0\r";
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CLIP, buf, strlen(buf));
-}
-
-void bta_hf_client_send_at_ccwa(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
- const char* buf;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- if (activate)
- buf = "AT+CCWA=1\r";
- else
- buf = "AT+CCWA=0\r";
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CCWA, buf, strlen(buf));
-}
-
-void bta_hf_client_send_at_cmee(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
- const char* buf;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- if (activate)
- buf = "AT+CMEE=1\r";
- else
- buf = "AT+CMEE=0\r";
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CMEE, buf, strlen(buf));
-}
-
-void bta_hf_client_send_at_cops(tBTA_HF_CLIENT_CB* client_cb, bool query) {
- const char* buf;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- if (query)
- buf = "AT+COPS?\r";
- else
- buf = "AT+COPS=3,0\r";
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_COPS, buf, strlen(buf));
-}
-
-void bta_hf_client_send_at_clcc(tBTA_HF_CLIENT_CB* client_cb) {
- const char* buf;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- buf = "AT+CLCC\r";
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CLCC, buf, strlen(buf));
-}
-
-void bta_hf_client_send_at_bvra(tBTA_HF_CLIENT_CB* client_cb, bool enable) {
- const char* buf;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- if (enable)
- buf = "AT+BVRA=1\r";
- else
- buf = "AT+BVRA=0\r";
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BVRA, buf, strlen(buf));
-}
-
-void bta_hf_client_send_at_vgs(tBTA_HF_CLIENT_CB* client_cb, uint32_t volume) {
- char buf[BTA_HF_CLIENT_AT_MAX_LEN];
- int at_len;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- at_len = snprintf(buf, sizeof(buf), "AT+VGS=%u\r", volume);
- if (at_len < 0) {
- APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
- return;
- }
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VGS, buf, at_len);
-}
-
-void bta_hf_client_send_at_vgm(tBTA_HF_CLIENT_CB* client_cb, uint32_t volume) {
- char buf[BTA_HF_CLIENT_AT_MAX_LEN];
- int at_len;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- at_len = snprintf(buf, sizeof(buf), "AT+VGM=%u\r", volume);
- if (at_len < 0) {
- APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
- return;
- }
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VGM, buf, at_len);
-}
-
-void bta_hf_client_send_at_atd(tBTA_HF_CLIENT_CB* client_cb, char* number,
- uint32_t memory) {
- char buf[BTA_HF_CLIENT_AT_MAX_LEN];
- int at_len;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- if (number[0] != '\0') {
- at_len = snprintf(buf, sizeof(buf), "ATD%s;\r", number);
- } else {
- at_len = snprintf(buf, sizeof(buf), "ATD>%u;\r", memory);
- }
-
- if (at_len < 0) {
- APPL_TRACE_ERROR("%s: error preparing ATD command", __func__);
- return;
- }
-
- at_len = MIN((size_t)at_len, sizeof(buf));
-
- if (at_len < 0) {
- APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
- return;
- }
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_ATD, buf, at_len);
-}
-
-void bta_hf_client_send_at_bldn(tBTA_HF_CLIENT_CB* client_cb) {
- const char* buf;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- buf = "AT+BLDN\r";
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BLDN, buf, strlen(buf));
-}
-
-void bta_hf_client_send_at_ata(tBTA_HF_CLIENT_CB* client_cb) {
- const char* buf;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- buf = "ATA\r";
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_ATA, buf, strlen(buf));
-}
-
-void bta_hf_client_send_at_chup(tBTA_HF_CLIENT_CB* client_cb) {
- const char* buf;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- buf = "AT+CHUP\r";
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CHUP, buf, strlen(buf));
-}
-
-void bta_hf_client_send_at_btrh(tBTA_HF_CLIENT_CB* client_cb, bool query,
- uint32_t val) {
- char buf[BTA_HF_CLIENT_AT_MAX_LEN];
- int at_len;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- if (query) {
- at_len = snprintf(buf, sizeof(buf), "AT+BTRH?\r");
- } else {
- at_len = snprintf(buf, sizeof(buf), "AT+BTRH=%u\r", val);
- }
-
- if (at_len < 0) {
- APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
- return;
- }
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BTRH, buf, at_len);
-}
-
-void bta_hf_client_send_at_vts(tBTA_HF_CLIENT_CB* client_cb, char code) {
- char buf[BTA_HF_CLIENT_AT_MAX_LEN];
- int at_len;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- at_len = snprintf(buf, sizeof(buf), "AT+VTS=%c\r", code);
-
- if (at_len < 0) {
- APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
- return;
- }
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VTS, buf, at_len);
-}
-
-void bta_hf_client_send_at_bcc(tBTA_HF_CLIENT_CB* client_cb) {
- const char* buf;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- buf = "AT+BCC\r";
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BCC, buf, strlen(buf));
-}
-
-void bta_hf_client_send_at_cnum(tBTA_HF_CLIENT_CB* client_cb) {
- const char* buf;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- buf = "AT+CNUM\r";
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CNUM, buf, strlen(buf));
-}
-
-void bta_hf_client_send_at_nrec(tBTA_HF_CLIENT_CB* client_cb) {
- const char* buf;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- if (!(client_cb->peer_features & BTA_HF_CLIENT_PEER_FEAT_ECNR)) {
- APPL_TRACE_ERROR("%s: Remote does not support NREC.", __func__);
- return;
- }
-
- buf = "AT+NREC=0\r";
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_NREC, buf, strlen(buf));
-}
-
-void bta_hf_client_send_at_binp(tBTA_HF_CLIENT_CB* client_cb, uint32_t action) {
- char buf[BTA_HF_CLIENT_AT_MAX_LEN];
- int at_len;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- at_len = snprintf(buf, sizeof(buf), "AT+BINP=%u\r", action);
-
- if (at_len < 0) {
- APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
- return;
- }
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BINP, buf, at_len);
-}
-
-void bta_hf_client_send_at_bia(tBTA_HF_CLIENT_CB* client_cb) {
- char buf[BTA_HF_CLIENT_AT_MAX_LEN];
- int at_len;
- int i;
-
- APPL_TRACE_DEBUG("%s", __func__);
- if (client_cb->peer_version < HFP_VERSION_1_6) {
- APPL_TRACE_DEBUG("Remote does not Support AT+BIA");
- return;
- }
-
- at_len = snprintf(buf, sizeof(buf), "AT+BIA=");
-
- for (i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++) {
- int sup = client_cb->at_cb.indicator_lookup[i] == -1 ? 0 : 1;
-
-/* If this value matches the position of SIGNAL in the indicators array,
- * then hardcode disable signal strength indicators.
- * indicator_lookup[i] points to the position in the bta_hf_client_indicators
- * array defined at the top of this file */
-#ifdef BTA_HF_CLIENT_INDICATOR_SIGNAL_POS
- if (client_cb->at_cb.indicator_lookup[i] ==
- BTA_HF_CLIENT_INDICATOR_SIGNAL_POS) {
- sup = 0;
- }
-#endif
-
- at_len += snprintf(buf + at_len, sizeof(buf) - at_len, "%u,", sup);
- }
-
- buf[at_len - 1] = '\r';
-
- if (at_len < 0) {
- APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
- return;
- }
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BIA, buf, at_len);
-}
-
-void bta_hf_client_send_at_vendor_specific_cmd(tBTA_HF_CLIENT_CB* client_cb,
- const char* str) {
- char buf[BTA_HF_CLIENT_AT_MAX_LEN];
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- int at_len = snprintf(buf, sizeof(buf), "AT%s", str);
-
- if (at_len < 1) {
- APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
- return;
- }
-
- buf[at_len - 1] = '\r';
-
- bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VENDOR_SPECIFIC, buf,
- at_len);
-}
-
-void bta_hf_client_at_init(tBTA_HF_CLIENT_CB* client_cb) {
- alarm_free(client_cb->at_cb.resp_timer);
- alarm_free(client_cb->at_cb.hold_timer);
- memset(&(client_cb->at_cb), 0, sizeof(tBTA_HF_CLIENT_AT_CB));
- client_cb->at_cb.resp_timer = alarm_new("bta_hf_client.scb_at_resp_timer");
- client_cb->at_cb.hold_timer = alarm_new("bta_hf_client.scb_at_hold_timer");
- bta_hf_client_at_reset(client_cb);
-}
-
-void bta_hf_client_at_reset(tBTA_HF_CLIENT_CB* client_cb) {
- int i;
-
- bta_hf_client_stop_at_resp_timer(client_cb);
- bta_hf_client_stop_at_hold_timer(client_cb);
-
- bta_hf_client_clear_queued_at(client_cb);
-
- bta_hf_client_at_clear_buf(client_cb);
-
- for (i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++) {
- client_cb->at_cb.indicator_lookup[i] = -1;
- }
-
- client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
-}
-
-void bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA* p_data) {
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (!client_cb) {
- APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- tBTA_HF_CLIENT_DATA_VAL* p_val = (tBTA_HF_CLIENT_DATA_VAL*)p_data;
- char buf[BTA_HF_CLIENT_AT_MAX_LEN];
-
- APPL_TRACE_DEBUG("%s: at cmd: %d", __func__, p_val->uint8_val);
- switch (p_val->uint8_val) {
- case BTA_HF_CLIENT_AT_CMD_VTS:
- bta_hf_client_send_at_vts(client_cb, (char)p_val->uint32_val1);
- break;
- case BTA_HF_CLIENT_AT_CMD_BTRH:
- bta_hf_client_send_at_btrh(client_cb, false, p_val->uint32_val1);
- break;
- case BTA_HF_CLIENT_AT_CMD_CHUP:
- bta_hf_client_send_at_chup(client_cb);
- break;
- case BTA_HF_CLIENT_AT_CMD_CHLD:
- /* expects ascii code for command */
- bta_hf_client_send_at_chld(client_cb, '0' + p_val->uint32_val1,
- p_val->uint32_val2);
- break;
- case BTA_HF_CLIENT_AT_CMD_BIEV:
- /* expects ascii code for command */
- bta_hf_client_send_at_biev(client_cb, p_val->uint32_val1,
- p_val->uint32_val2);
- break;
- case BTA_HF_CLIENT_AT_CMD_BCC:
- bta_hf_client_send_at_bcc(client_cb);
- break;
- case BTA_HF_CLIENT_AT_CMD_CNUM:
- bta_hf_client_send_at_cnum(client_cb);
- break;
- case BTA_HF_CLIENT_AT_CMD_ATA:
- bta_hf_client_send_at_ata(client_cb);
- break;
- case BTA_HF_CLIENT_AT_CMD_COPS:
- bta_hf_client_send_at_cops(client_cb, true);
- break;
- case BTA_HF_CLIENT_AT_CMD_ATD:
- bta_hf_client_send_at_atd(client_cb, p_val->str, p_val->uint32_val1);
- break;
- case BTA_HF_CLIENT_AT_CMD_VGM:
- bta_hf_client_send_at_vgm(client_cb, p_val->uint32_val1);
- break;
- case BTA_HF_CLIENT_AT_CMD_VGS:
- bta_hf_client_send_at_vgs(client_cb, p_val->uint32_val1);
- break;
- case BTA_HF_CLIENT_AT_CMD_BVRA:
- bta_hf_client_send_at_bvra(client_cb,
- p_val->uint32_val1 == 0 ? false : true);
- break;
- case BTA_HF_CLIENT_AT_CMD_CLCC:
- bta_hf_client_send_at_clcc(client_cb);
- break;
- case BTA_HF_CLIENT_AT_CMD_BINP:
- bta_hf_client_send_at_binp(client_cb, p_val->uint32_val1);
- break;
- case BTA_HF_CLIENT_AT_CMD_BLDN:
- bta_hf_client_send_at_bldn(client_cb);
- break;
- case BTA_HF_CLIENT_AT_CMD_NREC:
- bta_hf_client_send_at_nrec(client_cb);
- break;
- case BTA_HF_CLIENT_AT_CMD_VENDOR_SPECIFIC_CMD:
- bta_hf_client_send_at_vendor_specific_cmd(client_cb, p_val->str);
- break;
- default:
- APPL_TRACE_ERROR("Default case");
- snprintf(buf, BTA_HF_CLIENT_AT_MAX_LEN,
- "Cmd %d 1st arg %u 2nd arg %u string arg %s", p_val->uint8_val,
- p_val->uint32_val1, p_val->uint32_val2, p_val->str);
- APPL_TRACE_ERROR("%s: AT buffer: %s ", __func__, buf);
- break;
- }
-}
diff --git a/bta/hf_client/bta_hf_client_at.h b/bta/hf_client/bta_hf_client_at.h
deleted file mode 100644
index 11a0d0b..0000000
--- a/bta/hf_client/bta_hf_client_at.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/******************************************************************************
- *
- * Copyright (c) 2014 The Android Open Source Project
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/*****************************************************************************
- * Data types
- ****************************************************************************/
-
-#include <cstdint>
-#include "osi/include/alarm.h"
-
-/* ASCII character string of arguments to the AT command */
-#define BTA_HF_CLIENT_AT_MAX_LEN 512
-
-typedef uint8_t tBTA_HF_CLIENT_AT_CMD;
-
-/* Maximum combined buffer for received AT events string */
-#define BTA_HF_CLIENT_AT_PARSER_MAX_LEN 4096
-
-/* This structure holds prepared AT command queued for sending */
-struct queued_at_cmd {
- tBTA_HF_CLIENT_AT_CMD cmd;
- char buf[BTA_HF_CLIENT_AT_MAX_LEN];
- uint16_t buf_len;
- struct queued_at_cmd* next;
-};
-typedef struct queued_at_cmd tBTA_HF_CLIENT_AT_QCMD;
-
-/* Maximum number of indicators */
-#define BTA_HF_CLIENT_AT_INDICATOR_COUNT 20
-
-/* AT command parsing control block */
-typedef struct {
- char buf[BTA_HF_CLIENT_AT_PARSER_MAX_LEN +
- 1]; /* extra byte to always have \0 at the end */
- unsigned int offset;
- tBTA_HF_CLIENT_AT_CMD current_cmd;
- tBTA_HF_CLIENT_AT_QCMD* queued_cmd;
- alarm_t* resp_timer; /* AT response timer */
- alarm_t* hold_timer; /* AT hold timer */
-
- /* CIND: lookup table to store the sequence of incoming indicators and their
- values
- so when their values come later, we know which value in sequence match
- certain indicator */
- int indicator_lookup[BTA_HF_CLIENT_AT_INDICATOR_COUNT];
-
-} tBTA_HF_CLIENT_AT_CB;
diff --git a/bta/hf_client/bta_hf_client_int.h b/bta/hf_client/bta_hf_client_int.h
deleted file mode 100755
index 3c13e6c..0000000
--- a/bta/hf_client/bta_hf_client_int.h
+++ /dev/null
@@ -1,352 +0,0 @@
-/******************************************************************************
- *
- * Copyright (c) 2014 The Android Open Source Project
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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 <unordered_set>
-
-#include "bta/hf_client/bta_hf_client_at.h"
-#include "bta/include/bta_hf_client_api.h"
-#include "bta/sys/bta_sys.h"
-#include "osi/include/alarm.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/bt_types.h"
-#include "types/raw_address.h"
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-
-/* RFCOMM MTU SIZE */
-#define BTA_HF_CLIENT_MTU 256
-
-/* profile role for connection */
-#define BTA_HF_CLIENT_ACP 0 /* accepted connection */
-#define BTA_HF_CLIENT_INT 1 /* initiating connection */
-
-/* Time (in milliseconds) to wait for retry in case of collision */
-#ifndef BTA_HF_CLIENT_COLLISION_TIMER_MS
-#define BTA_HF_CLIENT_COLLISION_TIMER_MS 2411
-#endif
-
-/* Maximum number of HF devices supported simultaneously */
-#define HF_CLIENT_MAX_DEVICES 10
-
-enum {
- /* these events are handled by the state machine */
- BTA_HF_CLIENT_API_OPEN_EVT = BTA_SYS_EVT_START(BTA_ID_HS),
- BTA_HF_CLIENT_API_CLOSE_EVT,
- BTA_HF_CLIENT_API_AUDIO_OPEN_EVT,
- BTA_HF_CLIENT_API_AUDIO_CLOSE_EVT,
- BTA_HF_CLIENT_RFC_OPEN_EVT,
- BTA_HF_CLIENT_RFC_CLOSE_EVT,
- BTA_HF_CLIENT_RFC_SRV_CLOSE_EVT,
- BTA_HF_CLIENT_RFC_DATA_EVT,
- BTA_HF_CLIENT_DISC_ACP_RES_EVT,
- BTA_HF_CLIENT_DISC_INT_RES_EVT,
- BTA_HF_CLIENT_DISC_OK_EVT,
- BTA_HF_CLIENT_DISC_FAIL_EVT,
- BTA_HF_CLIENT_SCO_OPEN_EVT,
- BTA_HF_CLIENT_SCO_CLOSE_EVT,
- BTA_HF_CLIENT_SEND_AT_CMD_EVT,
- BTA_HF_CLIENT_MAX_EVT,
-
- /* these events are handled outside of the state machine */
- BTA_HF_CLIENT_API_ENABLE_EVT,
- BTA_HF_CLIENT_API_DISABLE_EVT
-};
-
-/* AT Command enum */
-enum {
- BTA_HF_CLIENT_AT_NONE,
- BTA_HF_CLIENT_AT_BRSF,
- BTA_HF_CLIENT_AT_BAC,
- BTA_HF_CLIENT_AT_CIND,
- BTA_HF_CLIENT_AT_CIND_STATUS,
- BTA_HF_CLIENT_AT_CMER,
- BTA_HF_CLIENT_AT_CHLD,
- BTA_HF_CLIENT_AT_CMEE,
- BTA_HF_CLIENT_AT_BIA,
- BTA_HF_CLIENT_AT_CLIP,
- BTA_HF_CLIENT_AT_CCWA,
- BTA_HF_CLIENT_AT_COPS,
- BTA_HF_CLIENT_AT_CLCC,
- BTA_HF_CLIENT_AT_BVRA,
- BTA_HF_CLIENT_AT_VGS,
- BTA_HF_CLIENT_AT_VGM,
- BTA_HF_CLIENT_AT_ATD,
- BTA_HF_CLIENT_AT_BLDN,
- BTA_HF_CLIENT_AT_ATA,
- BTA_HF_CLIENT_AT_CHUP,
- BTA_HF_CLIENT_AT_BTRH,
- BTA_HF_CLIENT_AT_VTS,
- BTA_HF_CLIENT_AT_BCC,
- BTA_HF_CLIENT_AT_BCS,
- BTA_HF_CLIENT_AT_CNUM,
- BTA_HF_CLIENT_AT_NREC,
- BTA_HF_CLIENT_AT_BINP,
- BTA_HF_CLIENT_AT_BIND_SET_IND,
- BTA_HF_CLIENT_AT_BIND_READ_SUPPORTED_IND,
- BTA_HF_CLIENT_AT_BIND_READ_ENABLED_IND,
- BTA_HF_CLIENT_AT_BIEV,
- BTA_HF_CLIENT_AT_VENDOR_SPECIFIC,
-};
-
-/*****************************************************************************
- * Data types
- ****************************************************************************/
-/* data type for BTA_HF_CLIENT_API_OPEN_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- RawAddress bd_addr;
- uint16_t* handle;
-} tBTA_HF_CLIENT_API_OPEN;
-
-/* data type for BTA_HF_CLIENT_DISC_RESULT_EVT */
-typedef struct {
- BT_HDR_RIGID hdr;
- uint16_t status;
-} tBTA_HF_CLIENT_DISC_RESULT;
-
-/* data type for RFCOMM events */
-typedef struct {
- BT_HDR_RIGID hdr;
- uint16_t port_handle;
-} tBTA_HF_CLIENT_RFC;
-
-/* generic purpose data type for other events */
-typedef struct {
- BT_HDR_RIGID hdr;
- bool bool_val;
- uint8_t uint8_val;
- uint32_t uint32_val1;
- uint32_t uint32_val2;
- char str[BTA_HF_CLIENT_NUMBER_LEN + 1];
-} tBTA_HF_CLIENT_DATA_VAL;
-
-/* union of all event datatypes */
-typedef union {
- BT_HDR_RIGID hdr;
- tBTA_HF_CLIENT_API_OPEN api_open;
- tBTA_HF_CLIENT_DISC_RESULT disc_result;
- tBTA_HF_CLIENT_RFC rfc;
- tBTA_HF_CLIENT_DATA_VAL val;
-
-} tBTA_HF_CLIENT_DATA;
-
-/* First handle for the control block */
-#define BTA_HF_CLIENT_CB_FIRST_HANDLE 1
-
-/* sco states */
-enum {
- BTA_HF_CLIENT_SCO_SHUTDOWN_ST, /* no listening, no connection */
- BTA_HF_CLIENT_SCO_LISTEN_ST, /* listening */
- BTA_HF_CLIENT_SCO_OPENING_ST, /* connection opening */
- BTA_HF_CLIENT_SCO_OPEN_CL_ST, /* opening connection being closed */
- BTA_HF_CLIENT_SCO_OPEN_ST, /* open */
- BTA_HF_CLIENT_SCO_CLOSING_ST, /* closing */
- BTA_HF_CLIENT_SCO_CLOSE_OP_ST, /* closing sco being opened */
- BTA_HF_CLIENT_SCO_SHUTTING_ST /* sco shutting down */
-};
-
-/* type for HF control block */
-typedef struct {
- // Fields useful for particular control block.
- uint8_t handle; /* Handle of the control block to be
- used by upper layer */
- RawAddress peer_addr; /* peer bd address */
- tSDP_DISCOVERY_DB* p_disc_db; /* pointer to discovery database */
- uint16_t conn_handle; /* RFCOMM handle of connected service */
- tBTA_HF_CLIENT_PEER_FEAT peer_features; /* peer device features */
- tBTA_HF_CLIENT_CHLD_FEAT chld_features; /* call handling features */
- uint16_t peer_version; /* profile version of peer device */
- uint8_t peer_scn; /* peer scn */
- uint8_t role; /* initiator/acceptor role */
- uint16_t sco_idx; /* SCO handle */
- uint8_t sco_state; /* SCO state variable */
- bool sco_close_rfc; /* true if also close RFCOMM after SCO */
- tBTM_SCO_CODEC_TYPE negotiated_codec; /* negotiated codec */
- bool svc_conn; /* set to true when service level connection is up */
- bool send_at_reply; /* set to true to notify framework about AT results */
- tBTA_HF_CLIENT_AT_CB at_cb; /* AT Parser control block */
- uint8_t state; /* state machine state */
- bool is_allocated; /* if the control block is already allocated */
- alarm_t* collision_timer; /* Collision timer */
- std::unordered_set<int>
- peer_hf_indicators; /* peer supported hf indicator indices (HFP1.7) */
- std::unordered_set<int>
- enabled_hf_indicators; /* enabled hf indicator indices (HFP1.7) */
-} tBTA_HF_CLIENT_CB;
-
-typedef struct {
- // Common fields, should be taken out.
- uint32_t sdp_handle;
- uint8_t scn;
- tBTA_HF_CLIENT_CBACK* p_cback; /* application callback */
- tBTA_HF_CLIENT_FEAT features; /* features registered by application */
- uint16_t serv_handle; /* RFCOMM server handle */
- bool deregister; /* true if service shutting down */
-
- // Maximum number of control blocks supported by the BTA layer.
- tBTA_HF_CLIENT_CB cb[HF_CLIENT_MAX_DEVICES];
-} tBTA_HF_CLIENT_CB_ARR;
-
-extern tBTA_HF_CLIENT_CB_ARR bta_hf_client_cb_arr;
-
-/*****************************************************************************
- * Function prototypes
- ****************************************************************************/
-
-/* main functions */
-extern tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_handle(uint16_t handle);
-extern tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_bda(
- const RawAddress& bd_addr);
-extern tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_rfc_handle(uint16_t handle);
-extern tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_sco_handle(uint16_t handle);
-extern bool bta_hf_client_hdl_event(BT_HDR_RIGID* p_msg);
-extern void bta_hf_client_sm_execute(uint16_t event,
- tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB* client_cb, bool error);
-extern bool bta_hf_client_allocate_handle(const RawAddress& bd_addr,
- uint16_t* p_handle);
-extern void bta_hf_client_app_callback(uint16_t event, tBTA_HF_CLIENT* data);
-extern void bta_hf_client_collision_cback(tBTA_SYS_CONN_STATUS status,
- uint8_t id, uint8_t app_id,
- const RawAddress& peer_addr);
-extern void bta_hf_client_resume_open(tBTA_HF_CLIENT_CB* client_cb);
-extern tBTA_STATUS bta_hf_client_api_enable(tBTA_HF_CLIENT_CBACK* p_cback,
- tBTA_HF_CLIENT_FEAT features,
- const char* p_service_name);
-
-extern void bta_hf_client_api_disable(void);
-extern void bta_hf_client_dump_statistics(int fd);
-extern void bta_hf_client_cb_arr_init(void);
-
-/* SDP functions */
-extern bool bta_hf_client_add_record(char* p_service_name, uint8_t scn,
- tBTA_HF_CLIENT_FEAT features,
- uint32_t sdp_handle);
-extern void bta_hf_client_create_record(tBTA_HF_CLIENT_CB_ARR* client_cb,
- const char* p_data);
-extern void bta_hf_client_del_record(tBTA_HF_CLIENT_CB_ARR* client_cb);
-extern bool bta_hf_client_sdp_find_attr(tBTA_HF_CLIENT_CB* client_cb);
-extern void bta_hf_client_do_disc(tBTA_HF_CLIENT_CB* client_cb);
-extern void bta_hf_client_free_db(tBTA_HF_CLIENT_DATA* p_data);
-
-/* RFCOMM functions */
-extern void bta_hf_client_setup_port(uint16_t handle);
-extern void bta_hf_client_start_server();
-extern void bta_hf_client_close_server();
-extern void bta_hf_client_rfc_do_open(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_rfc_do_close(tBTA_HF_CLIENT_DATA* p_data);
-
-/* SCO functions */
-extern void bta_hf_client_sco_listen(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_sco_conn_open(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_sco_conn_close(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_sco_open(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_sco_close(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_sco_shutdown(tBTA_HF_CLIENT_CB* client_cb);
-extern void bta_hf_client_cback_sco(tBTA_HF_CLIENT_CB* client_cb,
- uint8_t event);
-
-/* AT command functions */
-extern void bta_hf_client_at_parse(tBTA_HF_CLIENT_CB* client_cb, char* buf,
- unsigned int len);
-extern void bta_hf_client_send_at_brsf(tBTA_HF_CLIENT_CB* client_cb,
- tBTA_HF_CLIENT_FEAT features);
-extern void bta_hf_client_send_at_bac(tBTA_HF_CLIENT_CB* client_cb);
-extern void bta_hf_client_send_at_cind(tBTA_HF_CLIENT_CB* client_cb,
- bool status);
-extern void bta_hf_client_send_at_cmer(tBTA_HF_CLIENT_CB* client_cb,
- bool activate);
-extern void bta_hf_client_send_at_chld(tBTA_HF_CLIENT_CB* client_cb, char cmd,
- uint32_t idx);
-extern void bta_hf_client_send_at_bind(tBTA_HF_CLIENT_CB* client_cb, int step);
-extern void bta_hf_client_send_at_biev(tBTA_HF_CLIENT_CB* client_cb, int ind_id,
- int value);
-extern void bta_hf_client_send_at_clip(tBTA_HF_CLIENT_CB* client_cb,
- bool activate);
-extern void bta_hf_client_send_at_ccwa(tBTA_HF_CLIENT_CB* client_cb,
- bool activate);
-extern void bta_hf_client_send_at_cmee(tBTA_HF_CLIENT_CB* client_cb,
- bool activate);
-extern void bta_hf_client_send_at_cops(tBTA_HF_CLIENT_CB* client_cb,
- bool query);
-extern void bta_hf_client_send_at_clcc(tBTA_HF_CLIENT_CB* client_cb);
-extern void bta_hf_client_send_at_bvra(tBTA_HF_CLIENT_CB* client_cb,
- bool enable);
-extern void bta_hf_client_send_at_vgs(tBTA_HF_CLIENT_CB* client_cb,
- uint32_t volume);
-extern void bta_hf_client_send_at_vgm(tBTA_HF_CLIENT_CB* client_cb,
- uint32_t volume);
-extern void bta_hf_client_send_at_atd(tBTA_HF_CLIENT_CB* client_cb,
- char* number, uint32_t memory);
-extern void bta_hf_client_send_at_bldn(tBTA_HF_CLIENT_CB* client_cb);
-extern void bta_hf_client_send_at_ata(tBTA_HF_CLIENT_CB* client_cb);
-extern void bta_hf_client_send_at_chup(tBTA_HF_CLIENT_CB* client_cb);
-extern void bta_hf_client_send_at_btrh(tBTA_HF_CLIENT_CB* client_cb, bool query,
- uint32_t val);
-extern void bta_hf_client_send_at_vts(tBTA_HF_CLIENT_CB* client_cb, char code);
-extern void bta_hf_client_send_at_bcc(tBTA_HF_CLIENT_CB* client_cb);
-extern void bta_hf_client_send_at_bcs(tBTA_HF_CLIENT_CB* client_cb,
- uint32_t codec);
-extern void bta_hf_client_send_at_cnum(tBTA_HF_CLIENT_CB* client_cb);
-extern void bta_hf_client_send_at_nrec(tBTA_HF_CLIENT_CB* client_cb);
-extern void bta_hf_client_send_at_binp(tBTA_HF_CLIENT_CB* client_cb,
- uint32_t action);
-extern void bta_hf_client_send_at_bia(tBTA_HF_CLIENT_CB* client_cb);
-
-/* AT API Functions */
-void bta_hf_client_at_init(tBTA_HF_CLIENT_CB* client_cb);
-void bta_hf_client_at_reset(tBTA_HF_CLIENT_CB* client_cb);
-extern void bta_hf_client_ind(tBTA_HF_CLIENT_CB* client_cb,
- tBTA_HF_CLIENT_IND_TYPE type, uint16_t value);
-extern void bta_hf_client_evt_val(tBTA_HF_CLIENT_CB* client_cb,
- tBTA_HF_CLIENT_EVT type, uint16_t value);
-extern void bta_hf_client_operator_name(tBTA_HF_CLIENT_CB* client_name,
- char* name);
-extern void bta_hf_client_clip(tBTA_HF_CLIENT_CB* client_cb, char* number);
-extern void bta_hf_client_ccwa(tBTA_HF_CLIENT_CB* client_cb, char* number);
-extern void bta_hf_client_at_result(tBTA_HF_CLIENT_CB* client_cb,
- tBTA_HF_CLIENT_AT_RESULT_TYPE type,
- uint16_t cme);
-extern void bta_hf_client_clcc(tBTA_HF_CLIENT_CB* client_cb, uint32_t idx,
- bool incoming, uint8_t status, bool mpty,
- char* number);
-extern void bta_hf_client_cnum(tBTA_HF_CLIENT_CB* client_cb, char* number,
- uint16_t service);
-extern void bta_hf_client_binp(tBTA_HF_CLIENT_CB* client_cb, char* number);
-
-/* Action functions */
-extern void bta_hf_client_start_close(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA* p_data);
-
-/* Commands handling functions */
-extern void bta_hf_client_dial(tBTA_HF_CLIENT_DATA* p_data);
-extern void bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA* p_data);
diff --git a/bta/hf_client/bta_hf_client_main.cc b/bta/hf_client/bta_hf_client_main.cc
deleted file mode 100644
index 441e324..0000000
--- a/bta/hf_client/bta_hf_client_main.cc
+++ /dev/null
@@ -1,968 +0,0 @@
-/******************************************************************************
- *
- * Copyright (c) 2016 The Android Open Source Project
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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 <cstdio>
-
-#include "bta/hf_client/bta_hf_client_int.h"
-#include "bta/include/utl.h"
-#include "osi/include/allocator.h"
-#include "osi/include/osi.h" // UNUSED_ATTR
-#include "stack/include/bt_hdr.h"
-#include "stack/include/btm_api.h"
-#include "types/raw_address.h"
-
-#include <base/logging.h>
-
-static const char* bta_hf_client_evt_str(uint16_t event);
-static const char* bta_hf_client_state_str(uint8_t state);
-void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle);
-
-/* state machine states */
-enum {
- BTA_HF_CLIENT_INIT_ST,
- BTA_HF_CLIENT_OPENING_ST,
- BTA_HF_CLIENT_OPEN_ST,
- BTA_HF_CLIENT_CLOSING_ST
-};
-
-/* state machine action enumeration list */
-enum {
- BTA_HF_CLIENT_RFC_DO_CLOSE,
- BTA_HF_CLIENT_START_CLOSE,
- BTA_HF_CLIENT_START_OPEN,
- BTA_HF_CLIENT_RFC_ACP_OPEN,
- BTA_HF_CLIENT_SCO_LISTEN,
- BTA_HF_CLIENT_SCO_CONN_OPEN,
- BTA_HF_CLIENT_SCO_CONN_CLOSE,
- BTA_HF_CLIENT_SCO_OPEN,
- BTA_HF_CLIENT_SCO_CLOSE,
- BTA_HF_CLIENT_FREE_DB,
- BTA_HF_CLIENT_OPEN_FAIL,
- BTA_HF_CLIENT_RFC_OPEN,
- BTA_HF_CLIENT_RFC_FAIL,
- BTA_HF_CLIENT_DISC_INT_RES,
- BTA_HF_CLIENT_RFC_DO_OPEN,
- BTA_HF_CLIENT_DISC_FAIL,
- BTA_HF_CLIENT_RFC_CLOSE,
- BTA_HF_CLIENT_RFC_DATA,
- BTA_HF_CLIENT_DISC_ACP_RES,
- BTA_HF_CLIENT_SVC_CONN_OPEN,
- BTA_HF_CLIENT_SEND_AT_CMD,
- BTA_HF_CLIENT_NUM_ACTIONS,
-};
-
-#define BTA_HF_CLIENT_IGNORE BTA_HF_CLIENT_NUM_ACTIONS
-
-/* type for action functions */
-typedef void (*tBTA_HF_CLIENT_ACTION)(tBTA_HF_CLIENT_DATA* p_data);
-
-/* action functions table, indexed with action enum */
-const tBTA_HF_CLIENT_ACTION bta_hf_client_action[] = {
- /* BTA_HF_CLIENT_RFC_DO_CLOSE */ bta_hf_client_rfc_do_close,
- /* BTA_HF_CLIENT_START_CLOSE */ bta_hf_client_start_close,
- /* BTA_HF_CLIENT_START_OPEN */ bta_hf_client_start_open,
- /* BTA_HF_CLIENT_RFC_ACP_OPEN */ bta_hf_client_rfc_acp_open,
- /* BTA_HF_CLIENT_SCO_LISTEN */ NULL,
- /* BTA_HF_CLIENT_SCO_CONN_OPEN */ bta_hf_client_sco_conn_open,
- /* BTA_HF_CLIENT_SCO_CONN_CLOSE*/ bta_hf_client_sco_conn_close,
- /* BTA_HF_CLIENT_SCO_OPEN */ bta_hf_client_sco_open,
- /* BTA_HF_CLIENT_SCO_CLOSE */ bta_hf_client_sco_close,
- /* BTA_HF_CLIENT_FREE_DB */ bta_hf_client_free_db,
- /* BTA_HF_CLIENT_OPEN_FAIL */ bta_hf_client_open_fail,
- /* BTA_HF_CLIENT_RFC_OPEN */ bta_hf_client_rfc_open,
- /* BTA_HF_CLIENT_RFC_FAIL */ bta_hf_client_rfc_fail,
- /* BTA_HF_CLIENT_DISC_INT_RES */ bta_hf_client_disc_int_res,
- /* BTA_HF_CLIENT_RFC_DO_OPEN */ bta_hf_client_rfc_do_open,
- /* BTA_HF_CLIENT_DISC_FAIL */ bta_hf_client_disc_fail,
- /* BTA_HF_CLIENT_RFC_CLOSE */ bta_hf_client_rfc_close,
- /* BTA_HF_CLIENT_RFC_DATA */ bta_hf_client_rfc_data,
- /* BTA_HF_CLIENT_DISC_ACP_RES */ bta_hf_client_disc_acp_res,
- /* BTA_HF_CLIENT_SVC_CONN_OPEN */ bta_hf_client_svc_conn_open,
- /* BTA_HF_CLIENT_SEND_AT_CMD */ bta_hf_client_send_at_cmd,
-};
-
-/* state table information */
-#define BTA_HF_CLIENT_ACTIONS 2 /* number of actions */
-#define BTA_HF_CLIENT_NEXT_STATE 2 /* position of next state */
-#define BTA_HF_CLIENT_NUM_COLS 3 /* number of columns in state tables */
-
-/* state table for init state */
-const uint8_t bta_hf_client_st_init[][BTA_HF_CLIENT_NUM_COLS] = {
- /* Event Action 1 Action 2
- Next state */
- /* API_OPEN_EVT */ {BTA_HF_CLIENT_START_OPEN, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPENING_ST},
- /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_ACP_OPEN, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPEN_ST},
- /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
-};
-
-/* state table for opening state */
-const uint8_t bta_hf_client_st_opening[][BTA_HF_CLIENT_NUM_COLS] = {
- /* Event Action 1 Action 2
- Next state */
- /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPENING_ST},
- /* API_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_DO_CLOSE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_CLOSING_ST},
- /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPENING_ST},
- /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPENING_ST},
- /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_OPEN, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPEN_ST},
- /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_FAIL, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPENING_ST},
- /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPENING_ST},
- /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPENING_ST},
- /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_DISC_INT_RES, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPENING_ST},
- /* DISC_OK_EVT */ {BTA_HF_CLIENT_RFC_DO_OPEN, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPENING_ST},
- /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_DISC_FAIL, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPENING_ST},
- /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPENING_ST},
- /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPENING_ST},
-};
-
-/* state table for open state */
-const uint8_t bta_hf_client_st_open[][BTA_HF_CLIENT_NUM_COLS] = {
- /* Event Action 1 Action 2
- Next state */
- /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPEN_ST},
- /* API_CLOSE_EVT */ {BTA_HF_CLIENT_START_CLOSE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_CLOSING_ST},
- /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_OPEN, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPEN_ST},
- /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CLOSE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPEN_ST},
- /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPEN_ST},
- /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPEN_ST},
- /* RFC_DATA_EVT */ {BTA_HF_CLIENT_RFC_DATA, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPEN_ST},
- /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_DISC_ACP_RES, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPEN_ST},
- /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPEN_ST},
- /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPEN_ST},
- /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPEN_ST},
- /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_CONN_OPEN, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPEN_ST},
- /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CONN_CLOSE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPEN_ST},
- /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_SEND_AT_CMD, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_OPEN_ST},
-};
-
-/* state table for closing state */
-const uint8_t bta_hf_client_st_closing[][BTA_HF_CLIENT_NUM_COLS] = {
- /* Event Action 1 Action 2
- Next state */
- /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_CLOSING_ST},
- /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_CLOSING_ST},
- /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_CLOSING_ST},
- /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_CLOSING_ST},
- /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_CLOSING_ST},
- /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_CLOSING_ST},
- /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_CLOSING_ST},
- /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_CLOSING_ST},
- /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_INIT_ST},
- /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_CLOSING_ST},
- /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_CLOSING_ST},
- /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_CLOSING_ST},
- /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_CLOSING_ST},
- /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
- BTA_HF_CLIENT_CLOSING_ST},
-};
-
-/* type for state table */
-typedef const uint8_t (*tBTA_HF_CLIENT_ST_TBL)[BTA_HF_CLIENT_NUM_COLS];
-
-/* state table */
-const tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] = {
- bta_hf_client_st_init, bta_hf_client_st_opening, bta_hf_client_st_open,
- bta_hf_client_st_closing};
-
-/* HF Client control block */
-tBTA_HF_CLIENT_CB_ARR bta_hf_client_cb_arr;
-
-/* Event handler for the state machine */
-static const tBTA_SYS_REG bta_hf_client_reg = {bta_hf_client_hdl_event,
- BTA_HfClientDisable};
-
-/*******************************************************************************
- *
- * Function bta_hf_client_cb_arr_init
- *
- * Description Initialize entire control block array set
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_cb_arr_init() {
- memset(&bta_hf_client_cb_arr, 0, sizeof(tBTA_HF_CLIENT_CB_ARR));
-
- // reset the handles and make the CBs non-allocated
- for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
- // Allocate the handles in increasing order of indices
- bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]), i);
- bta_hf_client_cb_arr.cb[i].handle = BTA_HF_CLIENT_CB_FIRST_HANDLE + i;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_cb_init
- *
- * Description Initialize an HF_Client service control block. Assign the
- * handle to cb->handle.
- *
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle) {
- APPL_TRACE_DEBUG("%s", __func__);
-
- // Free any memory we need to explicity release
- alarm_free(client_cb->collision_timer);
-
- // release unique pointers
- client_cb->enabled_hf_indicators.clear();
- client_cb->peer_hf_indicators.clear();
-
- // Memset the rest of the block
- // memset(client_cb, 0, sizeof(tBTA_HF_CLIENT_CB));
- *client_cb = {};
-
- // Re allocate any variables required
- client_cb->collision_timer = alarm_new("bta_hf_client.scb_collision_timer");
- client_cb->handle = handle;
- client_cb->sco_idx = BTM_INVALID_SCO_INDEX;
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_resume_open
- *
- * Description Resume opening process.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_resume_open(tBTA_HF_CLIENT_CB* client_cb) {
- APPL_TRACE_DEBUG("%s", __func__);
-
- /* resume opening process. */
- if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
- client_cb->state = BTA_HF_CLIENT_OPENING_ST;
- tBTA_HF_CLIENT_DATA msg;
- msg.hdr.layer_specific = client_cb->handle;
- msg.api_open.bd_addr = client_cb->peer_addr;
- bta_hf_client_start_open(&msg);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_collision_timer_cback
- *
- * Description HF Client connection collision timer callback
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_hf_client_collision_timer_cback(void* data) {
- APPL_TRACE_DEBUG("%s", __func__);
- tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data;
-
- /* If the peer haven't opened connection, restart opening process */
- bta_hf_client_resume_open(client_cb);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_collision_cback
- *
- * Description Get notified about collision.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status,
- uint8_t id, UNUSED_ATTR uint8_t app_id,
- const RawAddress& peer_addr) {
- tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_bda(peer_addr);
- if (client_cb != NULL && client_cb->state == BTA_HF_CLIENT_OPENING_ST) {
- if (id == BTA_ID_SYS) /* ACL collision */
- {
- APPL_TRACE_WARNING("HF Client found collision (ACL) ...");
- } else if (id == BTA_ID_HS) /* RFCOMM collision */
- {
- APPL_TRACE_WARNING("HF Client found collision (RFCOMM) ...");
- } else {
- APPL_TRACE_WARNING("HF Client found collision (\?\?\?) ...");
- }
-
- client_cb->state = BTA_HF_CLIENT_INIT_ST;
-
- /* Cancel SDP if it had been started. */
- if (client_cb->p_disc_db) {
- (void)SDP_CancelServiceSearch(client_cb->p_disc_db);
- osi_free_and_reset((void**)&client_cb->p_disc_db);
- }
-
- /* reopen registered server */
- /* Collision may be detected before or after we close servers. */
- bta_hf_client_start_server();
-
- /* Start timer to handle connection opening restart */
- alarm_set_on_mloop(client_cb->collision_timer,
- BTA_HF_CLIENT_COLLISION_TIMER_MS,
- bta_hf_client_collision_timer_cback, (void*)client_cb);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_api_enable
- *
- * Description Handle an API enable event.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-tBTA_STATUS bta_hf_client_api_enable(tBTA_HF_CLIENT_CBACK* p_cback,
- tBTA_HF_CLIENT_FEAT features,
- const char* p_service_name) {
- /* If already registered then return error */
- if (bta_sys_is_register(BTA_ID_HS)) {
- APPL_TRACE_ERROR("BTA HF Client is already enabled, ignoring ...");
- return BTA_FAILURE;
- }
-
- /* register with BTA system manager */
- bta_sys_register(BTA_ID_HS, &bta_hf_client_reg);
-
- /* reset the control blocks */
- bta_hf_client_cb_arr_init();
-
- bta_hf_client_cb_arr.p_cback = p_cback;
- bta_hf_client_cb_arr.features = features;
-
- /* create SDP records */
- bta_hf_client_create_record(&bta_hf_client_cb_arr, p_service_name);
-
- /* set same setting as AG does */
- BTM_WriteVoiceSettings(AG_VOICE_SETTINGS);
-
- bta_sys_collision_register(BTA_ID_HS, bta_hf_client_collision_cback);
-
- /* Set the Audio service class bit */
- tBTA_UTL_COD cod;
- cod.service = BTM_COD_SERVICE_AUDIO;
- utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
-
- /* start RFCOMM server */
- bta_hf_client_start_server();
-
- return BTA_SUCCESS;
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_find_cb_by_handle
- *
- * Description Finds the control block by handle provided
- *
- * handle: Handle as obtained from BTA_HfClientOpen call
- *
- *
- * Returns Control block corresponding to the handle and NULL if
- * none exists
- *
- ******************************************************************************/
-tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_handle(uint16_t handle) {
- // Handles are limited from 1 through HF_CLIENT_MAX_DEVICES
- if (handle < 1 || handle > HF_CLIENT_MAX_DEVICES) {
- APPL_TRACE_ERROR("%s: handle out of range (%d, %d) %d", __func__, 1,
- HF_CLIENT_MAX_DEVICES, handle);
- return NULL;
- }
-
- // Check if the associated index is allocated. Index is (handle - 1).
- if (bta_hf_client_cb_arr.cb[handle - 1].is_allocated)
- return &(bta_hf_client_cb_arr.cb[handle - 1]);
-
- APPL_TRACE_ERROR("%s: block not found for handle %d", __func__, handle);
- return NULL;
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_find_cb_by_bda
- *
- * Description Finds the control block by handle provided
- *
- * bda: address of the device to find the handle for.
- * Since there can only be one HF connection for a device
- * we should always find a unique block
- *
- * Returns Control block corresponding to the address and NULL if
- * none exists
- *
- ******************************************************************************/
-tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_bda(const RawAddress& peer_addr) {
- for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
- // Check if the associated index is allocated and that BD ADDR matches
- tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
- if (client_cb->is_allocated && peer_addr == client_cb->peer_addr) {
- return client_cb;
- } else {
- APPL_TRACE_WARNING("%s: bdaddr mismatch for handle %d alloc %d", __func__,
- i, client_cb->is_allocated);
- }
- }
- APPL_TRACE_ERROR("%s: block not found", __func__);
- return NULL;
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_find_cb_by_rfc_handle
- *
- * Description Finds the control block by RFC handle provided.
- *
- * handle: RFC handle for the established connection
- *
- *
- * Returns Control block corresponding to the handle and NULL if none
- * exists
- *
- ******************************************************************************/
-tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_rfc_handle(uint16_t handle) {
- for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
- tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
- bool is_allocated = client_cb->is_allocated;
- uint16_t conn_handle = client_cb->conn_handle;
-
- APPL_TRACE_DEBUG("%s: cb rfc_handle %d alloc %d conn_handle %d", __func__,
- handle, is_allocated, conn_handle);
-
- if (is_allocated && conn_handle == handle) {
- return client_cb;
- }
-
- APPL_TRACE_WARNING("%s: no cb yet %d alloc %d conn_handle %d", __func__,
- handle, is_allocated, conn_handle);
- }
-
- APPL_TRACE_ERROR("%s: no cb found for rfc handle %d", __func__, handle);
- return NULL;
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_find_cb_by_sco_handle
- *
- * Description Finds the control block by sco handle provided
- *
- * handle: sco handle
- *
- *
- * Returns Control block corresponding to the sco handle and
- * none if none exists
- *
- ******************************************************************************/
-tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_sco_handle(uint16_t handle) {
- for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
- tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
- if (client_cb->is_allocated && client_cb->sco_idx == handle) {
- return client_cb;
- }
- }
- APPL_TRACE_ERROR("%s: block not found for handle %d", __func__, handle);
- return NULL;
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_allocate_handle
- *
- * Description Allocates a handle for the new BD ADDR that needs a new RF
- * channel for HF connection. If the channel cannot be created
- * for a reason then false is returned
- *
- * bd_addr: Address of the device for which this block is
- * being created. Single device can only have one block.
- * p_handle: OUT variable to store the outcome of allocate. If
- * allocate failed then value is not valid
- *
- *
- * Returns true if the creation of p_handle succeeded, false otherwise
- *
- ******************************************************************************/
-bool bta_hf_client_allocate_handle(const RawAddress& bd_addr,
- uint16_t* p_handle) {
- tBTA_HF_CLIENT_CB* existing_cb = bta_hf_client_find_cb_by_bda(bd_addr);
- if (existing_cb != NULL) {
- BTIF_TRACE_ERROR("%s: cannot allocate handle since BDADDR already exists",
- __func__);
- return false;
- }
- /* Check that we do not have a request to for same device in the control
- * blocks */
- for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
- tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
- if (client_cb->is_allocated) {
- APPL_TRACE_WARNING("%s: control block already used index %d", __func__,
- i);
- continue;
- }
-
- // Reset the client control block
- bta_hf_client_cb_init(client_cb, client_cb->handle);
-
- *p_handle = client_cb->handle;
- APPL_TRACE_DEBUG("%s: marking CB handle %d to true", __func__,
- client_cb->handle);
-
- client_cb->is_allocated = true;
- client_cb->peer_addr = bd_addr;
- bta_hf_client_at_init(client_cb);
- return true;
- }
-
- return false;
- APPL_TRACE_ERROR("%s: all control blocks in use!", __func__);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_app_callback
- *
- * Description Calls the application callback
- *
- *
- * Returns Void
- *
- ******************************************************************************/
-void bta_hf_client_app_callback(uint16_t event, tBTA_HF_CLIENT* data) {
- if (bta_hf_client_cb_arr.p_cback != NULL) {
- bta_hf_client_cb_arr.p_cback(event, data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_api_disable
- *
- * Description Handle an API disable event.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_api_disable() {
- if (!bta_sys_is_register(BTA_ID_HS)) {
- APPL_TRACE_WARNING("BTA HF Client is already disabled, ignoring ...");
- return;
- }
-
- /* Remove the collision handler */
- bta_sys_collision_register(BTA_ID_HS, NULL);
-
- bta_hf_client_cb_arr.deregister = true;
-
- /* remove sdp record */
- bta_hf_client_del_record(&bta_hf_client_cb_arr);
-
- /* remove rfcomm server */
- bta_hf_client_close_server();
-
- /* reinit the control block */
- for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
- if (bta_hf_client_cb_arr.cb[i].is_allocated) {
- bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]), i);
- }
- }
-
- /* De-register with BTA system manager */
- bta_sys_deregister(BTA_ID_HS);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_hdl_event
- *
- * Description Data HF Client main event handling function.
- *
- *
- * Returns bool
- *
- ******************************************************************************/
-bool bta_hf_client_hdl_event(BT_HDR_RIGID* p_msg) {
- APPL_TRACE_DEBUG("%s: %s (0x%x)", __func__,
- bta_hf_client_evt_str(p_msg->event), p_msg->event);
- bta_hf_client_sm_execute(p_msg->event, (tBTA_HF_CLIENT_DATA*)p_msg);
- return true;
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_sm_execute
- *
- * Description State machine event handling function for HF Client
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_sm_execute(uint16_t event, tBTA_HF_CLIENT_DATA* p_data) {
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- tBTA_HF_CLIENT_ST_TBL state_table;
- uint8_t action;
- int i;
-
- uint16_t in_event = event;
- uint8_t in_state = client_cb->state;
-
- /* Ignore displaying of AT results when not connected (Ignored in state
- * machine) */
- if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) {
- APPL_TRACE_EVENT("HF Client evt : State %d (%s), Event 0x%04x (%s)",
- client_cb->state,
- bta_hf_client_state_str(client_cb->state), event,
- bta_hf_client_evt_str(event));
- }
-
- event &= 0x00FF;
- if (event >= (BTA_HF_CLIENT_MAX_EVT & 0x00FF)) {
- APPL_TRACE_ERROR("HF Client evt out of range, ignoring...");
- return;
- }
-
- /* look up the state table for the current state */
- state_table = bta_hf_client_st_tbl[client_cb->state];
-
- /* set next state */
- client_cb->state = state_table[event][BTA_HF_CLIENT_NEXT_STATE];
-
- /* execute action functions */
- for (i = 0; i < BTA_HF_CLIENT_ACTIONS; i++) {
- action = state_table[event][i];
- if (action != BTA_HF_CLIENT_IGNORE) {
- (*bta_hf_client_action[action])(p_data);
- } else {
- break;
- }
- }
-
- /* If the state has changed then notify the app of the corresponding change */
- if (in_state != client_cb->state) {
- VLOG(1) << __func__ << ": notifying state change to " << in_state << " -> "
- << client_cb->state << " device " << client_cb->peer_addr;
- tBTA_HF_CLIENT evt;
- memset(&evt, 0, sizeof(evt));
- evt.bd_addr = client_cb->peer_addr;
- if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
- bta_hf_client_app_callback(BTA_HF_CLIENT_CLOSE_EVT, &evt);
- APPL_TRACE_DEBUG("%s: marking CB handle %d to false", __func__, client_cb->handle);
- client_cb->is_allocated = false;
- } else if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) {
- evt.open.handle = client_cb->handle;
- bta_hf_client_app_callback(BTA_HF_CLIENT_OPEN_EVT, &evt);
- }
- }
-
- VLOG(2) << __func__ << ": device " << client_cb->peer_addr
- << "state change: [" << bta_hf_client_state_str(in_state) << "] -> ["
- << bta_hf_client_state_str(client_cb->state) << "] after Event ["
- << bta_hf_client_evt_str(in_event) << "]";
-}
-
-static void send_post_slc_cmd(tBTA_HF_CLIENT_CB* client_cb) {
- client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
-
- tBTA_HF_CLIENT_DATA p_data;
- p_data.hdr.layer_specific = client_cb->handle;
- bta_hf_client_sco_listen(&p_data);
- bta_hf_client_send_at_bia(client_cb);
- bta_hf_client_send_at_ccwa(client_cb, true);
- bta_hf_client_send_at_cmee(client_cb, true);
- bta_hf_client_send_at_cops(client_cb, false);
- bta_hf_client_send_at_btrh(client_cb, true, 0);
- bta_hf_client_send_at_clip(client_cb, true);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_slc_seq
- *
- * Description Handles AT commands sequence required for SLC creation
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB* client_cb, bool error) {
- APPL_TRACE_DEBUG("bta_hf_client_slc_seq cmd: %u",
- client_cb->at_cb.current_cmd);
-
- if (error) {
- /* SLC establishment error, sent close rfcomm event */
- APPL_TRACE_ERROR(
- "HFPClient: Failed to create SLC due to AT error, disconnecting (%u)",
- client_cb->at_cb.current_cmd);
-
- tBTA_HF_CLIENT_DATA msg;
- msg.hdr.layer_specific = client_cb->handle;
- bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
- return;
- }
-
- if (client_cb->svc_conn) {
- APPL_TRACE_WARNING("%s: SLC already connected for CB handle %d", __func__,
- client_cb->handle);
- return;
- }
-
- switch (client_cb->at_cb.current_cmd) {
- case BTA_HF_CLIENT_AT_NONE:
- bta_hf_client_send_at_brsf(client_cb, bta_hf_client_cb_arr.features);
- break;
-
- case BTA_HF_CLIENT_AT_BRSF:
- if ((bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_CODEC) &&
- (client_cb->peer_features & BTA_HF_CLIENT_PEER_CODEC)) {
- bta_hf_client_send_at_bac(client_cb);
- break;
- }
-
- bta_hf_client_send_at_cind(client_cb, false);
- break;
-
- case BTA_HF_CLIENT_AT_BAC:
- bta_hf_client_send_at_cind(client_cb, false);
- break;
-
- case BTA_HF_CLIENT_AT_CIND:
- bta_hf_client_send_at_cind(client_cb, true);
- break;
-
- case BTA_HF_CLIENT_AT_CIND_STATUS:
- bta_hf_client_send_at_cmer(client_cb, true);
- break;
-
- case BTA_HF_CLIENT_AT_CMER:
- if (client_cb->peer_features & BTA_HF_CLIENT_PEER_FEAT_3WAY &&
- bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_3WAY) {
- bta_hf_client_send_at_chld(client_cb, '?', 0);
- } else if (bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_HF_IND &&
- client_cb->peer_features & BTA_HF_CLIENT_PEER_HF_IND) {
- bta_hf_client_send_at_bind(client_cb, 0);
- } else {
- tBTA_HF_CLIENT_DATA msg;
- msg.hdr.layer_specific = client_cb->handle;
- bta_hf_client_svc_conn_open(&msg);
- send_post_slc_cmd(client_cb);
- }
- break;
-
- case BTA_HF_CLIENT_AT_CHLD:
- if (bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_HF_IND &&
- client_cb->peer_features & BTA_HF_CLIENT_PEER_HF_IND) {
- bta_hf_client_send_at_bind(client_cb, 0);
- } else {
- tBTA_HF_CLIENT_DATA msg;
- msg.hdr.layer_specific = client_cb->handle;
- bta_hf_client_svc_conn_open(&msg);
- send_post_slc_cmd(client_cb);
- }
- break;
-
- case BTA_HF_CLIENT_AT_BIND_SET_IND:
- bta_hf_client_send_at_bind(client_cb, 1);
- break;
-
- case BTA_HF_CLIENT_AT_BIND_READ_SUPPORTED_IND:
- bta_hf_client_send_at_bind(client_cb, 2);
- break;
-
- case BTA_HF_CLIENT_AT_BIND_READ_ENABLED_IND:
- tBTA_HF_CLIENT_DATA msg;
- msg.hdr.layer_specific = client_cb->handle;
- bta_hf_client_svc_conn_open(&msg);
- send_post_slc_cmd(client_cb);
- break;
-
- default: {
- /* If happen there is a bug in SLC creation procedure... */
- APPL_TRACE_ERROR(
- "HFPClient: Failed to create SLCdue to unexpected AT command, "
- "disconnecting (%u)",
- client_cb->at_cb.current_cmd);
-
- tBTA_HF_CLIENT_DATA msg;
- msg.hdr.layer_specific = client_cb->handle;
- bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
- break;
- }
- }
-}
-
-#ifndef CASE_RETURN_STR
-#define CASE_RETURN_STR(const) \
- case const: \
- return #const;
-#endif
-
-static const char* bta_hf_client_evt_str(uint16_t event) {
- switch (event) {
- CASE_RETURN_STR(BTA_HF_CLIENT_API_OPEN_EVT)
- CASE_RETURN_STR(BTA_HF_CLIENT_API_CLOSE_EVT)
- CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_OPEN_EVT)
- CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_CLOSE_EVT)
- CASE_RETURN_STR(BTA_HF_CLIENT_RFC_OPEN_EVT)
- CASE_RETURN_STR(BTA_HF_CLIENT_RFC_CLOSE_EVT)
- CASE_RETURN_STR(BTA_HF_CLIENT_RFC_SRV_CLOSE_EVT)
- CASE_RETURN_STR(BTA_HF_CLIENT_RFC_DATA_EVT)
- CASE_RETURN_STR(BTA_HF_CLIENT_DISC_ACP_RES_EVT)
- CASE_RETURN_STR(BTA_HF_CLIENT_DISC_INT_RES_EVT)
- CASE_RETURN_STR(BTA_HF_CLIENT_DISC_OK_EVT)
- CASE_RETURN_STR(BTA_HF_CLIENT_DISC_FAIL_EVT)
- CASE_RETURN_STR(BTA_HF_CLIENT_API_ENABLE_EVT)
- CASE_RETURN_STR(BTA_HF_CLIENT_API_DISABLE_EVT)
- CASE_RETURN_STR(BTA_HF_CLIENT_SCO_OPEN_EVT)
- CASE_RETURN_STR(BTA_HF_CLIENT_SCO_CLOSE_EVT)
- CASE_RETURN_STR(BTA_HF_CLIENT_SEND_AT_CMD_EVT)
- default:
- return "Unknown HF Client Event";
- }
-}
-
-static const char* bta_hf_client_state_str(uint8_t state) {
- switch (state) {
- CASE_RETURN_STR(BTA_HF_CLIENT_INIT_ST)
- CASE_RETURN_STR(BTA_HF_CLIENT_OPENING_ST)
- CASE_RETURN_STR(BTA_HF_CLIENT_OPEN_ST)
- CASE_RETURN_STR(BTA_HF_CLIENT_CLOSING_ST)
- default:
- return "Unknown HF Client State";
- }
-}
-
-void bta_hf_client_dump_statistics(int fd) {
- dprintf(fd, "\nBluetooth HF Client BTA Statistics\n");
-
- // We dump statistics for all control blocks
- for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
- tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
- if (!client_cb->is_allocated) {
- // Skip the blocks which are not allocated
- continue;
- }
-
- dprintf(fd, " Control block #%d\n", i + 1);
-
- uint8_t* a = client_cb->peer_addr.address;
- // Device name
- dprintf(fd, " Peer Device: %02x:%02x:%02x:%02x:%02x:%02x\n", a[0], a[1],
- a[2], a[3], a[4], a[5]);
-
- // State machine state
- dprintf(fd, " State Machine State: %s\n",
- bta_hf_client_state_str(client_cb->state));
-
- // Local RFC channelfor communication
- dprintf(fd, " RFCOMM Channel (local) %d\n", client_cb->conn_handle);
-
- // BTA Handle shared between BTA and client (ex BTIF)
- dprintf(fd, " BTA Generated handle %d\n", client_cb->handle);
- }
-}
diff --git a/bta/hf_client/bta_hf_client_rfc.cc b/bta/hf_client/bta_hf_client_rfc.cc
deleted file mode 100644
index d964003..0000000
--- a/bta/hf_client/bta_hf_client_rfc.cc
+++ /dev/null
@@ -1,294 +0,0 @@
-/******************************************************************************
- *
- * Copyright (c) 2014 The Android Open Source Project
- * Copyright 2004-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains the audio gateway functions controlling the RFCOMM
- * connections.
- *
- ******************************************************************************/
-
-#include <cstdint>
-
-#include "bta/hf_client/bta_hf_client_int.h"
-#include "osi/include/allocator.h"
-#include "osi/include/osi.h" // UNUSED_ATTR
-#include "stack/include/port_api.h"
-#include "stack/include/sdp_api.h"
-#include "types/raw_address.h"
-
-#include <base/logging.h>
-
-/*******************************************************************************
- *
- * Function bta_hf_client_port_cback
- *
- * Description RFCOMM Port callback. The handle in this function is
- * specified by BTA layer via the PORT_SetEventCallback
- * method
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_hf_client_port_cback(UNUSED_ATTR uint32_t code,
- uint16_t port_handle) {
- /* ignore port events for port handles other than connected handle */
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_rfc_handle(port_handle);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__, port_handle);
- return;
- }
-
- tBTA_HF_CLIENT_RFC* p_buf =
- (tBTA_HF_CLIENT_RFC*)osi_malloc(sizeof(tBTA_HF_CLIENT_RFC));
- p_buf->hdr.event = BTA_HF_CLIENT_RFC_DATA_EVT;
- p_buf->hdr.layer_specific = client_cb->handle;
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_mgmt_cback
- *
- * Description RFCOMM management callback
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_hf_client_mgmt_cback(uint32_t code, uint16_t port_handle) {
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_rfc_handle(port_handle);
-
- APPL_TRACE_DEBUG("%s: code = %d, port_handle = %d serv = %d", __func__, code,
- port_handle, bta_hf_client_cb_arr.serv_handle);
-
- /* ignore close event for port handles other than connected handle */
- if (code != PORT_SUCCESS && client_cb != NULL &&
- port_handle != client_cb->conn_handle) {
- APPL_TRACE_DEBUG("bta_hf_client_mgmt_cback ignoring handle:%d",
- port_handle);
- return;
- }
-
- tBTA_HF_CLIENT_RFC* p_buf =
- (tBTA_HF_CLIENT_RFC*)osi_malloc(sizeof(tBTA_HF_CLIENT_RFC));
-
- if (code == PORT_SUCCESS) {
- if (client_cb && port_handle == client_cb->conn_handle) { /* out conn */
- p_buf->hdr.event = BTA_HF_CLIENT_RFC_OPEN_EVT;
- } else if (port_handle == bta_hf_client_cb_arr.serv_handle) {
- p_buf->hdr.event = BTA_HF_CLIENT_RFC_OPEN_EVT;
-
- APPL_TRACE_DEBUG("%s: allocating a new CB for incoming connection",
- __func__);
- // Find the BDADDR of the peer device
- RawAddress peer_addr = RawAddress::kEmpty;
- uint16_t lcid = 0;
- int status = PORT_CheckConnection(port_handle, &peer_addr, &lcid);
- if (status != PORT_SUCCESS) {
- LOG(ERROR) << __func__ << ": PORT_CheckConnection returned " << status;
- }
-
- // Since we accepted a remote request we should allocate a handle first.
- uint16_t tmp_handle = -1;
- bta_hf_client_allocate_handle(peer_addr, &tmp_handle);
- client_cb = bta_hf_client_find_cb_by_handle(tmp_handle);
-
- // If allocation fails then we abort.
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: error allocating a new handle", __func__);
- p_buf->hdr.event = BTA_HF_CLIENT_RFC_CLOSE_EVT;
- } else {
- // Set the connection fields for this new CB
- client_cb->conn_handle = port_handle;
-
- // Since we have accepted an incoming RFCOMM connection:
- // a) Release the current server from it duties
- // b) Start a new server for more new incoming connection
- bta_hf_client_cb_arr.serv_handle = 0;
- bta_hf_client_start_server();
- }
- } else {
- APPL_TRACE_ERROR("%s: PORT_SUCCESS, ignoring handle = %d", __func__,
- port_handle);
- osi_free(p_buf);
- return;
- }
- } else if (client_cb != NULL &&
- port_handle == client_cb->conn_handle) { /* code != PORT_SUC */
- LOG(ERROR) << __func__ << ": closing port handle " << port_handle << "dev "
- << client_cb->peer_addr;
-
- RFCOMM_RemoveServer(port_handle);
- p_buf->hdr.event = BTA_HF_CLIENT_RFC_CLOSE_EVT;
- } else if (client_cb == NULL) {
- // client_cb is already cleaned due to hfp client disabled.
- // Assigned a valid event value to header and send this message anyway.
- p_buf->hdr.event = BTA_HF_CLIENT_RFC_CLOSE_EVT;
- }
-
- p_buf->hdr.layer_specific = client_cb != NULL ? client_cb->handle : 0;
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_setup_port
- *
- * Description Setup RFCOMM port for use by HF Client.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_setup_port(uint16_t handle) {
- PORT_SetEventMask(handle, PORT_EV_RXCHAR);
- PORT_SetEventCallback(handle, bta_hf_client_port_cback);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_start_server
- *
- * Description Setup RFCOMM server for use by HF Client.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_start_server() {
- int port_status;
-
- if (bta_hf_client_cb_arr.serv_handle > 0) {
- APPL_TRACE_DEBUG("%s: already started, handle: %d", __func__,
- bta_hf_client_cb_arr.serv_handle);
- return;
- }
-
- port_status = RFCOMM_CreateConnectionWithSecurity(
- UUID_SERVCLASS_HF_HANDSFREE, bta_hf_client_cb_arr.scn, true,
- BTA_HF_CLIENT_MTU, RawAddress::kAny, &(bta_hf_client_cb_arr.serv_handle),
- bta_hf_client_mgmt_cback, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
-
- APPL_TRACE_DEBUG("%s: started rfcomm server with handle %d", __func__,
- bta_hf_client_cb_arr.serv_handle);
-
- if (port_status == PORT_SUCCESS) {
- bta_hf_client_setup_port(bta_hf_client_cb_arr.serv_handle);
- } else {
- APPL_TRACE_DEBUG("%s: RFCOMM_CreateConnection returned error:%d", __func__,
- port_status);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_close_server
- *
- * Description Close RFCOMM server port for use by HF Client.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_close_server() {
- APPL_TRACE_DEBUG("%s: %d", __func__, bta_hf_client_cb_arr.serv_handle);
-
- if (bta_hf_client_cb_arr.serv_handle == 0) {
- APPL_TRACE_DEBUG("%s: already stopped", __func__);
- return;
- }
-
- RFCOMM_RemoveServer(bta_hf_client_cb_arr.serv_handle);
- bta_hf_client_cb_arr.serv_handle = 0;
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_rfc_do_open
- *
- * Description Open an RFCOMM connection to the peer device.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_rfc_do_open(tBTA_HF_CLIENT_DATA* p_data) {
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- if (RFCOMM_CreateConnectionWithSecurity(
- UUID_SERVCLASS_HF_HANDSFREE, client_cb->peer_scn, false,
- BTA_HF_CLIENT_MTU, client_cb->peer_addr, &(client_cb->conn_handle),
- bta_hf_client_mgmt_cback,
- BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT) == PORT_SUCCESS) {
- bta_hf_client_setup_port(client_cb->conn_handle);
- APPL_TRACE_DEBUG("bta_hf_client_rfc_do_open : conn_handle = %d",
- client_cb->conn_handle);
- }
- /* RFCOMM create connection failed; send ourselves RFCOMM close event */
- else {
- bta_hf_client_sm_execute(BTA_HF_CLIENT_RFC_CLOSE_EVT, p_data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_rfc_do_close
- *
- * Description Close RFCOMM connection.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_rfc_do_close(tBTA_HF_CLIENT_DATA* p_data) {
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- if (client_cb->conn_handle) {
- RFCOMM_RemoveConnection(client_cb->conn_handle);
- } else {
- /* Close API was called while HF Client is in Opening state. */
- /* Need to trigger the state machine to send callback to the app */
- /* and move back to INIT state. */
- tBTA_HF_CLIENT_RFC* p_buf =
- (tBTA_HF_CLIENT_RFC*)osi_malloc(sizeof(tBTA_HF_CLIENT_RFC));
- p_buf->hdr.event = BTA_HF_CLIENT_RFC_CLOSE_EVT;
- bta_sys_sendmsg(p_buf);
-
- /* Cancel SDP if it had been started. */
- if (client_cb->p_disc_db) {
- (void)SDP_CancelServiceSearch(client_cb->p_disc_db);
- osi_free_and_reset((void**)&client_cb->p_disc_db);
- }
- }
-}
diff --git a/bta/hf_client/bta_hf_client_sco.cc b/bta/hf_client/bta_hf_client_sco.cc
deleted file mode 100644
index 9982402..0000000
--- a/bta/hf_client/bta_hf_client_sco.cc
+++ /dev/null
@@ -1,674 +0,0 @@
-/******************************************************************************
- *
- * Copyright (c) 2014 The Android Open Source Project
- * Copyright 2004-2012 Broadcom Corporation
- *
- * 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 "bta/hf_client/bta_hf_client_int.h"
-#include "bta/include/bta_ag_api.h"
-#include "osi/include/allocator.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/btm_api.h"
-
-#define BTA_HF_CLIENT_NO_EDR_ESCO \
- (ESCO_PKT_TYPES_MASK_NO_2_EV3 | ESCO_PKT_TYPES_MASK_NO_3_EV3 | \
- ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5)
-
-enum {
- BTA_HF_CLIENT_SCO_LISTEN_E,
- BTA_HF_CLIENT_SCO_OPEN_E, /* open request */
- BTA_HF_CLIENT_SCO_CLOSE_E, /* close request */
- BTA_HF_CLIENT_SCO_SHUTDOWN_E, /* shutdown request */
- BTA_HF_CLIENT_SCO_CONN_OPEN_E, /* SCO opened */
- BTA_HF_CLIENT_SCO_CONN_CLOSE_E, /* SCO closed */
-};
-
-/*******************************************************************************
- *
- * Function bta_hf_client_remove_sco
- *
- * Description Removes the specified SCO from the system.
- *
- * Returns bool - true if SCO removal was started
- *
- ******************************************************************************/
-static bool bta_hf_client_sco_remove(tBTA_HF_CLIENT_CB* client_cb) {
- bool removed_started = false;
- tBTM_STATUS status;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- if (client_cb->sco_idx != BTM_INVALID_SCO_INDEX) {
- status = BTM_RemoveSco(client_cb->sco_idx);
-
- APPL_TRACE_DEBUG("%s: idx 0x%04x, status:0x%x", __func__,
- client_cb->sco_idx, status);
-
- if (status == BTM_CMD_STARTED) {
- removed_started = true;
- }
- /* If no connection reset the SCO handle */
- else if ((status == BTM_SUCCESS) || (status == BTM_UNKNOWN_ADDR)) {
- client_cb->sco_idx = BTM_INVALID_SCO_INDEX;
- }
- }
- return removed_started;
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_cback_sco
- *
- * Description Call application callback function with SCO event.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_cback_sco(tBTA_HF_CLIENT_CB* client_cb, uint8_t event) {
- tBTA_HF_CLIENT evt;
-
- memset(&evt, 0, sizeof(evt));
- evt.bd_addr = client_cb->peer_addr;
-
- /* call app cback */
- bta_hf_client_app_callback(event, &evt);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_sco_conn_rsp
- *
- * Description Process the SCO connection request
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_hf_client_sco_conn_rsp(tBTA_HF_CLIENT_CB* client_cb,
- tBTM_ESCO_CONN_REQ_EVT_DATA* p_data) {
- enh_esco_params_t resp;
- uint8_t hci_status = HCI_SUCCESS;
-
- APPL_TRACE_DEBUG("%s", __func__);
-
- if (client_cb->sco_state == BTA_HF_CLIENT_SCO_LISTEN_ST) {
- if (p_data->link_type == BTM_LINK_TYPE_SCO) {
- // SCO
- resp = esco_parameters_for_codec(SCO_CODEC_CVSD_D1);
- } else if (client_cb->negotiated_codec == BTM_SCO_CODEC_MSBC) {
- // eSCO mSBC
- resp = esco_parameters_for_codec(ESCO_CODEC_MSBC_T2);
- } else if (bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_ESCO_S4) {
- // eSCO CVSD, HFP 1.7 requires S4
- resp = esco_parameters_for_codec(ESCO_CODEC_CVSD_S4);
- } else {
- // eSCO CVSD, S3 is preferred by default(before HFP 1.7)
- resp = esco_parameters_for_codec(ESCO_CODEC_CVSD_S3);
- }
-
- /* tell sys to stop av if any */
- bta_sys_sco_use(BTA_ID_HS, 1, client_cb->peer_addr);
- } else {
- hci_status = HCI_ERR_HOST_REJECT_DEVICE;
- }
-
- BTM_EScoConnRsp(p_data->sco_inx, hci_status, &resp);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_sco_connreq_cback
- *
- * Description BTM eSCO connection requests and eSCO change requests
- * Only the connection requests are processed by BTA.
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_hf_client_esco_connreq_cback(tBTM_ESCO_EVT event,
- tBTM_ESCO_EVT_DATA* p_data) {
- APPL_TRACE_DEBUG("%s: %d", __func__, event);
-
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_sco_handle(p_data->conn_evt.sco_inx);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: wrong SCO handle to control block %d", __func__,
- p_data->conn_evt.sco_inx);
- return;
- }
-
- if (event != BTM_ESCO_CONN_REQ_EVT) {
- return;
- }
-
- bta_hf_client_sco_conn_rsp(client_cb, &p_data->conn_evt);
-
- client_cb->sco_state = BTA_HF_CLIENT_SCO_OPENING_ST;
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_sco_conn_cback
- *
- * Description BTM SCO connection callback.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_hf_client_sco_conn_cback(uint16_t sco_idx) {
- APPL_TRACE_DEBUG("%s: %d", __func__, sco_idx);
-
- tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_sco_handle(sco_idx);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: wrong SCO handle to control block %d", __func__,
- sco_idx);
- return;
- }
-
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
- p_buf->event = BTA_HF_CLIENT_SCO_OPEN_EVT;
- p_buf->layer_specific = client_cb->handle;
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_sco_disc_cback
- *
- * Description BTM SCO disconnection callback.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_hf_client_sco_disc_cback(uint16_t sco_idx) {
- APPL_TRACE_DEBUG("%s: sco_idx %d", __func__, sco_idx);
-
- tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_sco_handle(sco_idx);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__, sco_idx);
- return;
- }
-
- BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
- p_buf->event = BTA_HF_CLIENT_SCO_CLOSE_EVT;
- p_buf->layer_specific = client_cb->handle;
- bta_sys_sendmsg(p_buf);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_create_sco
- *
- * Description
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_hf_client_sco_create(tBTA_HF_CLIENT_CB* client_cb,
- bool is_orig) {
- tBTM_STATUS status;
-
- APPL_TRACE_DEBUG("%s: %d", __func__, is_orig);
-
- /* Make sure this SCO handle is not already in use */
- if (client_cb->sco_idx != BTM_INVALID_SCO_INDEX) {
- APPL_TRACE_WARNING("%s: Index 0x%04x already in use", __func__,
- client_cb->sco_idx);
- return;
- }
-
- // codec parameters
- enh_esco_params_t params;
- // Since HF device is not expected to receive AT+BAC send +BCS command,
- // codec support of the connected AG device will be unknown,
- // so HF device will always establish only CVSD connection.
- if ((bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_ESCO_S4) &&
- (client_cb->peer_features & BTA_HF_CLIENT_PEER_ESCO_S4)) {
- // eSCO CVSD, HFP 1.7 requires S4
- params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S4);
- } else {
- // eSCO CVSD, S3 is preferred by default(before HFP 1.7)
- params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S3);
- }
-
- /* if initiating set current scb and peer bd addr */
- if (is_orig) {
- BTM_SetEScoMode(¶ms);
- /* tell sys to stop av if any */
- bta_sys_sco_use(BTA_ID_HS, 1, client_cb->peer_addr);
- }
-
- status = BTM_CreateSco(&client_cb->peer_addr, is_orig, params.packet_types,
- &client_cb->sco_idx, bta_hf_client_sco_conn_cback,
- bta_hf_client_sco_disc_cback);
- if (status == BTM_CMD_STARTED && !is_orig) {
- if (!BTM_RegForEScoEvts(client_cb->sco_idx,
- bta_hf_client_esco_connreq_cback))
- APPL_TRACE_DEBUG("%s: SCO registration success", __func__);
- }
-
- APPL_TRACE_API("%s: orig %d, inx 0x%04x, status 0x%x, pkt types 0x%04x",
- __func__, is_orig, client_cb->sco_idx, status,
- params.packet_types);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_sco_event
- *
- * Description Handle SCO events
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_hf_client_sco_event(tBTA_HF_CLIENT_CB* client_cb,
- uint8_t event) {
- APPL_TRACE_DEBUG("%s: before state: %d event: %d", __func__,
- client_cb->sco_state, event);
-
- switch (client_cb->sco_state) {
- case BTA_HF_CLIENT_SCO_SHUTDOWN_ST:
- switch (event) {
- // For WBS we only listen to SCO requests. Even for outgoing SCO
- // requests we first do a AT+BCC and wait for remote to initiate SCO
- case BTA_HF_CLIENT_SCO_LISTEN_E:
- /* create SCO listen connection */
- bta_hf_client_sco_create(client_cb, false);
- client_cb->sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
- break;
-
- // For non WBS cases and enabling outgoing SCO requests we need to force
- // open a SCO channel
- case BTA_HF_CLIENT_SCO_OPEN_E:
- /* remove listening connection */
- bta_hf_client_sco_remove(client_cb);
-
- /* create SCO connection to peer */
- bta_hf_client_sco_create(client_cb, true);
- client_cb->sco_state = BTA_HF_CLIENT_SCO_OPENING_ST;
- break;
-
- default:
- APPL_TRACE_WARNING("BTA_HF_CLIENT_SCO_SHUTDOWN_ST: Ignoring event %d",
- event);
- break;
- }
- break;
-
- case BTA_HF_CLIENT_SCO_LISTEN_ST:
- switch (event) {
- case BTA_HF_CLIENT_SCO_LISTEN_E:
- /* create SCO listen connection */
- bta_hf_client_sco_create(client_cb, false);
- break;
-
- case BTA_HF_CLIENT_SCO_OPEN_E:
- /* remove listening connection */
- bta_hf_client_sco_remove(client_cb);
-
- /* create SCO connection to peer */
- bta_hf_client_sco_create(client_cb, true);
- client_cb->sco_state = BTA_HF_CLIENT_SCO_OPENING_ST;
- break;
-
- case BTA_HF_CLIENT_SCO_SHUTDOWN_E:
- /* remove listening connection */
- bta_hf_client_sco_remove(client_cb);
-
- client_cb->sco_state = BTA_HF_CLIENT_SCO_SHUTDOWN_ST;
- break;
-
- case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
- /* SCO failed; create SCO listen connection */
- bta_hf_client_sco_create(client_cb, false);
- client_cb->sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
- break;
-
- default:
- APPL_TRACE_WARNING(
- "%s: BTA_HF_CLIENT_SCO_LISTEN_ST: Ignoring event %d", __func__,
- event);
- break;
- }
- break;
-
- case BTA_HF_CLIENT_SCO_OPENING_ST:
- switch (event) {
- case BTA_HF_CLIENT_SCO_CLOSE_E:
- client_cb->sco_state = BTA_HF_CLIENT_SCO_OPEN_CL_ST;
- break;
-
- case BTA_HF_CLIENT_SCO_SHUTDOWN_E:
- client_cb->sco_state = BTA_HF_CLIENT_SCO_SHUTTING_ST;
- break;
-
- case BTA_HF_CLIENT_SCO_CONN_OPEN_E:
- client_cb->sco_state = BTA_HF_CLIENT_SCO_OPEN_ST;
- break;
-
- case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
- /* SCO failed; create SCO listen connection */
- bta_hf_client_sco_create(client_cb, false);
- client_cb->sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
- break;
-
- default:
- APPL_TRACE_WARNING("BTA_HF_CLIENT_SCO_OPENING_ST: Ignoring event %d",
- event);
- break;
- }
- break;
-
- case BTA_HF_CLIENT_SCO_OPEN_CL_ST:
- switch (event) {
- case BTA_HF_CLIENT_SCO_OPEN_E:
- client_cb->sco_state = BTA_HF_CLIENT_SCO_OPENING_ST;
- break;
-
- case BTA_HF_CLIENT_SCO_SHUTDOWN_E:
- client_cb->sco_state = BTA_HF_CLIENT_SCO_SHUTTING_ST;
- break;
-
- case BTA_HF_CLIENT_SCO_CONN_OPEN_E:
- /* close SCO connection */
- bta_hf_client_sco_remove(client_cb);
-
- client_cb->sco_state = BTA_HF_CLIENT_SCO_CLOSING_ST;
- break;
-
- case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
- /* SCO failed; create SCO listen connection */
-
- client_cb->sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
- break;
-
- default:
- APPL_TRACE_WARNING("BTA_HF_CLIENT_SCO_OPEN_CL_ST: Ignoring event %d",
- event);
- break;
- }
- break;
-
- case BTA_HF_CLIENT_SCO_OPEN_ST:
- switch (event) {
- case BTA_HF_CLIENT_SCO_CLOSE_E:
- if (bta_hf_client_sco_remove(client_cb)) {
- client_cb->sco_state = BTA_HF_CLIENT_SCO_CLOSING_ST;
- }
- break;
-
- case BTA_HF_CLIENT_SCO_SHUTDOWN_E:
- /* remove listening connection */
- bta_hf_client_sco_remove(client_cb);
-
- client_cb->sco_state = BTA_HF_CLIENT_SCO_SHUTTING_ST;
- break;
-
- case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
- /* peer closed SCO */
- bta_hf_client_sco_create(client_cb, false);
- client_cb->sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
- break;
-
- default:
- APPL_TRACE_WARNING("BTA_HF_CLIENT_SCO_OPEN_ST: Ignoring event %d",
- event);
- break;
- }
- break;
-
- case BTA_HF_CLIENT_SCO_CLOSING_ST:
- switch (event) {
- case BTA_HF_CLIENT_SCO_OPEN_E:
- client_cb->sco_state = BTA_HF_CLIENT_SCO_CLOSE_OP_ST;
- break;
-
- case BTA_HF_CLIENT_SCO_SHUTDOWN_E:
- client_cb->sco_state = BTA_HF_CLIENT_SCO_SHUTTING_ST;
- break;
-
- case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
- /* peer closed sco; create SCO listen connection */
- bta_hf_client_sco_create(client_cb, false);
- client_cb->sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
- break;
-
- default:
- APPL_TRACE_WARNING("BTA_HF_CLIENT_SCO_CLOSING_ST: Ignoring event %d",
- event);
- break;
- }
- break;
-
- case BTA_HF_CLIENT_SCO_CLOSE_OP_ST:
- switch (event) {
- case BTA_HF_CLIENT_SCO_CLOSE_E:
- client_cb->sco_state = BTA_HF_CLIENT_SCO_CLOSING_ST;
- break;
-
- case BTA_HF_CLIENT_SCO_SHUTDOWN_E:
- client_cb->sco_state = BTA_HF_CLIENT_SCO_SHUTTING_ST;
- break;
-
- case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
- /* open SCO connection */
- bta_hf_client_sco_create(client_cb, true);
- client_cb->sco_state = BTA_HF_CLIENT_SCO_OPENING_ST;
- break;
-
- default:
- APPL_TRACE_WARNING("BTA_HF_CLIENT_SCO_CLOSE_OP_ST: Ignoring event %d",
- event);
- break;
- }
- break;
-
- case BTA_HF_CLIENT_SCO_SHUTTING_ST:
- switch (event) {
- case BTA_HF_CLIENT_SCO_CONN_OPEN_E:
- /* close SCO connection; wait for conn close event */
- bta_hf_client_sco_remove(client_cb);
- break;
-
- case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
- client_cb->sco_state = BTA_HF_CLIENT_SCO_SHUTDOWN_ST;
- break;
-
- case BTA_HF_CLIENT_SCO_SHUTDOWN_E:
- client_cb->sco_state = BTA_HF_CLIENT_SCO_SHUTDOWN_ST;
- break;
-
- default:
- APPL_TRACE_WARNING("BTA_HF_CLIENT_SCO_SHUTTING_ST: Ignoring event %d",
- event);
- break;
- }
- break;
-
- default:
- break;
- }
-
- APPL_TRACE_DEBUG("%s: after state: %d", __func__, client_cb->sco_state);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_sco_listen
- *
- * Description Initialize SCO listener
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_sco_listen(tBTA_HF_CLIENT_DATA* p_data) {
- APPL_TRACE_DEBUG("%s", __func__);
-
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- bta_hf_client_sco_event(client_cb, BTA_HF_CLIENT_SCO_LISTEN_E);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_sco_shutdown
- *
- * Description
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_sco_shutdown(tBTA_HF_CLIENT_CB* client_cb) {
- APPL_TRACE_DEBUG("%s", __func__);
-
- bta_hf_client_sco_event(client_cb, BTA_HF_CLIENT_SCO_SHUTDOWN_E);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_sco_conn_open
- *
- * Description
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_sco_conn_open(tBTA_HF_CLIENT_DATA* p_data) {
- APPL_TRACE_DEBUG("%s", __func__);
-
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- bta_hf_client_sco_event(client_cb, BTA_HF_CLIENT_SCO_CONN_OPEN_E);
-
- bta_sys_sco_open(BTA_ID_HS, 1, client_cb->peer_addr);
-
- if (client_cb->negotiated_codec == BTM_SCO_CODEC_MSBC) {
- bta_hf_client_cback_sco(client_cb, BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT);
- } else {
- bta_hf_client_cback_sco(client_cb, BTA_HF_CLIENT_AUDIO_OPEN_EVT);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_sco_conn_close
- *
- * Description
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_sco_conn_close(tBTA_HF_CLIENT_DATA* p_data) {
- APPL_TRACE_DEBUG("%s", __func__);
-
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- /* clear current scb */
- client_cb->sco_idx = BTM_INVALID_SCO_INDEX;
-
- bta_hf_client_sco_event(client_cb, BTA_HF_CLIENT_SCO_CONN_CLOSE_E);
-
- bta_sys_sco_close(BTA_ID_HS, 1, client_cb->peer_addr);
-
- bta_sys_sco_unuse(BTA_ID_HS, 1, client_cb->peer_addr);
-
- /* call app callback */
- bta_hf_client_cback_sco(client_cb, BTA_HF_CLIENT_AUDIO_CLOSE_EVT);
-
- if (client_cb->sco_close_rfc) {
- client_cb->sco_close_rfc = false;
- bta_hf_client_rfc_do_close(p_data);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_sco_open
- *
- * Description
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_sco_open(tBTA_HF_CLIENT_DATA* p_data) {
- APPL_TRACE_DEBUG("%s", __func__);
-
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- bta_hf_client_sco_event(client_cb, BTA_HF_CLIENT_SCO_OPEN_E);
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_sco_close
- *
- * Description
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_sco_close(tBTA_HF_CLIENT_DATA* p_data) {
- tBTA_HF_CLIENT_CB* client_cb =
- bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
- if (client_cb == NULL) {
- APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
- p_data->hdr.layer_specific);
- return;
- }
-
- APPL_TRACE_DEBUG("%s: sco_idx 0x%x", __func__, client_cb->sco_idx);
-
- if (client_cb->sco_idx != BTM_INVALID_SCO_INDEX) {
- bta_hf_client_sco_event(client_cb, BTA_HF_CLIENT_SCO_CLOSE_E);
- }
-}
diff --git a/bta/hf_client/bta_hf_client_sdp.cc b/bta/hf_client/bta_hf_client_sdp.cc
deleted file mode 100755
index 96b7a6d..0000000
--- a/bta/hf_client/bta_hf_client_sdp.cc
+++ /dev/null
@@ -1,368 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2014 The Android Open Source Project
- * Copyright 2003-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * This file contains the audio gateway functions performing SDP
- * operations.
- *
- ******************************************************************************/
-
-#include <cstdint>
-
-#include "bta/hf_client/bta_hf_client_int.h"
-#include "bta/include/bta_ag_api.h"
-#include "bta/include/bta_hf_client_api.h"
-#include "bta/sys/bta_sys.h"
-#include "osi/include/allocator.h"
-#include "osi/include/properties.h"
-#include "stack/btm/btm_sec.h"
-#include "stack/include/btm_api.h"
-#include "stack/include/port_api.h"
-#include "stack/include/sdpdefs.h"
-#include "types/bluetooth/uuid.h"
-
-using bluetooth::Uuid;
-
-/* Number of protocol elements in protocol element list. */
-#define BTA_HF_CLIENT_NUM_PROTO_ELEMS 2
-
-/* Number of elements in service class id list. */
-#define BTA_HF_CLIENT_NUM_SVC_ELEMS 2
-
-/*******************************************************************************
- *
- * Function bta_hf_client_sdp_cback
- *
- * Description SDP callback function.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_hf_client_sdp_cback(tSDP_STATUS status, const void* data) {
- uint16_t event;
- tBTA_HF_CLIENT_DISC_RESULT* p_buf = (tBTA_HF_CLIENT_DISC_RESULT*)osi_malloc(
- sizeof(tBTA_HF_CLIENT_DISC_RESULT));
-
- APPL_TRACE_DEBUG("bta_hf_client_sdp_cback status:0x%x", status);
- tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data;
-
- /* set event according to int/acp */
- if (client_cb->role == BTA_HF_CLIENT_ACP)
- event = BTA_HF_CLIENT_DISC_ACP_RES_EVT;
- else
- event = BTA_HF_CLIENT_DISC_INT_RES_EVT;
-
- p_buf->hdr.event = event;
- p_buf->hdr.layer_specific = client_cb->handle;
- p_buf->status = status;
-
- bta_sys_sendmsg(p_buf);
-}
-
-/******************************************************************************
- *
- * Function bta_hf_client_add_record
- *
- * Description This function is called by a server application to add
- * HFP Client information to an SDP record. Prior to
- * calling this function the application must call
- * SDP_CreateRecord() to create an SDP record.
- *
- * Returns true if function execution succeeded,
- * false if function execution failed.
- *
- *****************************************************************************/
-bool bta_hf_client_add_record(const char* p_service_name, uint8_t scn,
- tBTA_HF_CLIENT_FEAT features,
- uint32_t sdp_handle) {
- tSDP_PROTOCOL_ELEM proto_elem_list[BTA_HF_CLIENT_NUM_PROTO_ELEMS];
- uint16_t svc_class_id_list[BTA_HF_CLIENT_NUM_SVC_ELEMS];
- uint16_t browse_list[] = {UUID_SERVCLASS_PUBLIC_BROWSE_GROUP};
- uint16_t version;
- uint16_t profile_uuid;
- bool result = true;
- uint8_t buf[2];
- uint16_t sdp_features = 0;
-
- APPL_TRACE_DEBUG("bta_hf_client_add_record");
-
- memset(proto_elem_list, 0,
- BTA_HF_CLIENT_NUM_PROTO_ELEMS * sizeof(tSDP_PROTOCOL_ELEM));
-
- /* add the protocol element sequence */
- proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
- proto_elem_list[0].num_params = 0;
- proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
- proto_elem_list[1].num_params = 1;
- proto_elem_list[1].params[0] = scn;
- result &= SDP_AddProtocolList(sdp_handle, BTA_HF_CLIENT_NUM_PROTO_ELEMS,
- proto_elem_list);
-
- /* add service class id list */
- svc_class_id_list[0] = UUID_SERVCLASS_HF_HANDSFREE;
- svc_class_id_list[1] = UUID_SERVCLASS_GENERIC_AUDIO;
- result &= SDP_AddServiceClassIdList(sdp_handle, BTA_HF_CLIENT_NUM_SVC_ELEMS,
- svc_class_id_list);
-
- /* add profile descriptor list */
- profile_uuid = UUID_SERVCLASS_HF_HANDSFREE;
- version = BTA_HFP_VERSION;
-
- result &= SDP_AddProfileDescriptorList(sdp_handle, profile_uuid, version);
-
- /* add service name */
- if (p_service_name != NULL && p_service_name[0] != 0) {
- result &= SDP_AddAttribute(
- sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
- (uint32_t)(strlen(p_service_name) + 1), (uint8_t*)p_service_name);
- }
-
- /* add features */
- if (features & BTA_HF_CLIENT_FEAT_ECNR)
- sdp_features |= BTA_HF_CLIENT_FEAT_ECNR;
-
- if (features & BTA_HF_CLIENT_FEAT_3WAY)
- sdp_features |= BTA_HF_CLIENT_FEAT_3WAY;
-
- if (features & BTA_HF_CLIENT_FEAT_CLI) sdp_features |= BTA_HF_CLIENT_FEAT_CLI;
-
- if (features & BTA_HF_CLIENT_FEAT_VREC)
- sdp_features |= BTA_HF_CLIENT_FEAT_VREC;
-
- if (features & BTA_HF_CLIENT_FEAT_VOL) sdp_features |= BTA_HF_CLIENT_FEAT_VOL;
-
- /* Codec bit position is different in SDP (bit 5) and in BRSF (bit 7) */
- if (features & BTA_HF_CLIENT_FEAT_CODEC) sdp_features |= 0x0020;
-
- UINT16_TO_BE_FIELD(buf, sdp_features);
- result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_FEATURES,
- UINT_DESC_TYPE, 2, buf);
-
- /* add browse group list */
- result &= SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1,
- browse_list);
-
- return result;
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_create_record
- *
- * Description Create SDP record for registered service.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_create_record(tBTA_HF_CLIENT_CB_ARR* client_cb_arr,
- const char* p_service_name) {
- /* add sdp record if not already registered */
- if (client_cb_arr->sdp_handle == 0) {
- client_cb_arr->sdp_handle = SDP_CreateRecord();
- client_cb_arr->scn = BTM_AllocateSCN();
- bta_hf_client_add_record(p_service_name, client_cb_arr->scn,
- client_cb_arr->features,
- client_cb_arr->sdp_handle);
-
- bta_sys_add_uuid(UUID_SERVCLASS_HF_HANDSFREE);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_del_record
- *
- * Description Delete SDP record for registered service.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-void bta_hf_client_del_record(tBTA_HF_CLIENT_CB_ARR* client_cb) {
- APPL_TRACE_DEBUG("%s", __func__);
-
- if (client_cb->sdp_handle != 0) {
- SDP_DeleteRecord(client_cb->sdp_handle);
- client_cb->sdp_handle = 0;
- BTM_FreeSCN(client_cb->scn);
- RFCOMM_ClearSecurityRecord(client_cb->scn);
- bta_sys_remove_uuid(UUID_SERVCLASS_HF_HANDSFREE);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_sdp_find_attr
- *
- * Description Process SDP discovery results to find requested attribute
- *
- *
- * Returns true if results found, false otherwise.
- *
- ******************************************************************************/
-bool bta_hf_client_sdp_find_attr(tBTA_HF_CLIENT_CB* client_cb) {
- tSDP_DISC_REC* p_rec = NULL;
- tSDP_DISC_ATTR* p_attr;
- tSDP_PROTOCOL_ELEM pe;
- bool result = false;
-
- client_cb->peer_version = HFP_VERSION_1_1; /* Default version */
-
- /* loop through all records we found */
- while (true) {
- /* get next record; if none found, we're done */
- p_rec = SDP_FindServiceInDb(client_cb->p_disc_db,
- UUID_SERVCLASS_AG_HANDSFREE, p_rec);
- if (p_rec == NULL) {
- break;
- }
-
- /* get scn from proto desc list if initiator */
- if (client_cb->role == BTA_HF_CLIENT_INT) {
- if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
- client_cb->peer_scn = (uint8_t)pe.params[0];
- } else {
- continue;
- }
- }
-
- /* get profile version (if failure, version parameter is not updated) */
- SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_HF_HANDSFREE,
- &client_cb->peer_version);
-
- /* get features */
- p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES);
- if (p_attr != NULL) {
- /* Found attribute. Get value. */
- /* There might be race condition between SDP and BRSF. */
- /* Do not update if we already received BRSF. */
- if (client_cb->peer_features == 0) {
- client_cb->peer_features = p_attr->attr_value.v.u16;
-
- /* SDP and BRSF WBS bit are different, correct it if set */
- if (client_cb->peer_features & 0x0020) {
- client_cb->peer_features &= ~0x0020;
- client_cb->peer_features |= BTA_HF_CLIENT_PEER_CODEC;
- }
-
- /* get network for ability to reject calls */
- p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_NETWORK);
- if (p_attr != NULL) {
- if (p_attr->attr_value.v.u16 == 0x01) {
- client_cb->peer_features |= BTA_HF_CLIENT_PEER_REJECT;
- }
- }
- }
- }
-
- /* found what we needed */
- result = true;
- break;
- }
-
- APPL_TRACE_DEBUG("%s: peer_version=0x%x peer_features=0x%x", __func__,
- client_cb->peer_version, client_cb->peer_features);
-
- return result;
-}
-
-/*******************************************************************************
- *
- * Function bta_hf_client_do_disc
- *
- * Description Do service discovery.